mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Fold branches/sx-cleanup/ [14463:15384] back into trunk/.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15399 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
e3a674154b
commit
eb73260220
68
ChangeLog
68
ChangeLog
@ -77,6 +77,17 @@
|
||||
relocation of previously compiled-in paths. With the exception of
|
||||
the env variables in src/bin/gnucash, we're fully relocatable now.
|
||||
|
||||
2006-09-16 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/gnome/gnc-plugin-page-sx-list.c (sxsl_get_sx_vars): Add
|
||||
variable extraction to instance-model creation. The
|
||||
GncSxInstances now has a hashtable of variables parsed from the
|
||||
formula, and the GncSxInstance has a copy of that variables hash.
|
||||
Not finished, but mostly in place.
|
||||
|
||||
* src/gnome/dialog-sx-since-last-run.c: New, simplified version of
|
||||
the since-last-run dialog. GncSxSlrTreeModelAdapter.
|
||||
|
||||
2006-09-13 Christian Stimming <stimming@tuhh.de>
|
||||
|
||||
* src/import-export/hbci/gnc-plugin-hbci.c: Move the MT940
|
||||
@ -270,6 +281,30 @@
|
||||
preferences_dialog->Windows. Move "Show close button on notebook
|
||||
tabs" from General to Windows. Fixes #340299.
|
||||
|
||||
2006-07-27 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/gnome-utils/gnc-dense-cal.c
|
||||
(gnc_dense_cal_transient_model_new): Actually implement
|
||||
GncDenseCalTransientModel.
|
||||
|
||||
* src/gnome/dialog-sx-editor.c (gnc_sxed_update_cal):
|
||||
* src/gnome/dialog-sx-from-trans.c (sxftd_update_example_cal):
|
||||
Use GncDenseCalTransientModel from previous ad-hoc updaters.
|
||||
|
||||
|
||||
2006-07-25 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/gnome-utils/gnc-dense-cal.c:
|
||||
Add GncDenseCalModel interface, support.
|
||||
Add unfinished GncDenseCalTransient model impl. for
|
||||
one-off being-edited-SX calendar usage.
|
||||
|
||||
* src/gnome/gnc-plugin-page-sx-list.c:
|
||||
Add GncSxInstanceDenseCalAdapter between GncSxInstanceModel and
|
||||
GncDenseCalModel. Start to hook up 'added' and 'removing' signals
|
||||
on the GncSxInstanceModel. The SX-List dense-cal works again, and
|
||||
reflects both removed and new SXes.
|
||||
|
||||
2006-07-24 Derek Atkins <derek@ihtfp.com>
|
||||
|
||||
* [lots of Makefile.am files]:
|
||||
@ -302,6 +337,27 @@
|
||||
extra de-quoting of path names that is done on the GNC_MODULE_PATH
|
||||
env variable.
|
||||
|
||||
2006-07-16 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/engine/SX-book-p.h:
|
||||
* src/engine/SX-book.h:
|
||||
* src/engine/SX-book.c: Promote SX list from a GList to a
|
||||
`SchedXactions` QOF Entity. Create add/remove API that emits
|
||||
GNC_EVENT_{INSERT,REMOVE} signals. Correctly associate the SX
|
||||
List with the collection of SchedXaction qof-type rather than the
|
||||
SX template transactions qof-type. Remove some (now-)dead
|
||||
code. Fix long-standing bug in registration of SX qof types.
|
||||
|
||||
* src/gnome/dialog-sx-editor.[ch]:
|
||||
* src/gnome/dialog-schedxaction.[ch]:
|
||||
Move the SX editor dialog subset of dialog-schedxaction to
|
||||
dialog-sx-editor.[ch].
|
||||
|
||||
* src/gnome/gnc-plugin-page-sx-list.c:
|
||||
Hookup SX editor for both 'new' and 'edit' actions. Hookup
|
||||
row-activation from tree-view. Extend GncSxInstanceModel to
|
||||
support SchedXactions (sx list) modification events.
|
||||
|
||||
2006-07-16 Derek Atkins <derek@ihtfp.com>
|
||||
|
||||
* configure.in:
|
||||
@ -331,6 +387,18 @@
|
||||
* src/gnome-utils/gnc-main-window.c: Do not move windows on
|
||||
restoration that would be offscreen.
|
||||
|
||||
2006-07-15 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/engine/SchedXaction.h (GNC_IS_SX,GNC_SX): added for convenience.
|
||||
|
||||
* src/gnome/ui/gnc-plugin-page-sx-list-ui.xml:
|
||||
* src/gnome/gnc-plugin-page-sx-list.[ch]: SX List as a plugin page.
|
||||
|
||||
* src/gnome/gnc-plugin-basic-commands.c: Call SX List plugin page,
|
||||
not dialog.
|
||||
|
||||
* src/doc/sx.rst: Added.
|
||||
|
||||
2006-07-15 Derek Atkins <derek@ihtfp.com>
|
||||
|
||||
* src/business/business-core/gncAddress.[ch]:
|
||||
|
@ -34,6 +34,7 @@ libgncmod_app_utils_la_SOURCES = \
|
||||
gnc-exp-parser.c \
|
||||
gnc-gettext-util.c \
|
||||
gnc-helpers.c \
|
||||
gnc-sx-instance-model.c \
|
||||
gncmod-app-utils.c \
|
||||
gnc-ui-util.c \
|
||||
guile-util.c \
|
||||
@ -59,6 +60,7 @@ gncinclude_HEADERS = \
|
||||
gnc-exp-parser.h \
|
||||
gnc-gettext-util.h \
|
||||
gnc-helpers.h \
|
||||
gnc-sx-instance-model.h \
|
||||
gnc-ui-common.h \
|
||||
gnc-ui-util.h \
|
||||
guile-util.h \
|
||||
|
1274
src/app-utils/gnc-sx-instance-model.c
Normal file
1274
src/app-utils/gnc-sx-instance-model.c
Normal file
File diff suppressed because it is too large
Load Diff
210
src/app-utils/gnc-sx-instance-model.h
Normal file
210
src/app-utils/gnc-sx-instance-model.h
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* gnc-sx-instance-model.h
|
||||
*
|
||||
* Copyright (C) 2006 Josh Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
#ifndef _GNC_SX_INSTANCE_MODEL_H
|
||||
#define _GNC_SX_INSTANCE_MODEL_H
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include "gnc-numeric.h"
|
||||
#include "SchedXaction.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GNC_TYPE_SX_INSTANCE_MODEL (gnc_sx_instance_model_get_type ())
|
||||
#define GNC_SX_INSTANCE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModel))
|
||||
#define GNC_SX_INSTANCE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModelClass))
|
||||
#define GNC_IS_SX_INSTANCE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_SX_INSTANCE_MODEL))
|
||||
#define GNC_IS_SX_INSTANCE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_SX_INSTANCE_MODEL))
|
||||
#define GNC_SX_INSTANCE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModelClass))
|
||||
|
||||
typedef struct _GncSxInstanceModel
|
||||
{
|
||||
GObject parent;
|
||||
gboolean disposed;
|
||||
|
||||
/* private */
|
||||
gint qof_event_handler_id;
|
||||
|
||||
/* signals */
|
||||
/* void (*added)(SchedXaction *sx); // gpointer user_data */
|
||||
/* void (*updated)(SchedXaction *sx); // gpointer user_data */
|
||||
/* void (*removing)(SchedXaction *sx); // gpointer user_data */
|
||||
|
||||
/* public */
|
||||
GDate range_end;
|
||||
GList *sx_instance_list; /* <GncSxInstances*> */
|
||||
} GncSxInstanceModel;
|
||||
|
||||
typedef struct _GncSxInstanceModelClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
|
||||
guint removing_signal_id;
|
||||
guint updated_signal_id;
|
||||
guint added_signal_id;
|
||||
} GncSxInstanceModelClass;
|
||||
|
||||
typedef struct _GncSxInstances
|
||||
{
|
||||
SchedXaction *sx;
|
||||
GHashTable /** <name:char*,GncSxVariable*> **/ *variable_names;
|
||||
gboolean variable_names_parsed;
|
||||
|
||||
GDate next_instance_date;
|
||||
|
||||
/** GList<GncSxInstance*> **/
|
||||
GList *list; /* @fixme: s/list/?/ */
|
||||
} GncSxInstances;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SX_INSTANCE_STATE_IGNORED,
|
||||
SX_INSTANCE_STATE_POSTPONED,
|
||||
SX_INSTANCE_STATE_TO_CREATE,
|
||||
SX_INSTANCE_STATE_REMINDER,
|
||||
SX_INSTANCE_STATE_CREATED,
|
||||
SX_INSTANCE_STATE_MAX_STATE
|
||||
} GncSxInstanceState;
|
||||
|
||||
typedef struct _GncSxVariable
|
||||
{
|
||||
gchar *name;
|
||||
gnc_numeric value; /**< only numeric values are supported. **/
|
||||
gboolean editable;
|
||||
} GncSxVariable;
|
||||
|
||||
typedef struct _GncSxInstance
|
||||
{
|
||||
GncSxInstances *parent; /**< the parent instances collection. **/
|
||||
void *temporal_state; /**< the sx creation temporal state. **/
|
||||
GncSxInstanceState orig_state; /**< the original state at generation time. **/
|
||||
GncSxInstanceState state; /**< the current state of the instance (during editing) **/
|
||||
GDate date; /**< the instance date. **/
|
||||
GHashTable *variable_bindings; /**< variable bindings. **/
|
||||
} GncSxInstance;
|
||||
|
||||
typedef struct _GncSxVariableNeeded
|
||||
{
|
||||
GncSxInstance *instance;
|
||||
GncSxVariable *variable;
|
||||
} GncSxVariableNeeded;
|
||||
|
||||
GType gnc_sx_instance_model_get_type(void);
|
||||
|
||||
GncSxInstanceModel* gnc_sx_get_current_instances(void);
|
||||
|
||||
GncSxInstanceModel* gnc_sx_get_instances(GDate *range_end);
|
||||
|
||||
/**
|
||||
* Regenerates and updates the GncSxInstances* for the given SX. Model
|
||||
* consumers are probably going to call this in response to seeing the
|
||||
* "update" signal, unless they need to be doing something else like
|
||||
* finishing an iteration over an existing GncSxInstances*.
|
||||
**/
|
||||
void gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx);
|
||||
void gnc_sx_instance_model_remove_sx_instances(GncSxInstanceModel *model, SchedXaction *sx);
|
||||
|
||||
/** @return GList<GncSxVariable*> **/
|
||||
GList *gnc_sx_instance_get_variables(GncSxInstance *inst);
|
||||
|
||||
Account* gnc_sx_get_template_transaction_account(SchedXaction *sx);
|
||||
|
||||
/**
|
||||
* @return caller-owned data struct.
|
||||
**/
|
||||
GHashTable* gnc_sx_instance_get_variables_for_parser(GHashTable *instance_var_hash);
|
||||
|
||||
GncSxVariable* gnc_sx_variable_new_full(gchar *name, gnc_numeric value, gboolean editable);
|
||||
void gnc_sx_variable_free(GncSxVariable *var);
|
||||
|
||||
/**
|
||||
* There is a constraint around a sequence of upcoming instance states. In
|
||||
* short: the last-created state and a list of postponed instances are modeled,
|
||||
* but upcoming reminders are not. As such, a reminder can never be before any
|
||||
* other (modeled) instance type. For instance, the following sequences are
|
||||
* disallowed:
|
||||
*
|
||||
* [...]
|
||||
* remind <- will be lost/skipped over; must be converted to `postponed`.
|
||||
* to-create <- this will be the last-recorded state.
|
||||
* [...]
|
||||
*
|
||||
* [...]
|
||||
* remind <- same as previous; will be lost/skipped; must be `postponed`.
|
||||
* postponed
|
||||
* [...]
|
||||
*
|
||||
* remind <- same...
|
||||
* ignore
|
||||
* [...]
|
||||
*
|
||||
*
|
||||
* As such, the SinceLastRun model will enforce that there are no previous
|
||||
* `remind` instances at every state change. They will be silently converted to
|
||||
* `postponed`-state transactions.
|
||||
**/
|
||||
void gnc_sx_instance_model_change_instance_state(GncSxInstanceModel *model,
|
||||
GncSxInstance *instance,
|
||||
GncSxInstanceState new_state);
|
||||
|
||||
void gnc_sx_instance_model_set_variable(GncSxInstanceModel *model,
|
||||
GncSxInstance *instance,
|
||||
GncSxVariable *variable,
|
||||
gnc_numeric *new_value);
|
||||
|
||||
/**
|
||||
* @return List<GncSxVariableNeeded> of unbound {instance,variable} pairs;
|
||||
* the caller owns the list and the items.
|
||||
**/
|
||||
GList* gnc_sx_instance_model_check_variables(GncSxInstanceModel *model);
|
||||
void gnc_sx_instance_model_effect_change(GncSxInstanceModel *model,
|
||||
gboolean auto_create_only,
|
||||
GList **created_transaction_guids,
|
||||
GList **creation_errors);
|
||||
|
||||
typedef struct _GncSxSummary
|
||||
{
|
||||
gboolean need_dialog; /**< If the dialog needs to be displayed. **/
|
||||
|
||||
gint num_instances; /**< The number of total instances (in any state). **/
|
||||
gint num_to_create_instances; /**< The number of (not-auto-create) to-create instances. **/
|
||||
gint num_auto_create_instances; /**< The total number of auto-create instances. **/
|
||||
gint num_auto_create_no_notify_instances; /**< The number of automatically-created instances that do no request notification. **/
|
||||
} GncSxSummary;
|
||||
|
||||
/**
|
||||
* @param summary Caller-provided, populated with a summarization of the
|
||||
* state of the model. Specifically, used to determine if there are SLR SXes
|
||||
* that need either auto-creation or user-interaction.
|
||||
**/
|
||||
void gnc_sx_instance_model_summarize(GncSxInstanceModel *model, GncSxSummary *summary);
|
||||
void gnc_sx_summary_print(GncSxSummary *summary);
|
||||
|
||||
void gnc_sx_get_variables(SchedXaction *sx, GHashTable *var_hash);
|
||||
int gnc_sx_parse_vars_from_formula(const char *formula, GHashTable *var_hash, gnc_numeric *result);
|
||||
void gnc_sx_randomize_variables(GHashTable *vars);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // _GNC_SX_INSTANCE_MODEL_H
|
@ -3,7 +3,8 @@ TESTS = \
|
||||
test-load-module \
|
||||
test-exp-parser \
|
||||
test-scm-query-string \
|
||||
test-print-parse-amount
|
||||
test-print-parse-amount \
|
||||
test-sx
|
||||
|
||||
test_exp_parser_SOURCES = \
|
||||
${top_builddir}/src/core-utils/gnc-gconf-utils.c \
|
||||
@ -48,7 +49,8 @@ check_PROGRAMS = \
|
||||
test-exp-parser \
|
||||
test-print-parse-amount \
|
||||
test-scm-query-string \
|
||||
test-print-queries
|
||||
test-print-queries \
|
||||
test-sx
|
||||
|
||||
EXTRA_DIST = \
|
||||
test-load-module
|
||||
|
@ -208,11 +208,23 @@ test_parser (void)
|
||||
success ("shutdown expression parser");
|
||||
}
|
||||
|
||||
static void
|
||||
test_variable_expressions()
|
||||
{
|
||||
gnc_numeric num;
|
||||
gchar *errLoc = NULL;
|
||||
GHashTable *vars = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
do_test(gnc_exp_parser_parse_separate_vars("123 + a", &num, &errLoc, vars), "parsing");
|
||||
do_test(g_hash_table_size(vars) == 1, "'a' is the variable; good job, gnc-exp-parser!");
|
||||
success("variable found");
|
||||
}
|
||||
|
||||
static void
|
||||
real_main (void *closure, int argc, char **argv)
|
||||
{
|
||||
/* set_should_print_success (TRUE); */
|
||||
test_parser();
|
||||
test_variable_expressions();
|
||||
print_test_results();
|
||||
exit(get_rv());
|
||||
}
|
||||
|
197
src/app-utils/test/test-sx.c
Normal file
197
src/app-utils/test/test-sx.c
Normal file
@ -0,0 +1,197 @@
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include "SX-book.h"
|
||||
#include "gnc-sx-instance-model.h"
|
||||
#include "gnc-ui-util.h"
|
||||
|
||||
#include "test-stuff.h"
|
||||
#include "test-engine-stuff.h"
|
||||
|
||||
static void
|
||||
test_basic()
|
||||
{
|
||||
GncSxInstanceModel *model;
|
||||
GDate *yesterday, *range_end_tomorrow;
|
||||
SchedXaction *foo;
|
||||
|
||||
yesterday = g_date_new();
|
||||
g_date_clear(yesterday, 1);
|
||||
g_date_set_time_t(yesterday, time(NULL));
|
||||
g_date_subtract_days(yesterday, 1);
|
||||
|
||||
foo = add_daily_sx("foo", yesterday, NULL, NULL);
|
||||
|
||||
range_end_tomorrow = g_date_new();
|
||||
g_date_clear(range_end_tomorrow, 1);
|
||||
g_date_set_time_t(range_end_tomorrow, time(NULL));
|
||||
g_date_add_days(range_end_tomorrow, 1);
|
||||
model = gnc_sx_get_instances(range_end_tomorrow);
|
||||
|
||||
{
|
||||
GncSxInstances *insts;
|
||||
GList *iter;
|
||||
|
||||
do_test(g_list_length(model->sx_instance_list) == 1, "1 GncSxInstances");
|
||||
insts = (GncSxInstances*)model->sx_instance_list->data;
|
||||
do_test(g_list_length(insts->list) == 3, "yesterday, today and tomorrow");
|
||||
for (iter = insts->list; iter != NULL; iter = iter->next)
|
||||
{
|
||||
GncSxInstance *inst = (GncSxInstance*)iter->data;
|
||||
do_test(inst->state == SX_INSTANCE_STATE_TO_CREATE, "to-create");
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref(G_OBJECT(model));
|
||||
remove_sx(foo);
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty()
|
||||
{
|
||||
// no sxes should exist at this point.
|
||||
int way_in_the_future_year = 2038;
|
||||
GDate *end;
|
||||
GncSxInstanceModel *model;
|
||||
|
||||
end = g_date_new_dmy(31, 12, way_in_the_future_year);
|
||||
model = gnc_sx_get_instances(end);
|
||||
do_test(g_list_length(model->sx_instance_list) == 0, "no instances");
|
||||
g_object_unref(G_OBJECT(model));
|
||||
success("empty");
|
||||
}
|
||||
|
||||
static void
|
||||
test_once()
|
||||
{
|
||||
SchedXaction *lonely;
|
||||
GDate *when, *end;
|
||||
int random_offset_within_one_year = 0;
|
||||
GncSxInstanceModel *model;
|
||||
GncSxInstances *instances;
|
||||
GncSxInstance *instance;
|
||||
|
||||
when = g_date_new();
|
||||
g_date_clear(when, 1);
|
||||
g_date_set_time_t(when, time(NULL));
|
||||
while (random_offset_within_one_year == 0)
|
||||
random_offset_within_one_year = get_random_int_in_range(-365, 365);
|
||||
g_date_add_days(when, random_offset_within_one_year);
|
||||
|
||||
end = g_date_new();
|
||||
g_date_clear(end, 1);
|
||||
g_date_set_time_t(end, time(NULL));
|
||||
g_date_add_years(end, 1);
|
||||
|
||||
lonely = add_once_sx("once", when);
|
||||
|
||||
model = gnc_sx_get_instances(end);
|
||||
|
||||
do_test(g_list_length(model->sx_instance_list) == 1, "1 instances");
|
||||
instances = (GncSxInstances*)model->sx_instance_list->data;
|
||||
do_test(g_list_length(instances->list) == 1, "1 instance");
|
||||
instance = (GncSxInstance*)instances->list->data;
|
||||
do_test(g_date_compare(when, &instances->next_instance_date) == 0, "next instance is expected");
|
||||
do_test(g_date_compare(when, &instance->date) == 0, "instance date is expected");
|
||||
|
||||
g_object_unref(model);
|
||||
success("model unref");
|
||||
remove_sx(lonely);
|
||||
}
|
||||
|
||||
static GncSxInstance*
|
||||
_nth_instance(GncSxInstances *instances, int i)
|
||||
{
|
||||
return (GncSxInstance*)g_list_nth_data(instances->list, i);
|
||||
}
|
||||
|
||||
static void
|
||||
test_state_changes()
|
||||
{
|
||||
SchedXaction *foo;
|
||||
GDate *start, *end;
|
||||
GncSxInstanceModel *model;
|
||||
GncSxInstances *insts;
|
||||
GncSxInstance *inst;
|
||||
|
||||
start = g_date_new();
|
||||
g_date_set_time_t(start, time(NULL));
|
||||
|
||||
end = g_date_new();
|
||||
g_date_set_time_t(end, time(NULL));
|
||||
g_date_add_days(end, 3);
|
||||
|
||||
foo = add_daily_sx("foo", start, NULL, NULL);
|
||||
model = gnc_sx_get_instances(end);
|
||||
|
||||
do_test(g_list_length(model->sx_instance_list) == 1, "one sx");
|
||||
insts = (GncSxInstances*)g_list_nth_data(model->sx_instance_list, 0);
|
||||
do_test(g_list_length(insts->list) == 4, "4 instances");
|
||||
|
||||
inst = _nth_instance(insts, 2);
|
||||
gnc_sx_instance_model_change_instance_state(model, inst, SX_INSTANCE_STATE_TO_CREATE);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
inst = _nth_instance(insts, i);
|
||||
do_test(inst->state == SX_INSTANCE_STATE_TO_CREATE, "0 didn't change");
|
||||
}
|
||||
success("nothing else changed");
|
||||
}
|
||||
|
||||
inst = _nth_instance(insts, 1);
|
||||
gnc_sx_instance_model_change_instance_state(model, inst, SX_INSTANCE_STATE_POSTPONED);
|
||||
{
|
||||
int i;
|
||||
inst = _nth_instance(insts, 1);
|
||||
do_test(inst->state == SX_INSTANCE_STATE_POSTPONED, "as we said");
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (i == 1)
|
||||
continue; // skip
|
||||
inst = _nth_instance(insts, i);
|
||||
do_test(inst->state == SX_INSTANCE_STATE_TO_CREATE, "still to create");
|
||||
}
|
||||
}
|
||||
success("postponed changed what it needed to");
|
||||
|
||||
inst = _nth_instance(insts, 1);
|
||||
gnc_sx_instance_model_change_instance_state(model, inst, SX_INSTANCE_STATE_REMINDER);
|
||||
success("changed to reminder");
|
||||
{
|
||||
int i;
|
||||
inst = _nth_instance(insts, 0);
|
||||
do_test(inst->state == SX_INSTANCE_STATE_TO_CREATE, "left alone");
|
||||
inst = _nth_instance(insts, 1);
|
||||
do_test(inst->state == SX_INSTANCE_STATE_REMINDER, "as we asked for");
|
||||
for (i = 2; i < 4; i++)
|
||||
{
|
||||
inst = _nth_instance(insts, i);
|
||||
do_test(inst->state == SX_INSTANCE_STATE_REMINDER, "changed as well");
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref(model);
|
||||
remove_sx(foo);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
g_type_init();
|
||||
qof_init();
|
||||
gnc_engine_init(0, NULL);
|
||||
|
||||
test_empty();
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 10; i++)
|
||||
test_once();
|
||||
}
|
||||
test_basic();
|
||||
test_state_changes();
|
||||
|
||||
print_test_results();
|
||||
exit(get_rv());
|
||||
}
|
@ -237,16 +237,19 @@ add_transaction_local(sixtp_gdv2 *data, Transaction *trn)
|
||||
static gboolean
|
||||
add_schedXaction_local(sixtp_gdv2 *data, SchedXaction *sx)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
list = gnc_book_get_schedxactions (data->book);
|
||||
list = g_list_append(list, sx);
|
||||
|
||||
gnc_book_set_schedxactions(data->book, list);
|
||||
data->counter.schedXactions_loaded++;
|
||||
run_callback(data, "schedXactions");
|
||||
|
||||
return TRUE;
|
||||
SchedXactions *sxes;
|
||||
#if 0 // old
|
||||
GList *list;
|
||||
list = gnc_book_get_schedxactions (data->book);
|
||||
list = g_list_append(list, sx);
|
||||
gnc_book_set_schedxactions(data->book, list);
|
||||
#endif // 0
|
||||
sxes = gnc_book_get_schedxactions(data->book);
|
||||
gnc_sxes_add_sx(sxes, sx);
|
||||
data->counter.schedXactions_loaded++;
|
||||
run_callback(data, "schedXactions");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -932,7 +935,7 @@ write_book(FILE *out, QofBook *book, sixtp_gdv2 *gd)
|
||||
"transaction",
|
||||
gnc_book_count_transactions(book),
|
||||
"schedxaction",
|
||||
g_list_length( gnc_book_get_schedxactions(book) ),
|
||||
g_list_length(gnc_book_get_schedxactions(book)->sx_list),
|
||||
"budget", qof_collection_count(
|
||||
qof_book_get_collection(book, GNC_ID_BUDGET)),
|
||||
NULL);
|
||||
@ -1067,25 +1070,24 @@ write_template_transaction_data( FILE *out, QofBook *book, sixtp_gdv2 *gd )
|
||||
static void
|
||||
write_schedXactions( FILE *out, QofBook *book, sixtp_gdv2 *gd)
|
||||
{
|
||||
GList *schedXactions;
|
||||
SchedXaction *tmpSX;
|
||||
xmlNodePtr node;
|
||||
GList *schedXactions;
|
||||
SchedXaction *tmpSX;
|
||||
xmlNodePtr node;
|
||||
|
||||
schedXactions = gnc_book_get_schedxactions(book)->sx_list;
|
||||
|
||||
/* get list of scheduled transactions from QofBook */
|
||||
schedXactions = gnc_book_get_schedxactions( book );
|
||||
if ( schedXactions == NULL )
|
||||
return;
|
||||
|
||||
if ( schedXactions == NULL )
|
||||
return;
|
||||
|
||||
do {
|
||||
tmpSX = schedXactions->data;
|
||||
node = gnc_schedXaction_dom_tree_create( tmpSX );
|
||||
xmlElemDump( out, NULL, node );
|
||||
fprintf( out, "\n" );
|
||||
xmlFreeNode( node );
|
||||
gd->counter.schedXactions_loaded++;
|
||||
run_callback(gd, "schedXactions");
|
||||
} while ( (schedXactions = schedXactions->next) );
|
||||
do {
|
||||
tmpSX = schedXactions->data;
|
||||
node = gnc_schedXaction_dom_tree_create( tmpSX );
|
||||
xmlElemDump( out, NULL, node );
|
||||
fprintf( out, "\n" );
|
||||
xmlFreeNode( node );
|
||||
gd->counter.schedXactions_loaded++;
|
||||
run_callback(gd, "schedXactions");
|
||||
} while ( (schedXactions = schedXactions->next) );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1175,7 +1177,7 @@ gnc_book_write_to_xml_filehandle_v2(QofBook *book, FILE *out)
|
||||
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));
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#include "gnc-glib-utils.h"
|
||||
|
||||
int
|
||||
int
|
||||
safe_utf8_collate (const char * da, const char * db)
|
||||
{
|
||||
if (da && !(*da))
|
||||
@ -222,3 +222,31 @@ gnc_utf8_strip_invalid_strdup(const gchar* str)
|
||||
gnc_utf8_strip_invalid (result);
|
||||
return result;
|
||||
}
|
||||
|
||||
GList*
|
||||
gnc_g_list_map(GList* list, GncGMapFunc fn, gpointer user_data)
|
||||
{
|
||||
GList *rtn = NULL;
|
||||
for (; list != NULL; list = list->next)
|
||||
{
|
||||
rtn = g_list_append(rtn, (*fn)(list->data, user_data));
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_g_list_cut(GList **list, GList *cut_point)
|
||||
{
|
||||
if (list == NULL || *list == NULL)
|
||||
return;
|
||||
|
||||
// if it's the first element.
|
||||
if (cut_point->prev == NULL)
|
||||
{
|
||||
*list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
cut_point->prev->next = NULL;
|
||||
cut_point->prev = NULL;
|
||||
}
|
||||
|
@ -81,6 +81,19 @@ void gnc_utf8_strip_invalid (gchar *str);
|
||||
* caller. */
|
||||
gchar *gnc_utf8_strip_invalid_strdup (const gchar* str);
|
||||
|
||||
typedef gpointer (*GncGMapFunc)(gpointer data, gpointer user_data);
|
||||
|
||||
/**
|
||||
* @return Caller-owned GList* of results of apply `fn` to `list` in order.
|
||||
**/
|
||||
GList* gnc_g_list_map(GList* list, GncGMapFunc fn, gpointer user_data);
|
||||
|
||||
/**
|
||||
* Cut a GList into two parts; the {@param cut_point} is the beginning of the
|
||||
* new list; {@param list} may need to be modified, but will be the list
|
||||
* before the {@param cut_point}.
|
||||
**/
|
||||
void gnc_g_list_cut(GList **list, GList *cut_point);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
312
src/doc/sx.rst
Normal file
312
src/doc/sx.rst
Normal file
@ -0,0 +1,312 @@
|
||||
Scheduled Transactions
|
||||
===============================================================
|
||||
|
||||
Overview
|
||||
--------------
|
||||
|
||||
- SX List
|
||||
- CRUD operations on SXes
|
||||
- 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)
|
||||
|
||||
TODO
|
||||
----------
|
||||
|
||||
- meta
|
||||
- [x] move files around
|
||||
- [ ] GncSxListTreeModelAdapter: s/real/adapted/
|
||||
- [ ] generic tree model adapter setup code
|
||||
|
||||
- core
|
||||
- [x] sx list -> qof collection
|
||||
- [x] sx engine events
|
||||
- [x] sx list collection add/remove -- sx-list GNC_EVENT_ITEM_ADDED, _REMOVED
|
||||
- [x] sx modified -- QOF_EVENT_MODIFY
|
||||
- [x] sx upcoming instance model
|
||||
! - [x] implement sort model
|
||||
- [x] rename, re-home gnc-sx-instance-model:sxsl_get_sx_vars
|
||||
- [x] rename, re-home gnc-sx-instance-model:parse_vars_from_formula
|
||||
- [ ] after updating/merging new instances, enforce state (+variable) consistency.
|
||||
|
||||
- unit testing
|
||||
- [ ] model updating in the face of change
|
||||
- [ ] insert sx
|
||||
- [ ] remove sx
|
||||
- [ ] update sx
|
||||
- [ ] add instances
|
||||
- [ ] remove instances
|
||||
- [ ] make "weird"
|
||||
- [x] ensure state consistency model is upheld
|
||||
- [ ] check variables-unbound logic
|
||||
- [ ] verify summary counts
|
||||
- [ ] check "since last run" states
|
||||
- [ ] -autocreate[, ±notify]
|
||||
- [ ] +autocreate, -notify
|
||||
- [ ] +autocreate, +notify
|
||||
- [ ] +autocreate, -notify, w/postponed
|
||||
- [ ] +autocreate, +notify, w/postponed
|
||||
- [ ] bugs
|
||||
- [?] Expired scheduled transactions never run - <http://bugzilla.gnome.org/show_bug.cgi?id=375892>
|
||||
|
||||
- bugs
|
||||
- [ ] with SLR open (with instances), add variables to SX; only newly-created instances will have appropriate variable tables.
|
||||
|
||||
! - [ ] crash with two sx lists open and SX mutation
|
||||
- I'm pretty sure this is due to SX lists not getting cleaned up on page close, somehow.
|
||||
[[[
|
||||
(gnucash:17610): GLib-GObject-WARNING **: invalid unclassed pointer in cast to `GncSxListTreeModelAdapterType'
|
||||
sx list tree model adapter update
|
||||
|
||||
(gnucash:17610): Gtk-CRITICAL **: gtk_tree_store_clear: assertion `GTK_IS_TREE_STORE (tree_store)' failed ]]]
|
||||
|
||||
- [x] Scheduled Transactions on 31st/last put in following month - <http://bugzilla.gnome.org/show_bug.cgi?id=104844>
|
||||
|
||||
- sx list page
|
||||
- [ ] use gnc-tree-view
|
||||
- [ ] save/restore state
|
||||
- [/] make into split panel
|
||||
- [ ] fix slider position
|
||||
- [ ] {0, 1, 2, 4, 8, 12} month selection for dense calendar
|
||||
|
||||
- sx editor
|
||||
- [ ] clean up, reformat
|
||||
- [ ] model-ize
|
||||
- (check_consistent, especially...)
|
||||
|
||||
- gnc-frequency
|
||||
- [ ] clean up, reformat
|
||||
|
||||
- gnc_dense_cal
|
||||
- [ ] font handling: gdk -> pango
|
||||
- [ ] change number-of-month properties to display-named properties (width, length)
|
||||
- [?] better transient/floating window
|
||||
- [/] (re-format file)
|
||||
- [x] set_model(GncTemporalInstancesModel *mdl)
|
||||
- [x] new interface creation.
|
||||
- [x] register callbacks for signals
|
||||
- [x] remove clist usage
|
||||
|
||||
- sx-from-trans
|
||||
- [?] convert to GObject
|
||||
- [x] hookup destroy/finalize
|
||||
|
||||
- FreqSpec
|
||||
- [ ] type+ui-type -> type
|
||||
|
||||
- use Recurrence instead of FreqSpec
|
||||
- [ ] XML migration, handling
|
||||
|
||||
- since-last-run
|
||||
! - [x] rewrite adapter (re-)population logic
|
||||
- [x] move "effect_change" up to app-utils/, test.
|
||||
- [x] move state-change up to app-utils
|
||||
- [x] move variable-setting up to app-utils
|
||||
- [x] move summarization up to app-utils
|
||||
- [x] add reminders, postponed to SxInstanceModel
|
||||
- [x] add mutation support to sx instance model
|
||||
- [x] state machine
|
||||
- [x] add variable state to sx instance model
|
||||
- [x] handle (hidden/system not for editing) variables.
|
||||
- [x] add sx_upcoming_instance_model()
|
||||
- [x] add effect_auto_create()
|
||||
- [x] add some sort of "ready to go" flag and api
|
||||
- [x] variable setting, primarily
|
||||
- [x] some sort of commit_changes()
|
||||
- [x] add variable table to instances
|
||||
- [x] ui: add 'review created transactions' checkbox to SLR dialog
|
||||
using txn search.
|
||||
|
||||
- destroy/cleanup
|
||||
- notes
|
||||
- dispose: should no longer hold references to other objects; callable
|
||||
multiple times; chain up at end
|
||||
- finalize: complete destruction; just before free; only called once;
|
||||
chain up at end.
|
||||
|
||||
Pedantic Todo
|
||||
----------------------
|
||||
|
||||
- s/SchedXaction/Scheduled/
|
||||
- s/temporal_state/instance_sequence_context/
|
||||
- change instance variable from 'i' to '__i' or something
|
||||
|
||||
============================================================
|
||||
|
||||
(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 separate to-review page, however the user may (optionally) want
|
||||
to see the created transactions. This is done using the transaction-search
|
||||
functionality over the created transactions by ID.
|
||||
|
||||
Upcoming instance states
|
||||
---------------------------------------
|
||||
|
||||
reminder -> to-create
|
||||
postponed -> to-create
|
||||
to-create -> postponed
|
||||
to-create -> ignore
|
||||
to-create -> created [terminal]
|
||||
|
||||
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.
|
||||
created: the instance has been created in this interaction cycle.
|
||||
|
||||
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.
|
||||
|
||||
Testing Notes
|
||||
---------------------
|
||||
|
||||
- auto-create
|
||||
- auto-create with postponed instances shouldn't destroy postponed
|
||||
instances
|
||||
|
||||
- basic sequence stuff
|
||||
|
||||
dialog-sxsincelast.c: ~L1241:
|
||||
"Handle an interesting corner case of postponing or
|
||||
ignoring the first instance. We only want to increment the
|
||||
counters for newly-discovered-as-to-be-created SXes."
|
||||
|
||||
- auto-create
|
||||
- auto-create transactions can be created w/o user interaction
|
||||
- their state is transitioned to 'created', which is not modifiable
|
||||
|
||||
- auto-create (+notify) transactions should be displayed, even if they are
|
||||
the only transactions created.
|
||||
|
||||
- auto-create (-notify) transactions should not be displayed, unless there
|
||||
are other transactions.
|
||||
|
||||
- Scenarios
|
||||
- only auto-create (-notify): no SLR, info dialog w/count (***)
|
||||
- only auto-create (+notify): SLR dialog, already created
|
||||
- others, auto-create (-notify): SLR dialog, incl. created
|
||||
- others, auto-create (+notify): SLR dialog, incl. created
|
||||
|
||||
Bugs to close after merge
|
||||
--------------------------------------
|
||||
|
||||
- With many auto-create transactions but none with notify option, "Auto-Created Transactions Notification" druid page lists every existing transaction - http://bugzilla.gnome.org/show_bug.cgi?id=347116
|
||||
- Since last run dialog does not allow for early finish, an... - http://bugzilla.gnome.org/show_bug.cgi?id=329384
|
||||
- Since Last Run druid changes data before Apply - http://bugzilla.gnome.org/show_bug.cgi?id=333849
|
||||
- Resize the "Since Last Run" window is incorrect - http://bugzilla.gnome.org/show_bug.cgi?id=353563
|
||||
- Transaction reminders page has slightly incorrect instructions - http://bugzilla.gnome.org/show_bug.cgi?id=331069
|
||||
- Transaction not highlighted in "Transaction Preparation" window - http://bugzilla.gnome.org/show_bug.cgi?id=342658
|
||||
- Scrolling through variables list does not work - http://bugzilla.gnome.org/show_bug.cgi?id=343190
|
||||
- Gnucash thinks the file has changed after cancelling out of the Since Last Run dialog and making no changes - http://bugzilla.gnome.org/show_bug.cgi?id=344494
|
||||
- Transaction reminder with variable amount doesn't display value field - http://bugzilla.gnome.org/show_bug.cgi?id=147946
|
||||
|
||||
------------------------------------------------------------
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
Major overhaul
|
||||
--------------
|
||||
|
||||
The core application-side SX code was overhauled for clarity, modularity, correctness, testability, &c.
|
||||
|
||||
SXList Plugin Page
|
||||
-------------------
|
||||
|
||||
The SX list and upcoming-instances calendar moved from a top-level window to being a plugin page in the normal application container.
|
||||
|
||||
Since Last Run
|
||||
--------------
|
||||
|
||||
The Since Last Run (SLR) dialog received a functional overhaul as well. The previous druid-based approach led to a huge bookkeeping headache, as transitioning between pages required partially-processed SXes to be maintained and transactions to be created and destroyed. As well, the multi-stage dialog approach was just too involved and ill-suited to the task at hand, especially as some stages were conditional on the state of the data. It made me sad.
|
||||
|
||||
The new Since Last Run dialog is a single treeview of upcoming instances and variable bindings. There's a checkbox to have all created transactions presented after they are.
|
||||
|
||||
It's easier to describe via screenshot: <http://asynchronous.org/tmp/sx-cleanup-eg.png>.
|
||||
|
||||
Updating/signaling
|
||||
------------------
|
||||
|
||||
Part of the overhaul is a better use of QOF and GObject signaling for updates. The SX list and SLR update in response to changes in each other; for instance, you can change the frequency or start-range of an SX while the SLR dialog is open, and it will update in place.
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
(as of 2007-01-14)
|
||||
- The SX List plugin page doesn't save/restore its state.
|
||||
- Updating the variables in a formula with the SLR dialog open isn't consistent.
|
||||
- Closing an sx list plugin page leads to corrupted state.
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
In new files (and old files related to this code that I hold copyright on), I've removed the "or any later version" clause. I have problems licensing under a license that I haven't read, or that can change in ways I disagree with. At some point I'll make this change for all source files I hold copyright on, and I intend to not use the clause on sources I (re)write in the future.
|
||||
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
The key areas I think need testing are the new plugin page and the SLR dialog. It, at least, shouldn't do anything worse than the 1.8/2.0 SX code. :)
|
@ -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;
|
||||
};
|
||||
|
||||
void gnc_book_set_schedxactions( QofBook *book, GList *newList );
|
||||
void gnc_collection_set_schedxactions( QofCollection *col, GList *newList );
|
||||
|
||||
SchedXactions* gnc_collection_get_schedxactions(const QofCollection *col);
|
||||
|
||||
/* 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 */
|
||||
|
@ -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 @@ sxtg_book_end (QofBook *book)
|
||||
gnc_book_set_template_group (book, NULL);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
sxtg_is_dirty(const QofCollection *col)
|
||||
{
|
||||
@ -144,78 +144,45 @@ static QofObject sxtg_object_def =
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
SchedXactions *
|
||||
gnc_collection_get_schedxaction_list(const QofCollection *col)
|
||||
{
|
||||
return qof_collection_get_data (col);
|
||||
}
|
||||
|
||||
GList *
|
||||
SchedXactions*
|
||||
gnc_collection_get_schedxactions(const QofCollection *col)
|
||||
{
|
||||
SchedXactions *list;
|
||||
list = qof_collection_get_data (col);
|
||||
if (list) return list->sx_list;
|
||||
return NULL;
|
||||
SchedXactions *rtn = qof_collection_get_data(col);
|
||||
// @@assert(rtn != null);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
GList *
|
||||
SchedXactions*
|
||||
gnc_book_get_schedxactions(QofBook *book)
|
||||
{
|
||||
QofCollection *col;
|
||||
col = qof_book_get_collection (book, GNC_ID_SXTT);
|
||||
return gnc_collection_get_schedxactions (col);
|
||||
col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
|
||||
return gnc_collection_get_schedxactions(col);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_collection_set_schedxactions( QofCollection *col, GList *newList )
|
||||
gnc_sxes_add_sx(SchedXactions *sxes, SchedXaction *sx)
|
||||
{
|
||||
SchedXactions *old_list, *new_list;
|
||||
if ( col == NULL ) return;
|
||||
|
||||
old_list = qof_collection_get_data (col);
|
||||
if (old_list && old_list->sx_list == newList)
|
||||
{
|
||||
/* Assume the worst, that any 'set' means the data has
|
||||
* changed, and needs to be saved. */
|
||||
old_list->sx_notsaved = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
new_list = g_new (SchedXactions, 1);
|
||||
new_list->sx_list = newList;
|
||||
new_list->sx_notsaved = TRUE;
|
||||
if (NULL == newList) new_list->sx_notsaved = FALSE;
|
||||
|
||||
qof_collection_set_data (col, new_list);
|
||||
|
||||
g_free (old_list);
|
||||
if (g_list_find(sxes->sx_list, sx) != NULL)
|
||||
return;
|
||||
sxes->sx_list = g_list_append(sxes->sx_list, sx);
|
||||
qof_event_gen(&sxes->inst.entity, GNC_EVENT_ITEM_ADDED, (gpointer)sx);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_book_set_schedxactions( QofBook *book, GList *newList )
|
||||
gnc_sxes_del_sx(SchedXactions *sxes, SchedXaction *sx)
|
||||
{
|
||||
QofCollection *col;
|
||||
if ( book == NULL ) return;
|
||||
|
||||
col = qof_book_get_collection (book, GNC_ID_SXTT);
|
||||
gnc_collection_set_schedxactions (col, newList);
|
||||
GList *to_remove;
|
||||
to_remove = g_list_find(sxes->sx_list, sx);
|
||||
if (to_remove == NULL)
|
||||
return;
|
||||
sxes->sx_list = g_list_delete_link(sxes->sx_list, to_remove);
|
||||
qof_event_gen(&sxes->inst.entity, GNC_EVENT_ITEM_REMOVED, (gpointer)sx);
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
/* SX-trans stuff */
|
||||
|
||||
static void
|
||||
sxtt_book_begin (QofBook *book)
|
||||
{
|
||||
gnc_book_set_schedxactions (book, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sxtt_book_end (QofBook *book)
|
||||
{
|
||||
gnc_book_set_schedxactions (book, NULL);
|
||||
}
|
||||
static void
|
||||
mark_sx_clean(gpointer data, gpointer user_data)
|
||||
{
|
||||
@ -223,14 +190,29 @@ mark_sx_clean(gpointer data, gpointer user_data)
|
||||
qof_instance_mark_clean (QOF_INSTANCE(sx));
|
||||
}
|
||||
|
||||
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 @@ book_sxlist_notsaved(const QofCollection *col)
|
||||
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 @@ book_sxlist_notsaved(const QofCollection *col)
|
||||
|
||||
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 @@ static QofObject sxtt_object_def =
|
||||
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 @@ static QofObject sxtt_object_def =
|
||||
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 @@ gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct)
|
||||
{
|
||||
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;
|
||||
|
@ -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@linas.org>
|
||||
* @author Copyright (c) 2006 Joshua Sled <jsled@asynchronous.org>
|
||||
*
|
||||
* XXX currently, this is crufty, it should be modified to use
|
||||
* entities a bit more whole-heartedly than it does.
|
||||
@ -39,17 +40,28 @@
|
||||
#define GNC_SX_BOOK_H
|
||||
|
||||
#include <glib.h>
|
||||
#include "SchedXaction.h"
|
||||
#include "qof.h"
|
||||
|
||||
typedef struct xaccSchedXactionsDef SchedXactions;
|
||||
|
||||
SchedXactions * gnc_collection_get_schedxaction_list(const QofCollection *col);
|
||||
GList * gnc_collection_get_schedxactions(const QofCollection *col);
|
||||
GList * gnc_book_get_schedxactions(QofBook *book);
|
||||
struct xaccSchedXactionsDef {
|
||||
QofInstance inst;
|
||||
GList* sx_list;
|
||||
gboolean sx_notsaved;
|
||||
};
|
||||
|
||||
#define GNC_IS_SXES(obj) (QOF_CHECK_TYPE((obj), GNC_ID_SXES))
|
||||
#define GNC_SXES(obj) (QOF_CHECK_CAST((obj), GNC_ID_SXES, SchedXactions))
|
||||
|
||||
SchedXactions* gnc_book_get_schedxactions(QofBook* book);
|
||||
|
||||
void gnc_sxes_add_sx(SchedXactions* sxes, SchedXaction* sx);
|
||||
void gnc_sxes_del_sx(SchedXactions* sxes, SchedXaction* sx);
|
||||
|
||||
/** Returns the template group from the book. **/
|
||||
AccountGroup * gnc_book_get_template_group(QofBook *book);
|
||||
AccountGroup * gnc_collection_get_template_group(const QofCollection *col);
|
||||
AccountGroup* gnc_book_get_template_group(QofBook* book);
|
||||
AccountGroup* gnc_collection_get_template_group(const QofCollection *col);
|
||||
|
||||
/** @return The list of SXes which reference the given Account. Caller should free this list. **/
|
||||
GList* gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct);
|
||||
|
@ -192,13 +192,18 @@ static void commit_err (QofInstance *inst, QofBackendError errcode)
|
||||
PERR ("Failed to commit: %d", errcode);
|
||||
}
|
||||
|
||||
static void noop (QofInstance *inst) {}
|
||||
static void commit_done(QofInstance *inst)
|
||||
{
|
||||
qof_event_gen (&inst->entity, QOF_EVENT_MODIFY, NULL);
|
||||
}
|
||||
|
||||
static void noop(QofInstance *inst) {}
|
||||
|
||||
void
|
||||
gnc_sx_commit_edit (SchedXaction *sx)
|
||||
{
|
||||
if (!qof_commit_edit (QOF_INSTANCE(sx))) return;
|
||||
qof_commit_edit_part2 (&sx->inst, commit_err, noop, noop);
|
||||
qof_commit_edit_part2 (&sx->inst, commit_err, commit_done, noop);
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
@ -375,8 +380,10 @@ xaccSchedXactionGetAutoCreate( SchedXaction *sx,
|
||||
gboolean *outAutoCreate,
|
||||
gboolean *outNotify )
|
||||
{
|
||||
*outAutoCreate = sx->autoCreateOption;
|
||||
*outNotify = sx->autoCreateNotify;
|
||||
if (outAutoCreate != NULL)
|
||||
*outAutoCreate = sx->autoCreateOption;
|
||||
if (outNotify != NULL)
|
||||
*outNotify = sx->autoCreateNotify;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,9 @@
|
||||
#include "FreqSpec.h"
|
||||
#include "gnc-engine.h"
|
||||
|
||||
#define GNC_IS_SX(obj) (QOF_CHECK_TYPE((obj), GNC_ID_SCHEDXACTION))
|
||||
#define GNC_SX(obj) (QOF_CHECK_CAST((obj), GNC_ID_SCHEDXACTION, SchedXaction))
|
||||
|
||||
/**
|
||||
* The SchedXaction data.
|
||||
*/
|
||||
@ -196,7 +199,7 @@ void gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData );
|
||||
|
||||
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 );
|
||||
|
||||
|
@ -98,8 +98,9 @@
|
||||
#define GNC_ID_PRICE "Price"
|
||||
#define GNC_ID_PRICEDB "PriceDB"
|
||||
#define GNC_ID_SPLIT "Split"
|
||||
#define GNC_ID_SCHEDXACTION "SchedXaction"
|
||||
#define GNC_ID_BUDGET "Budget"
|
||||
#define GNC_ID_SCHEDXACTION "SchedXaction"
|
||||
#define GNC_ID_SXES "SchedXactions"
|
||||
#define GNC_ID_SXTG "SXTGroup"
|
||||
#define GNC_ID_SXTT "SXTTrans"
|
||||
#define GNC_ID_TRANS "Trans"
|
||||
|
@ -32,8 +32,12 @@
|
||||
#include "Group.h"
|
||||
#include "GroupP.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-session.h"
|
||||
#include "Transaction.h"
|
||||
#include "TransactionP.h"
|
||||
#include "FreqSpec.h"
|
||||
#include "SchedXaction.h"
|
||||
#include "SX-book.h"
|
||||
|
||||
#include "test-engine-stuff.h"
|
||||
#include "test-stuff.h"
|
||||
@ -2160,3 +2164,61 @@ make_trans_query (Transaction *trans, TestQueryTypes query_types)
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
static FreqSpec*
|
||||
daily_freq(GDate* start, int multiplier)
|
||||
{
|
||||
QofBook *book = qof_session_get_book(gnc_get_current_session());
|
||||
FreqSpec *freq = xaccFreqSpecMalloc(book);
|
||||
xaccFreqSpecSetDaily(freq, start, multiplier);
|
||||
xaccFreqSpecSetUIType(freq, UIFREQ_DAILY);
|
||||
return freq;
|
||||
}
|
||||
|
||||
static FreqSpec*
|
||||
once_freq(GDate *when)
|
||||
{
|
||||
QofBook *book = qof_session_get_book(gnc_get_current_session());
|
||||
FreqSpec *freq = xaccFreqSpecMalloc(book);
|
||||
xaccFreqSpecSetOnceDate(freq, when);
|
||||
xaccFreqSpecSetUIType(freq, UIFREQ_ONCE);
|
||||
return freq;
|
||||
}
|
||||
|
||||
static SchedXaction*
|
||||
add_sx(gchar *name, GDate *start, GDate *end, GDate *last_occur, FreqSpec *fs)
|
||||
{
|
||||
QofBook *book = qof_session_get_book(gnc_get_current_session());
|
||||
SchedXaction *sx = xaccSchedXactionMalloc(book);
|
||||
xaccSchedXactionSetName(sx, name);
|
||||
xaccSchedXactionSetStartDate(sx, start);
|
||||
if (end != NULL)
|
||||
xaccSchedXactionSetEndDate(sx, end);
|
||||
if (last_occur != NULL)
|
||||
xaccSchedXactionSetLastOccurDate(sx, last_occur);
|
||||
xaccSchedXactionSetFreqSpec(sx, fs);
|
||||
|
||||
gnc_sxes_add_sx(gnc_book_get_schedxactions(book), sx);
|
||||
|
||||
return sx;
|
||||
}
|
||||
|
||||
SchedXaction*
|
||||
add_daily_sx(gchar *name, GDate *start, GDate *end, GDate *last_occur)
|
||||
{
|
||||
return add_sx(name, start, end, last_occur, daily_freq(start, 1));
|
||||
}
|
||||
|
||||
SchedXaction*
|
||||
add_once_sx(gchar *name, GDate *when)
|
||||
{
|
||||
return add_sx(name, when, NULL, NULL, once_freq(when));
|
||||
}
|
||||
|
||||
void
|
||||
remove_sx(SchedXaction *sx)
|
||||
{
|
||||
QofBook *book = qof_session_get_book(gnc_get_current_session());
|
||||
SchedXactions *sxes = gnc_book_get_schedxactions(book);
|
||||
gnc_sxes_del_sx(sxes, sx);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "qof.h"
|
||||
#include "Query.h"
|
||||
#include "gnc-pricedb.h"
|
||||
#include "SchedXaction.h"
|
||||
|
||||
Timespec* get_random_timespec(void);
|
||||
void random_timespec_zero_nsec (gboolean zero_nsec);
|
||||
@ -88,4 +89,8 @@ void make_random_changes_to_group (QofBook *book, AccountGroup *group);
|
||||
void make_random_changes_to_book (QofBook *book);
|
||||
void make_random_changes_to_session (QofSession *session);
|
||||
|
||||
SchedXaction* add_daily_sx(gchar *name, GDate *start, GDate *end, GDate *last_occur);
|
||||
SchedXaction* add_once_sx(gchar *name, GDate *when);
|
||||
void remove_sx(SchedXaction *sx);
|
||||
|
||||
#endif
|
||||
|
@ -559,6 +559,50 @@ test_composite (void)
|
||||
xaccFreqSpecFree(fs);
|
||||
}
|
||||
|
||||
static void
|
||||
test_monthly_31st_bug_104844()
|
||||
{
|
||||
gchar date_buf[128];
|
||||
GDate start, next, expected;
|
||||
FreqSpec *fs = xaccFreqSpecMalloc(book);
|
||||
|
||||
g_date_clear(&next, 1);
|
||||
|
||||
g_date_clear(&start, 1);
|
||||
g_date_set_dmy(&start, 31, 1, 2003);
|
||||
xaccFreqSpecSetMonthly(fs, &start, 1);
|
||||
|
||||
//g_date_add_days(&start, 1);
|
||||
xaccFreqSpecGetNextInstance(fs, &start, &next);
|
||||
g_date_clear(&expected, 1);
|
||||
g_date_set_dmy(&expected, 28, 2, 2003);
|
||||
g_date_strftime(date_buf, 128, "%c", &next);
|
||||
do_test(g_date_compare(&expected, &next) == 0, date_buf);
|
||||
|
||||
start = next;
|
||||
xaccFreqSpecGetNextInstance(fs, &start, &next);
|
||||
g_date_set_dmy(&expected, 31, 3, 2003);
|
||||
g_date_strftime(date_buf, 128, "%c", &next);
|
||||
do_test(g_date_compare(&expected, &next) == 0, date_buf);
|
||||
|
||||
// test...
|
||||
g_date_set_dmy(&start, 31, 1, 2003);
|
||||
xaccFreqSpecSetMonthly(fs, &start, 1);
|
||||
g_date_set_dmy(&start, 31, 1, 2007);
|
||||
xaccFreqSpecGetNextInstance(fs, &start, &next);
|
||||
g_date_set_dmy(&expected, 28, 2, 2007);
|
||||
g_date_strftime(date_buf, 128, "%c", &next);
|
||||
do_test(g_date_compare(&expected, &next) == 0, date_buf);
|
||||
|
||||
start = next;
|
||||
xaccFreqSpecGetNextInstance(fs, &start, &next);
|
||||
g_date_set_dmy(&expected, 31, 3, 2007);
|
||||
g_date_strftime(date_buf, 128, "%c", &next);
|
||||
do_test(g_date_compare(&expected, &next) == 0, date_buf);
|
||||
|
||||
xaccFreqSpecFree(fs);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -568,6 +612,9 @@ main (int argc, char **argv)
|
||||
g_return_val_if_fail(cashobjects_register(), -1);
|
||||
session = qof_session_new ();
|
||||
book = qof_session_get_book(session);
|
||||
|
||||
test_monthly_31st_bug_104844();
|
||||
|
||||
test_once();
|
||||
test_caseA();
|
||||
test_daily();
|
||||
@ -575,6 +622,7 @@ main (int argc, char **argv)
|
||||
test_monthly();
|
||||
test_month_relative();
|
||||
test_composite();
|
||||
|
||||
print_test_results();
|
||||
qof_session_end(session);
|
||||
qof_close();
|
||||
|
@ -193,14 +193,14 @@ run_test (void)
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
qof_init();
|
||||
if(cashobjects_register())
|
||||
{
|
||||
xaccLogDisable ();
|
||||
run_test ();
|
||||
success("transaction voiding seems OK");
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
qof_init();
|
||||
if(cashobjects_register())
|
||||
{
|
||||
xaccLogDisable ();
|
||||
run_test ();
|
||||
success("transaction voiding seems OK");
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ libgncmod_gnome_utils_la_SOURCES = \
|
||||
gnc-date-edit.c \
|
||||
gnc-date-format.c \
|
||||
gnc-dense-cal.c \
|
||||
gnc-dense-cal-model.c \
|
||||
gnc-dense-cal-store.c \
|
||||
gnc-druid-gnome.c \
|
||||
gnc-druid-provider-edge-gnome.c \
|
||||
gnc-druid-provider-file-gnome.c \
|
||||
@ -74,6 +76,7 @@ libgncmod_gnome_utils_la_SOURCES = \
|
||||
gnc-period-select.c \
|
||||
gnc-query-list.c \
|
||||
gnc-splash.c \
|
||||
gnc-sx-instance-dense-cal-adapter.c \
|
||||
gnc-tree-model.c \
|
||||
gnc-tree-model-account-types.c \
|
||||
gnc-tree-model-account.c \
|
||||
@ -117,6 +120,8 @@ gncinclude_HEADERS = \
|
||||
gnc-date-edit.h \
|
||||
gnc-date-format.h \
|
||||
gnc-dense-cal.h \
|
||||
gnc-dense-cal-model.h \
|
||||
gnc-dense-cal-store.h \
|
||||
gnc-druid-gnome-ui.h \
|
||||
gnc-embedded-window.h \
|
||||
gnc-file.h \
|
||||
@ -139,6 +144,7 @@ gncinclude_HEADERS = \
|
||||
gnc-period-select.h \
|
||||
gnc-query-list.h \
|
||||
gnc-splash.h \
|
||||
gnc-sx-instance-dense-cal-adapter.h \
|
||||
gnc-tree-model.h \
|
||||
gnc-tree-model-account-types.h \
|
||||
gnc-tree-model-account.h \
|
||||
|
132
src/gnome-utils/gnc-dense-cal-model.c
Normal file
132
src/gnome-utils/gnc-dense-cal-model.c
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* gnc-dense-cal-model.c
|
||||
*
|
||||
* Copyright (C) 2006 Joshua Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include "gnc-dense-cal.h"
|
||||
#include "gnc-dense-cal-model.h"
|
||||
|
||||
enum { GDCM_ADDED, GDCM_UPDATE, GDCM_REMOVE, LAST_SIGNAL };
|
||||
static guint gnc_dense_cal_model_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
gnc_dense_cal_model_base_init(gpointer g_class)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
gnc_dense_cal_model_signals[GDCM_ADDED]
|
||||
= g_signal_new("added",
|
||||
G_TYPE_FROM_CLASS(g_class),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
||||
0 /* default offset */,
|
||||
NULL /* accumulator */,
|
||||
NULL /* accum. data */,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE /* return */,
|
||||
1 /* n_params */,
|
||||
G_TYPE_UINT /* param types */
|
||||
);
|
||||
|
||||
gnc_dense_cal_model_signals[GDCM_UPDATE]
|
||||
= g_signal_new("update",
|
||||
G_TYPE_FROM_CLASS(g_class),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
||||
0 /* default offset */,
|
||||
NULL /* accumulator */,
|
||||
NULL /* accum. data */,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE /* return */,
|
||||
1 /* n_params */,
|
||||
G_TYPE_UINT /* param types */
|
||||
);
|
||||
|
||||
gnc_dense_cal_model_signals[GDCM_REMOVE]
|
||||
= g_signal_new("removing",
|
||||
G_TYPE_FROM_CLASS(g_class),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
||||
0 /* default offset */,
|
||||
NULL /* accumulator */,
|
||||
NULL /* accum. data */,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE /* return */,
|
||||
1 /* n_params */,
|
||||
G_TYPE_UINT /* param types */
|
||||
);
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
gnc_dense_cal_model_get_type(void)
|
||||
{
|
||||
static GType type = 0;
|
||||
if (type == 0) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof(GncDenseCalModelIface),
|
||||
gnc_dense_cal_model_base_init, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
NULL, /* class_init */
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
0,
|
||||
0, /* n_preallocs */
|
||||
NULL /* instance_init */
|
||||
};
|
||||
type = g_type_register_static(G_TYPE_INTERFACE, "GncDenseCalModel", &info, 0);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
GList*
|
||||
gnc_dense_cal_model_get_contained(GncDenseCalModel *model)
|
||||
{
|
||||
return (*GNC_DENSE_CAL_MODEL_GET_INTERFACE(model)->get_contained)(model);
|
||||
}
|
||||
|
||||
gchar*
|
||||
gnc_dense_cal_model_get_name(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
return (*GNC_DENSE_CAL_MODEL_GET_INTERFACE(model)->get_name)(model, tag);
|
||||
}
|
||||
|
||||
gchar*
|
||||
gnc_dense_cal_model_get_info(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
return (*GNC_DENSE_CAL_MODEL_GET_INTERFACE(model)->get_info)(model, tag);
|
||||
}
|
||||
|
||||
gint
|
||||
gnc_dense_cal_model_get_instance_count(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
return (*GNC_DENSE_CAL_MODEL_GET_INTERFACE(model)->get_instance_count)(model, tag);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_dense_cal_model_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date)
|
||||
{
|
||||
return (*GNC_DENSE_CAL_MODEL_GET_INTERFACE(model)->get_instance)(model, tag, instance_index, date);
|
||||
}
|
66
src/gnome-utils/gnc-dense-cal-model.h
Normal file
66
src/gnome-utils/gnc-dense-cal-model.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* gnc-dense-cal-model.h
|
||||
*
|
||||
* Copyright (C) 2006 Joshua Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
#ifndef _GNC_DENSE_CAL_MODEL_H
|
||||
#define _GNC_DENSE_CAL_MODEL_H
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GNC_TYPE_DENSE_CAL_MODEL (gnc_dense_cal_model_get_type())
|
||||
#define GNC_DENSE_CAL_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_DENSE_CAL_MODEL, GncDenseCalModel))
|
||||
#define GNC_IS_DENSE_CAL_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_DENSE_CAL_MODEL))
|
||||
#define GNC_DENSE_CAL_MODEL_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GNC_TYPE_DENSE_CAL_MODEL, GncDenseCalModelIface))
|
||||
|
||||
typedef struct _GncDenseCalModel GncDenseCalModel; /* non existant */
|
||||
typedef struct _GncDenseCalModelIface
|
||||
{
|
||||
GTypeInterface parent;
|
||||
|
||||
/* signals */
|
||||
void (*insert)(GncDenseCalModel *mdl, gint tag);
|
||||
void (*update)(GncDenseCalModel *mdl, gint tag);
|
||||
void (*remove)(GncDenseCalModel *mdl, gint tag);
|
||||
|
||||
/* virtual table */
|
||||
GList* (*get_contained)(GncDenseCalModel *model);
|
||||
gchar* (*get_name)(GncDenseCalModel *model, guint tag);
|
||||
gchar* (*get_info)(GncDenseCalModel *model, guint tag);
|
||||
gint (*get_instance_count)(GncDenseCalModel *model, guint tag);
|
||||
void (*get_instance)(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date);
|
||||
} GncDenseCalModelIface;
|
||||
|
||||
GType gnc_dense_cal_model_get_type(void);
|
||||
|
||||
/* @fixme: glist mem alloc policy... ? */
|
||||
GList* gnc_dense_cal_model_get_contained(GncDenseCalModel *model);
|
||||
gchar* gnc_dense_cal_model_get_name(GncDenseCalModel *model, guint tag);
|
||||
gchar* gnc_dense_cal_model_get_info(GncDenseCalModel *model, guint tag);
|
||||
gint gnc_dense_cal_model_get_instance_count(GncDenseCalModel *model, guint tag);
|
||||
void gnc_dense_cal_model_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // _GNC_DENSE_CAL_MODEL_H
|
290
src/gnome-utils/gnc-dense-cal-store.c
Normal file
290
src/gnome-utils/gnc-dense-cal-store.c
Normal file
@ -0,0 +1,290 @@
|
||||
/*
|
||||
* gnc-dense-cal-store.h
|
||||
*
|
||||
* Copyright (C) 2006 Joshua Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include "gnc-dense-cal.h"
|
||||
#include "gnc-dense-cal-model.h"
|
||||
#include "gnc-dense-cal-store.h"
|
||||
|
||||
struct _GncDenseCalStore
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GDate start_date;
|
||||
gdcs_end_type end_type;
|
||||
GDate end_date;
|
||||
gint n_occurrences;
|
||||
gchar *name;
|
||||
gchar *info;
|
||||
int num_marks;
|
||||
int num_real_marks;
|
||||
GDate **cal_marks;
|
||||
};
|
||||
|
||||
struct _GncDenseCalStoreClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
static void gnc_dense_cal_store_class_init(GncDenseCalStoreClass *klass);
|
||||
|
||||
static void gnc_dense_cal_store_finalize(GObject *obj);
|
||||
|
||||
static GList* gdcs_get_contained(GncDenseCalModel *model);
|
||||
static gchar* gdcs_get_name(GncDenseCalModel *model, guint tag);
|
||||
static gchar* gdcs_get_info(GncDenseCalModel *model, guint tag);
|
||||
static gint gdcs_get_instance_count(GncDenseCalModel *model, guint tag);
|
||||
static void gdcs_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date);
|
||||
|
||||
static void
|
||||
gnc_dense_cal_store_class_init(GncDenseCalStoreClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
parent_class = g_type_class_peek_parent(klass);
|
||||
|
||||
object_class->finalize = gnc_dense_cal_store_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_dense_cal_store_iface_init(gpointer g_iface, gpointer iface_data)
|
||||
{
|
||||
GncDenseCalModelIface *iface = (GncDenseCalModelIface*)g_iface;
|
||||
iface->get_contained = gdcs_get_contained;
|
||||
iface->get_name = gdcs_get_name;
|
||||
iface->get_info = gdcs_get_info;
|
||||
iface->get_instance_count = gdcs_get_instance_count;
|
||||
iface->get_instance = gdcs_get_instance;
|
||||
}
|
||||
|
||||
GType
|
||||
gnc_dense_cal_store_get_type(void)
|
||||
{
|
||||
static GType type = 0;
|
||||
if (type == 0)
|
||||
{
|
||||
static const GTypeInfo info = {
|
||||
sizeof (GncDenseCalStoreClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc)gnc_dense_cal_store_class_init, /* class_init */
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof(GncDenseCalStore),
|
||||
0, /* n_preallocs */
|
||||
NULL /* instance_init */
|
||||
};
|
||||
static const GInterfaceInfo iDenseCalModelInfo = {
|
||||
(GInterfaceInitFunc)gnc_dense_cal_store_iface_init,
|
||||
NULL, /* interface finalize */
|
||||
NULL, /* interface data */
|
||||
};
|
||||
type = g_type_register_static(G_TYPE_OBJECT, "GncDenseCalStore", &info, 0);
|
||||
g_type_add_interface_static(type,
|
||||
GNC_TYPE_DENSE_CAL_MODEL,
|
||||
&iDenseCalModelInfo);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
GncDenseCalStore*
|
||||
gnc_dense_cal_store_new(int num_marks)
|
||||
{
|
||||
GncDenseCalStore *model = g_object_new(GNC_TYPE_DENSE_CAL_STORE, NULL);
|
||||
model->num_marks = num_marks;
|
||||
model->cal_marks = g_new0(GDate*, num_marks);
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < model->num_marks; i++)
|
||||
{
|
||||
model->cal_marks[i] = g_date_new();
|
||||
}
|
||||
}
|
||||
model->num_real_marks = 0;
|
||||
g_date_clear(&model->start_date, 1);
|
||||
g_date_set_time_t(&model->start_date, time(NULL));
|
||||
model->end_type = NEVER_END;
|
||||
g_date_clear(&model->end_date, 1);
|
||||
g_date_set_time_t(&model->end_date, time(NULL));
|
||||
model->n_occurrences = 0;
|
||||
return model;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_dense_cal_store_clear(GncDenseCalStore *model)
|
||||
{
|
||||
model->num_real_marks = 0;
|
||||
g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
|
||||
}
|
||||
|
||||
void
|
||||
gnc_dense_cal_store_update_name(GncDenseCalStore *model, gchar *name)
|
||||
{
|
||||
if (model->name != NULL)
|
||||
{
|
||||
g_free(model->name);
|
||||
}
|
||||
model->name = g_strdup(name);
|
||||
g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
|
||||
}
|
||||
|
||||
void
|
||||
gnc_dense_cal_store_update_info(GncDenseCalStore *model, gchar *info)
|
||||
{
|
||||
if (model->info != NULL)
|
||||
{
|
||||
g_free(model->info);
|
||||
}
|
||||
model->info = g_strdup(info);
|
||||
g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
|
||||
}
|
||||
|
||||
static void
|
||||
gdcs_generic_update(GncDenseCalStore *trans, GDate *start, FreqSpec *fs)
|
||||
{
|
||||
int i;
|
||||
GDate date;
|
||||
|
||||
date = *start;
|
||||
/* go one day before what's in the box so we can get the correct start
|
||||
* date. */
|
||||
g_date_subtract_days(&date, 1);
|
||||
xaccFreqSpecGetNextInstance(fs, &date, &date);
|
||||
|
||||
i = 0;
|
||||
while ((i < trans->num_marks)
|
||||
&& g_date_valid(&date)
|
||||
/* Do checking against end restriction. */
|
||||
&& ((trans->end_type == NEVER_END)
|
||||
|| (trans->end_type == END_ON_DATE
|
||||
&& g_date_compare(&date, &trans->end_date) <= 0)
|
||||
|| (trans->end_type == END_AFTER_N_OCCS
|
||||
&& i < trans->n_occurrences)))
|
||||
{
|
||||
*trans->cal_marks[i++] = date;
|
||||
xaccFreqSpecGetNextInstance(fs, &date, &date);
|
||||
}
|
||||
trans->num_real_marks = (i-1);
|
||||
g_signal_emit_by_name(trans, "update", GUINT_TO_POINTER(1));
|
||||
}
|
||||
|
||||
void
|
||||
gnc_dense_cal_store_update_no_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs)
|
||||
{
|
||||
model->end_type = NEVER_END;
|
||||
gdcs_generic_update(model, start, fs);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_dense_cal_store_update_count_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs, int num_occur)
|
||||
{
|
||||
model->end_type = END_AFTER_N_OCCS;
|
||||
model->n_occurrences = num_occur;
|
||||
gdcs_generic_update(model, start, fs);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_dense_cal_store_update_date_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs, GDate *end_date)
|
||||
{
|
||||
model->end_type = END_ON_DATE;
|
||||
model->end_date = *end_date;
|
||||
gdcs_generic_update(model, start, fs);
|
||||
}
|
||||
|
||||
static GList*
|
||||
gdcs_get_contained(GncDenseCalModel *model)
|
||||
{
|
||||
GList *rtn = NULL;
|
||||
rtn = g_list_append(rtn, GUINT_TO_POINTER(1));
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
gdcs_get_name(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
|
||||
// assert(tag == 1)
|
||||
return mdl->name;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
gdcs_get_info(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
|
||||
// assert(tag == 1)
|
||||
return mdl->info;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdcs_get_instance_count(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
|
||||
// assert(tag == 1)
|
||||
return mdl->num_real_marks;
|
||||
}
|
||||
|
||||
static void
|
||||
gdcs_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date)
|
||||
{
|
||||
GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
|
||||
// assert(tag == 1)
|
||||
// assert 0 < instance_index < model->num_marks;
|
||||
*date = *mdl->cal_marks[instance_index];
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_dense_cal_store_finalize(GObject *obj)
|
||||
{
|
||||
int i;
|
||||
GncDenseCalStore *store;
|
||||
g_return_if_fail(obj != NULL);
|
||||
|
||||
store = GNC_DENSE_CAL_STORE(obj);
|
||||
|
||||
if (store->name != NULL)
|
||||
{
|
||||
g_free(store->name);
|
||||
store->name = NULL;
|
||||
}
|
||||
|
||||
if (store->info != NULL)
|
||||
{
|
||||
g_free(store->info);
|
||||
store->info = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < store->num_marks; i++)
|
||||
{
|
||||
g_free(store->cal_marks[i]);
|
||||
store->cal_marks[i] = NULL;
|
||||
}
|
||||
if (store->cal_marks != NULL)
|
||||
{
|
||||
g_free(store->cal_marks);
|
||||
store->cal_marks = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(parent_class)->finalize(obj);
|
||||
}
|
57
src/gnome-utils/gnc-dense-cal-store.h
Normal file
57
src/gnome-utils/gnc-dense-cal-store.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* gnc-dense-cal-store.h
|
||||
*
|
||||
* Copyright (C) 2006 Joshua Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
#ifndef _GNC_DENSE_CAL_STORE_H
|
||||
#define _GNC_DENSE_CAL_STORE_H
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include "gnc-dense-cal-model.h"
|
||||
#include "gnc-dense-cal.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GNC_TYPE_DENSE_CAL_STORE (gnc_dense_cal_store_get_type())
|
||||
#define GNC_DENSE_CAL_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_DENSE_CAL_STORE, GncDenseCalStore))
|
||||
#define GNC_DENSE_CAL_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_DENSE_CAL_STORE, GncDenseCalStoreClass))
|
||||
#define GNC_IS_DENSE_CAL_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_DENSE_CAL_STORE))
|
||||
#define GNC_IS_DENSE_CAL_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_DENSE_CAL_STORE))
|
||||
#define GNC_DENSE_CAL_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_DENSE_CAL_STORE, GncDenseCalStore))
|
||||
|
||||
typedef enum { NEVER_END, END_ON_DATE, END_AFTER_N_OCCS, BAD_END } gdcs_end_type;
|
||||
|
||||
typedef struct _GncDenseCalStore GncDenseCalStore;
|
||||
typedef struct _GncDenseCalStoreClass GncDenseCalStoreClass;
|
||||
|
||||
GType gnc_dense_cal_store_get_type(void);
|
||||
GncDenseCalStore* gnc_dense_cal_store_new(int num_marks);
|
||||
void gnc_dense_cal_store_clear(GncDenseCalStore *model);
|
||||
void gnc_dense_cal_store_update_name(GncDenseCalStore *model, gchar* name);
|
||||
void gnc_dense_cal_store_update_info(GncDenseCalStore *model, gchar* info);
|
||||
void gnc_dense_cal_store_update_no_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs);
|
||||
void gnc_dense_cal_store_update_count_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs, int num_occur);
|
||||
void gnc_dense_cal_store_update_date_end(GncDenseCalStore *model, GDate *start, FreqSpec *fs, GDate *end_date);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // _GNC_DENSE_CAL_STORE_H
|
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,11 @@
|
||||
#ifndef _DENSECAL_H_
|
||||
#define _DENSECAL_H_
|
||||
|
||||
/********************************************************************\
|
||||
* gnc-dense-cal.h : a custom densely-dispalyed calendar widget *
|
||||
* Copyright (C) 2002 Joshua Sled <jsled@asynchronous.org> *
|
||||
* Copyright (C) 2002,2006 Joshua Sled <jsled@asynchronous.org> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* published by the Free Software Foundation, under version 2 of *
|
||||
* the License. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
@ -23,14 +20,17 @@
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkadjustment.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <glib.h>
|
||||
#ifndef _GNC_DENSE_CAL_H
|
||||
#define _GNC_DENSE_CAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#include "config.h"
|
||||
|
||||
#include <FreqSpec.h>
|
||||
#include <glib.h>
|
||||
#include "gnc-dense-cal-model.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GNC_TYPE_DENSE_CAL (gnc_dense_cal_get_type ())
|
||||
#define GNC_DENSE_CAL(obj) GTK_CHECK_CAST (obj, gnc_dense_cal_get_type (), GncDenseCal)
|
||||
@ -40,92 +40,97 @@ extern "C" {
|
||||
typedef struct _GncDenseCal GncDenseCal;
|
||||
typedef struct _GncDenseCalClass GncDenseCalClass;
|
||||
|
||||
typedef struct _gdc_month_coords {
|
||||
gint x, y;
|
||||
typedef struct _gdc_month_coords
|
||||
{
|
||||
gint x, y;
|
||||
} gdc_month_coords;
|
||||
|
||||
enum GDC_COLORS {
|
||||
MONTH_THIS = 0,
|
||||
MONTH_THAT,
|
||||
MAX_COLORS
|
||||
enum GDC_COLORS
|
||||
{
|
||||
MONTH_THIS = 0,
|
||||
MONTH_THAT,
|
||||
MAX_COLORS
|
||||
};
|
||||
|
||||
struct _GncDenseCal
|
||||
{
|
||||
GtkWidget widget;
|
||||
GtkWidget widget;
|
||||
|
||||
GdkPixmap *drawbuf;
|
||||
GdkPixmap *drawbuf;
|
||||
|
||||
gboolean initialized;
|
||||
gboolean initialized;
|
||||
|
||||
gboolean showPopup;
|
||||
GtkWindow *transPopup;
|
||||
gboolean showPopup;
|
||||
GtkWindow *transPopup;
|
||||
|
||||
gint min_x_scale;
|
||||
gint min_y_scale;
|
||||
gint min_x_scale;
|
||||
gint min_y_scale;
|
||||
|
||||
gint x_scale;
|
||||
gint y_scale;
|
||||
gint x_scale;
|
||||
gint y_scale;
|
||||
|
||||
gint numMonths;
|
||||
gint monthsPerCol;
|
||||
gint num_weeks; /* computed */
|
||||
gint numMonths;
|
||||
gint monthsPerCol;
|
||||
gint num_weeks; /* computed */
|
||||
|
||||
GDateMonth month;
|
||||
gint year;
|
||||
gint firstOfMonthOffset;
|
||||
GDateMonth month;
|
||||
gint year;
|
||||
gint firstOfMonthOffset;
|
||||
|
||||
gint leftPadding;
|
||||
gint topPadding;
|
||||
gint leftPadding;
|
||||
gint topPadding;
|
||||
|
||||
gboolean needInitMonthLabels;
|
||||
gdc_month_coords monthPositions[12];
|
||||
GdkFont *monthLabelFont;
|
||||
GdkFont *dayLabelFont;
|
||||
GdkPixmap *monthLabels[12];
|
||||
gboolean needInitMonthLabels;
|
||||
gdc_month_coords monthPositions[12];
|
||||
GdkFont *monthLabelFont;
|
||||
GdkFont *dayLabelFont;
|
||||
GdkPixmap *monthLabels[12];
|
||||
|
||||
GdkColor weekColors[MAX_COLORS];
|
||||
GdkColor weekColors[MAX_COLORS];
|
||||
|
||||
guint label_lbearing;
|
||||
guint label_ascent;
|
||||
guint label_width;
|
||||
guint label_height;
|
||||
guint dayLabelHeight;
|
||||
guint label_lbearing;
|
||||
guint label_ascent;
|
||||
guint label_width;
|
||||
guint label_height;
|
||||
guint dayLabelHeight;
|
||||
|
||||
guint lastMarkTag;
|
||||
GncDenseCalModel *model;
|
||||
|
||||
/**
|
||||
* A GList of gdc_mark_data structs, one for each active/valid markTag.
|
||||
**/
|
||||
GList *markData;
|
||||
int numMarks;
|
||||
/* array of GList*s of per-cell markings. */
|
||||
GList **marks;
|
||||
guint lastMarkTag;
|
||||
|
||||
int disposed; /* private */
|
||||
/**
|
||||
* A GList of gdc_mark_data structs, one for each active/valid markTag.
|
||||
**/
|
||||
GList *markData;
|
||||
int numMarks;
|
||||
/* array of GList*s of per-cell markings. */
|
||||
GList **marks;
|
||||
|
||||
int disposed; /* private */
|
||||
};
|
||||
|
||||
struct _GncDenseCalClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
void (*marks_lost_cb)( GncDenseCal *dcal, gpointer user_data );
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
typedef struct _gdc_mark_data {
|
||||
gchar *name;
|
||||
gchar *info;
|
||||
guint tag;
|
||||
/* GdkColor markStyle; */
|
||||
/**
|
||||
* A GList of the dcal->marks indexes containing this mark.
|
||||
**/
|
||||
GList *ourMarks;
|
||||
typedef struct _gdc_mark_data
|
||||
{
|
||||
gchar *name;
|
||||
gchar *info;
|
||||
guint tag;
|
||||
/**
|
||||
* A GList of the dcal->marks indexes containing this mark.
|
||||
**/
|
||||
GList *ourMarks;
|
||||
} gdc_mark_data;
|
||||
|
||||
GtkWidget* gnc_dense_cal_new (void);
|
||||
GtkWidget* gnc_dense_cal_new_with_model (GncDenseCalModel *model);
|
||||
GType gnc_dense_cal_get_type (void);
|
||||
|
||||
void gnc_dense_cal_set_month( GncDenseCal *dcal, GDateMonth mon );
|
||||
void gnc_dense_cal_set_model(GncDenseCal *cal, GncDenseCalModel *model);
|
||||
void gnc_dense_cal_set_month(GncDenseCal *dcal, GDateMonth mon);
|
||||
/**
|
||||
* @param year Julian year: 2000 = 2000AD.
|
||||
**/
|
||||
@ -137,13 +142,6 @@ guint gnc_dense_cal_get_num_months( GncDenseCal *dcal );
|
||||
GDateMonth gnc_dense_cal_get_month( GncDenseCal *dcal );
|
||||
GDateYear gnc_dense_cal_get_year( GncDenseCal *dcal );
|
||||
|
||||
guint gnc_dense_cal_mark( GncDenseCal *dcal,
|
||||
guint size, GDate **daysArray,
|
||||
gchar *name, gchar *info );
|
||||
void gnc_dense_cal_mark_remove( GncDenseCal *dcal, guint markToRemove );
|
||||
G_END_DECLS
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _DENSECAL_H_ */
|
||||
#endif /* _GNC_DENSE_CAL_H */
|
||||
|
@ -638,12 +638,12 @@ gnc_frequency_save_state( GNCFrequency *gf, FreqSpec *fs, GDate *outDate )
|
||||
gint tmpInt;
|
||||
int i;
|
||||
GDate gd;
|
||||
time_t tmpTimeT;
|
||||
time_t start_tt;
|
||||
|
||||
tmpTimeT = gnc_date_edit_get_date( gf->startDate );
|
||||
start_tt = gnc_date_edit_get_date( gf->startDate );
|
||||
if ( NULL != outDate )
|
||||
{
|
||||
g_date_set_time_t( outDate, tmpTimeT );
|
||||
g_date_set_time_t( outDate, start_tt );
|
||||
}
|
||||
|
||||
if (NULL == fs) return;
|
||||
@ -656,7 +656,7 @@ gnc_frequency_save_state( GNCFrequency *gf, FreqSpec *fs, GDate *outDate )
|
||||
gnc_suspend_gui_refresh();
|
||||
|
||||
g_date_clear (&gd, 1);
|
||||
g_date_set_time_t( &gd, tmpTimeT );
|
||||
g_date_set_time_t( &gd, start_tt );
|
||||
|
||||
/*uift = xaccFreqSpecGetUIType( fs );*/
|
||||
uift = PAGES[page].uiFTVal;
|
||||
@ -667,6 +667,7 @@ gnc_frequency_save_state( GNCFrequency *gf, FreqSpec *fs, GDate *outDate )
|
||||
/* hmmm... shouldn't really be allowed. */
|
||||
break;
|
||||
case UIFREQ_ONCE:
|
||||
xaccFreqSpecSetOnceDate(fs, &gd);
|
||||
xaccFreqSpecSetUIType( fs, uift );
|
||||
break;
|
||||
case UIFREQ_DAILY:
|
||||
@ -771,8 +772,8 @@ gnc_frequency_save_state( GNCFrequency *gf, FreqSpec *fs, GDate *outDate )
|
||||
o = glade_xml_get_widget( gf->gxml, "semimonthly_second" );
|
||||
day = gtk_combo_box_get_active( GTK_COMBO_BOX(o) )+1;
|
||||
tmpFS = xaccFreqSpecMalloc(gnc_get_current_book ());
|
||||
tmpTimeT = gnc_date_edit_get_date( gf->startDate );
|
||||
g_date_set_time_t( &gd, tmpTimeT );
|
||||
start_tt = gnc_date_edit_get_date( gf->startDate );
|
||||
g_date_set_time_t( &gd, start_tt );
|
||||
g_date_to_struct_tm( &gd, &stm);
|
||||
if ( day >= stm.tm_mday ) {
|
||||
/* next month */
|
||||
@ -788,15 +789,19 @@ gnc_frequency_save_state( GNCFrequency *gf, FreqSpec *fs, GDate *outDate )
|
||||
}
|
||||
case UIFREQ_MONTHLY:
|
||||
{
|
||||
struct tm stm;
|
||||
o = glade_xml_get_widget( gf->gxml, "monthly_spin" );
|
||||
tmpInt = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(o));
|
||||
g_date_to_struct_tm( &gd, &stm);
|
||||
|
||||
o = glade_xml_get_widget( gf->gxml, "monthly_day" );
|
||||
day = gtk_combo_box_get_active( GTK_COMBO_BOX(o) ) + 1;
|
||||
stm.tm_mday = day;
|
||||
g_date_set_time_t( &gd, mktime( &stm ) );
|
||||
g_date_set_time_t(&gd, time(NULL));
|
||||
g_date_set_month(&gd, 1);
|
||||
g_date_set_day(&gd, day);
|
||||
{
|
||||
gchar buf[128];
|
||||
g_date_strftime(buf, 127, "%c", &gd);
|
||||
printf("monthly date [%s]\n", buf);
|
||||
}
|
||||
xaccFreqSpecSetMonthly( fs, &gd, tmpInt );
|
||||
xaccFreqSpecSetUIType( fs, uift );
|
||||
break;
|
||||
|
254
src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
Normal file
254
src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* gnc-sx-instance-dense-cal-adapter.c
|
||||
*
|
||||
* Copyright (C) 2006 Josh Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include "gnc-sx-instance-dense-cal-adapter.h"
|
||||
#include "gnc-dense-cal.h"
|
||||
|
||||
static void gnc_sx_instance_dense_cal_adapter_dispose(GObject *obj);
|
||||
static void gnc_sx_instance_dense_cal_adapter_finalize(GObject *obj);
|
||||
|
||||
static GList* gsidca_get_contained(GncDenseCalModel *model);
|
||||
static gchar* gsidca_get_name(GncDenseCalModel *model, guint tag);
|
||||
static gchar* gsidca_get_info(GncDenseCalModel *model, guint tag);
|
||||
static gint gsidca_get_instance_count(GncDenseCalModel *model, guint tag);
|
||||
static void gsidca_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
struct _GncSxInstanceDenseCalAdapterClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
};
|
||||
|
||||
struct _GncSxInstanceDenseCalAdapter
|
||||
{
|
||||
GObject parent;
|
||||
gboolean disposed;
|
||||
GncSxInstanceModel *instances;
|
||||
};
|
||||
|
||||
static void
|
||||
gnc_sx_instance_dense_cal_adapter_class_init(GncSxInstanceDenseCalAdapterClass *klass)
|
||||
{
|
||||
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
obj_class->dispose = gnc_sx_instance_dense_cal_adapter_dispose;
|
||||
obj_class->finalize = gnc_sx_instance_dense_cal_adapter_finalize;
|
||||
|
||||
parent_class = g_type_class_peek_parent(klass);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_sx_instance_dense_cal_adapter_init(GTypeInstance *instance, gpointer klass)
|
||||
{
|
||||
/*GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(instance);*/
|
||||
; /* nop */
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_sx_instance_dense_cal_adapter_interface_init(gpointer g_iface, gpointer iface_data)
|
||||
{
|
||||
GncDenseCalModelIface *iface = (GncDenseCalModelIface*)g_iface;
|
||||
iface->get_contained = gsidca_get_contained;
|
||||
iface->get_name = gsidca_get_name;
|
||||
iface->get_info = gsidca_get_info;
|
||||
iface->get_instance_count = gsidca_get_instance_count;
|
||||
iface->get_instance = gsidca_get_instance;
|
||||
}
|
||||
|
||||
static void
|
||||
gsidca_instances_added_cb(GncSxInstanceModel *model, SchedXaction *sx_added, gpointer user_data)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
|
||||
printf("instance added\n");
|
||||
g_signal_emit_by_name(adapter, "added", GPOINTER_TO_UINT(sx_added));
|
||||
}
|
||||
|
||||
static void
|
||||
gsidca_instances_updated_cb(GncSxInstanceModel *model, SchedXaction *sx_updated, gpointer user_data)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
|
||||
gnc_sx_instance_model_update_sx_instances(model, sx_updated);
|
||||
printf("instances updated\n");
|
||||
g_signal_emit_by_name(adapter, "update", GPOINTER_TO_UINT((gpointer)sx_updated));
|
||||
}
|
||||
|
||||
static void
|
||||
gsidca_instances_removing_cb(GncSxInstanceModel *model, SchedXaction *sx_to_be_removed, gpointer user_data)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
|
||||
printf("removing instance...\n");
|
||||
g_signal_emit_by_name(adapter, "removing", GPOINTER_TO_UINT(sx_to_be_removed));
|
||||
gnc_sx_instance_model_remove_sx_instances(model, sx_to_be_removed);
|
||||
}
|
||||
|
||||
GncSxInstanceDenseCalAdapter*
|
||||
gnc_sx_instance_dense_cal_adapter_new(GncSxInstanceModel *instances)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = g_object_new(GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER, NULL);
|
||||
adapter->instances = instances;
|
||||
g_object_ref(G_OBJECT(adapter->instances));
|
||||
|
||||
g_signal_connect(instances, "added", (GCallback)gsidca_instances_added_cb, adapter);
|
||||
g_signal_connect(instances, "updated", (GCallback)gsidca_instances_updated_cb, adapter);
|
||||
g_signal_connect(instances, "removing", (GCallback)gsidca_instances_removing_cb, adapter);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
GType
|
||||
gnc_sx_instance_dense_cal_adapter_get_type(void)
|
||||
{
|
||||
static GType type = 0;
|
||||
if (type == 0)
|
||||
{
|
||||
static const GTypeInfo info = {
|
||||
sizeof (GncSxInstanceDenseCalAdapterClass),
|
||||
NULL, /* base init */
|
||||
NULL, /* base finalize */
|
||||
(GClassInitFunc)gnc_sx_instance_dense_cal_adapter_class_init,
|
||||
NULL, /* class finalize */
|
||||
NULL, /* class data */
|
||||
sizeof(GncSxInstanceDenseCalAdapter),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc)gnc_sx_instance_dense_cal_adapter_init
|
||||
};
|
||||
static const GInterfaceInfo iDenseCalModelInfo = {
|
||||
(GInterfaceInitFunc)gnc_sx_instance_dense_cal_adapter_interface_init,
|
||||
NULL, /* interface finalize */
|
||||
NULL, /* interface data */
|
||||
};
|
||||
|
||||
type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"GncSxInstanceDenseCalAdapterType",
|
||||
&info, 0);
|
||||
g_type_add_interface_static(type,
|
||||
GNC_TYPE_DENSE_CAL_MODEL,
|
||||
&iDenseCalModelInfo);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static gint
|
||||
gsidca_find_sx_with_tag(gconstpointer list_data,
|
||||
gconstpointer find_data)
|
||||
{
|
||||
GncSxInstances *sx_instances = (GncSxInstances*)list_data;
|
||||
return (GUINT_TO_POINTER(GPOINTER_TO_UINT(sx_instances->sx)) == find_data ? 0 : 1);
|
||||
}
|
||||
|
||||
// @@ fixme this list is leaked.
|
||||
static GList*
|
||||
gsidca_get_contained(GncDenseCalModel *model)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
|
||||
//"removing return gnc_g_list_map(instances->sxes, sx_to_tag, null);
|
||||
GList *list = NULL, *sxes;
|
||||
for (sxes = adapter->instances->sx_instance_list; sxes != NULL; sxes = sxes->next)
|
||||
{
|
||||
GncSxInstances *sx_instances = (GncSxInstances*)sxes->data;
|
||||
list = g_list_append(list, GUINT_TO_POINTER(GPOINTER_TO_UINT(sx_instances->sx)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
gsidca_get_name(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
|
||||
GncSxInstances *insts
|
||||
= (GncSxInstances*)g_list_find_custom(adapter->instances->sx_instance_list, GUINT_TO_POINTER(tag), gsidca_find_sx_with_tag)->data;
|
||||
if (insts == NULL)
|
||||
return NULL;
|
||||
return xaccSchedXactionGetName(insts->sx);
|
||||
}
|
||||
|
||||
static gchar*
|
||||
gsidca_get_info(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
|
||||
// g_list_find(instances->sxes, {sx_to_tag, tag}).get_freq_spec().get_freq_str();
|
||||
FreqSpec *spec;
|
||||
GString *info;
|
||||
gchar *info_str;
|
||||
GncSxInstances *insts
|
||||
= (GncSxInstances*)g_list_find_custom(adapter->instances->sx_instance_list, GUINT_TO_POINTER(tag), gsidca_find_sx_with_tag)->data;
|
||||
if (insts == NULL)
|
||||
return NULL;
|
||||
spec = xaccSchedXactionGetFreqSpec(insts->sx);
|
||||
info = g_string_sized_new(16);
|
||||
xaccFreqSpecGetFreqStr(spec, info);
|
||||
info_str = info->str; // @fixme leaked... :/
|
||||
g_string_free(info, FALSE);
|
||||
return info_str;
|
||||
}
|
||||
|
||||
static gint
|
||||
gsidca_get_instance_count(GncDenseCalModel *model, guint tag)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
|
||||
// g_list_find(instances->sxes, {sx_to_tag, tag}).length();
|
||||
GncSxInstances *insts
|
||||
= (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->list);
|
||||
}
|
||||
|
||||
static void
|
||||
gsidca_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
|
||||
GncSxInstance *inst;
|
||||
GncSxInstances *insts
|
||||
= (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->list, instance_index);
|
||||
g_date_valid(&inst->date);
|
||||
*date = inst->date;
|
||||
g_date_valid(date);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_sx_instance_dense_cal_adapter_dispose(GObject *obj)
|
||||
{
|
||||
GncSxInstanceDenseCalAdapter *adapter;
|
||||
g_return_if_fail(obj != NULL);
|
||||
adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(obj);
|
||||
// g_return_if_fail(!adapter->disposed);
|
||||
if (adapter->disposed) return;
|
||||
adapter->disposed = TRUE;
|
||||
|
||||
g_object_unref(G_OBJECT(adapter->instances));
|
||||
adapter->instances = NULL;
|
||||
|
||||
G_OBJECT_CLASS(parent_class)->dispose(obj);
|
||||
}
|
||||
|
||||
static void gnc_sx_instance_dense_cal_adapter_finalize(GObject *obj)
|
||||
{
|
||||
g_return_if_fail(obj != NULL);
|
||||
// nop
|
||||
G_OBJECT_CLASS(parent_class)->finalize(obj);
|
||||
}
|
43
src/gnome-utils/gnc-sx-instance-dense-cal-adapter.h
Normal file
43
src/gnome-utils/gnc-sx-instance-dense-cal-adapter.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* gnc-sx-instance-dense-cal-adapter.h
|
||||
*
|
||||
* Copyright (C) 2006 Josh Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
#ifndef _GNC_SX_INSTANCE_DENSE_CAL_ADAPTER_H
|
||||
#define _GNC_SX_INSTANCE_DENSE_CAL_ADAPTER_H
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include "gnc-sx-instance-model.h"
|
||||
|
||||
typedef struct _GncSxInstanceDenseCalAdapterClass GncSxInstanceDenseCalAdapterClass;
|
||||
typedef struct _GncSxInstanceDenseCalAdapter GncSxInstanceDenseCalAdapter;
|
||||
|
||||
#define GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER (gnc_sx_instance_dense_cal_adapter_get_type ())
|
||||
#define GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER, GncSxInstanceDenseCalAdapter))
|
||||
#define GNC_SX_INSTANCE_DENSE_CAL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER, GncSxInstanceDenseCalAdapterClass))
|
||||
#define GNC_IS_SX_INSTANCE_DENSE_CAL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER))
|
||||
#define GNC_IS_SX_INSTANCE_DENSE_CAL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER))
|
||||
#define GNC_SX_INSTANCE_DENSE_CAL_ADAPTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER, GncSxInstanceDenseCalAdapterClass))
|
||||
|
||||
GncSxInstanceDenseCalAdapter* gnc_sx_instance_dense_cal_adapter_new(GncSxInstanceModel *instances);
|
||||
GType gnc_sx_instance_dense_cal_adapter_get_type(void);
|
||||
|
||||
#endif // _GNC_SX_INSTANCE_DENSE_CAL_ADAPTER_H
|
@ -1,5 +1,5 @@
|
||||
TESTS = \
|
||||
test-link-module test-load-module
|
||||
test-link-module test-load-module test-sx
|
||||
|
||||
# The following tests are nice, but have absolutely no place in an
|
||||
# automated testing system.
|
||||
@ -26,29 +26,30 @@ TESTS_ENVIRONMENT := \
|
||||
$(shell ${top_srcdir}/src/gnc-test-env --no-exports ${GNC_TEST_DEPS})
|
||||
|
||||
check_PROGRAMS = \
|
||||
test-link-module test-gnc-recurrence test-gnc-dialog
|
||||
test-link-module test-gnc-recurrence test-gnc-dialog test-sx
|
||||
|
||||
INCLUDES= \
|
||||
-I${top_srcdir}/src \
|
||||
-I${top_srcdir}/src/engine \
|
||||
-I${top_srcdir}/src/engine/test-core \
|
||||
-I${top_srcdir}/src/gnome-utils \
|
||||
-I${top_srcdir}/src/gnc-module \
|
||||
-I${top_srcdir}/src/app-utils \
|
||||
-I${top_srcdir}/src/test-core \
|
||||
${GLIB_CFLAGS} ${GUILE_INCS} ${GNOME_CFLAGS} ${GLADE_CFLAGS} ${QOF_CFLAGS}
|
||||
|
||||
test_gnc_recurrence_SOURCES=test-gnc-recurrence.c
|
||||
test_gnc_recurrence_LDADD = ${GNOME_LIBS} \
|
||||
LDADD = \
|
||||
${GNOME_LIBS} \
|
||||
${top_builddir}/src/app-utils/libgncmod-app-utils.la \
|
||||
${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
|
||||
${top_builddir}/src/engine/libgncmod-engine.la
|
||||
${top_builddir}/src/engine/libgncmod-engine.la \
|
||||
${top_builddir}/src/engine/test-core/libgncmod-test-engine.la \
|
||||
${top_builddir}/src/test-core/libgncmod-test.la
|
||||
|
||||
test_gnc_dialog_LDADD = ${GNOME_LIBS} \
|
||||
${top_builddir}/src/app-utils/libgncmod-app-utils.la \
|
||||
${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
|
||||
${top_builddir}/src/engine/libgncmod-engine.la
|
||||
test_gnc_recurrence_SOURCES=test-gnc-recurrence.c
|
||||
|
||||
test_link_module_SOURCES=test-link-module.c
|
||||
test_link_module_LDADD= \
|
||||
test_link_module_LDADD = \
|
||||
${GUILE_LIBS} \
|
||||
${top_builddir}/src/gnc-module/libgnc-module.la
|
||||
|
||||
|
82
src/gnome-utils/test/test-sx.c
Normal file
82
src/gnome-utils/test/test-sx.c
Normal file
@ -0,0 +1,82 @@
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include "qof.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-sx-instance-model.h"
|
||||
#include "gnc-sx-instance-dense-cal-adapter.h"
|
||||
#include "gnc-dense-cal.h"
|
||||
#include "gnc-dense-cal-model.h"
|
||||
|
||||
#include "test-stuff.h"
|
||||
#include "test-engine-stuff.h"
|
||||
|
||||
static void
|
||||
_removing(GObject *obj, SchedXaction *removing, gpointer unused_user_data)
|
||||
{
|
||||
gnc_sx_instance_model_remove_sx_instances(GNC_SX_INSTANCE_MODEL(obj), removing);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_default_handlers(GncSxInstanceModel *model)
|
||||
{
|
||||
g_signal_connect(model, "removing", (GCallback)_removing, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test()
|
||||
{
|
||||
GDate *start, *end;
|
||||
GncSxInstanceModel *model;
|
||||
GncSxInstanceDenseCalAdapter *dense_cal_model;
|
||||
GncDenseCal *cal;
|
||||
SchedXaction *foo, *bar;
|
||||
|
||||
start = g_date_new();
|
||||
g_date_clear(start, 1);
|
||||
g_date_set_time_t(start, time(NULL));
|
||||
|
||||
end = g_date_new();
|
||||
g_date_clear(end, 1);
|
||||
g_date_set_time_t(end, time(NULL));
|
||||
g_date_add_years(end, 1);
|
||||
|
||||
foo = add_daily_sx("foo", start, NULL, NULL);
|
||||
|
||||
model = gnc_sx_get_instances(end);
|
||||
setup_default_handlers(model);
|
||||
|
||||
do_test(g_list_length(model->sx_instance_list) == 1, "1 instances");
|
||||
|
||||
dense_cal_model = gnc_sx_instance_dense_cal_adapter_new(model);
|
||||
cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(dense_cal_model)));
|
||||
// gobject-2.10: g_object_ref_sink(cal);
|
||||
g_object_ref(G_OBJECT(cal));
|
||||
gtk_object_sink(GTK_OBJECT(cal));
|
||||
|
||||
bar = add_daily_sx("bar", start, NULL, NULL);
|
||||
do_test(g_list_length(model->sx_instance_list) == 2, "2 instances");
|
||||
|
||||
remove_sx(foo);
|
||||
|
||||
do_test(g_list_length(model->sx_instance_list) == 1, "1 instance");
|
||||
|
||||
g_object_unref(cal);
|
||||
success("freed calendar");
|
||||
g_object_unref(dense_cal_model);
|
||||
success("freed dense-cal model");
|
||||
g_object_unref(model);
|
||||
success("freed instances");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
g_type_init();
|
||||
gnc_engine_init(argc, argv);
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
test();
|
||||
|
||||
print_test_results();
|
||||
exit(get_rv());
|
||||
}
|
@ -29,11 +29,11 @@ libgnc_gnome_la_SOURCES = \
|
||||
dialog-price-edit-db.c \
|
||||
dialog-print-check.c \
|
||||
dialog-progress.c \
|
||||
dialog-sx-editor.c \
|
||||
dialog-sx-from-trans.c \
|
||||
dialog-sxsincelast.c \
|
||||
dialog-sx-since-last-run.c \
|
||||
dialog-tax-info.c \
|
||||
dialog-userpass.c \
|
||||
dialog-scheduledxaction.c \
|
||||
druid-acct-period.c \
|
||||
druid-hierarchy.c \
|
||||
druid-merge.c \
|
||||
@ -45,8 +45,10 @@ libgnc_gnome_la_SOURCES = \
|
||||
gnc-plugin-register.c \
|
||||
gnc-plugin-page-account-tree.c \
|
||||
gnc-plugin-page-budget.c \
|
||||
gnc-plugin-page-sx-list.c \
|
||||
gnc-plugin-page-register.c \
|
||||
gnc-split-reg.c \
|
||||
gnc-sx-list-tree-model-adapter.c \
|
||||
lot-viewer.c \
|
||||
reconcile-list.c \
|
||||
top-level.c \
|
||||
@ -67,9 +69,9 @@ noinst_HEADERS = \
|
||||
dialog-new-user.h \
|
||||
dialog-print-check.h \
|
||||
dialog-progress.h \
|
||||
dialog-sx-editor.h \
|
||||
dialog-sx-from-trans.h \
|
||||
dialog-sxsincelast.h \
|
||||
dialog-scheduledxaction.h \
|
||||
dialog-sx-since-last-run.h \
|
||||
druid-acct-period.h \
|
||||
druid-hierarchy.h \
|
||||
druid-merge.h \
|
||||
@ -81,8 +83,10 @@ noinst_HEADERS = \
|
||||
gnc-plugin-register.h \
|
||||
gnc-plugin-page-account-tree.h \
|
||||
gnc-plugin-page-budget.h \
|
||||
gnc-plugin-page-sx-list.h \
|
||||
gnc-plugin-page-register.h \
|
||||
gnc-split-reg.h \
|
||||
gnc-sx-list-tree-model-adapter.h \
|
||||
lot-viewer.h \
|
||||
reconcile-list.h \
|
||||
top-level.h \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,10 @@
|
||||
/********************************************************************\
|
||||
* dialog-scheduledxaction.h : dialogs for scheduled transactions *
|
||||
* Copyright (C) 2001 Joshua Sled <jsled@asynchronous.org> *
|
||||
* dialog-sx-editor.h : dialog for scheduled transaction editing *
|
||||
* Copyright (C) 2001,2006 Joshua Sled <jsled@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. *
|
||||
* 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 *
|
||||
@ -20,8 +19,8 @@
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef DIALOG_SCHEDULEDXACTION_H
|
||||
#define DIALOG_SCHEDULEDXACTION_H
|
||||
#ifndef DIALOG_SX_EDITOR_H
|
||||
#define DIALOG_SX_EDITOR_H
|
||||
|
||||
#include "SchedXaction.h"
|
||||
|
||||
@ -34,29 +33,12 @@
|
||||
#define KEY_CREATE_DAYS "create_days"
|
||||
#define KEY_REMIND_DAYS "remind_days"
|
||||
|
||||
struct _SchedXactionDialog;
|
||||
struct _SchedXactionEditorDialog;
|
||||
typedef struct _GncSxEditorDialog GncSxEditorDialog;
|
||||
|
||||
typedef struct _SchedXactionDialog SchedXactionDialog;
|
||||
typedef struct _SchedXactionEditorDialog SchedXactionEditorDialog;
|
||||
GncSxEditorDialog* gnc_ui_scheduled_xaction_editor_dialog_create(SchedXaction *sx,
|
||||
gboolean newSX);
|
||||
|
||||
SchedXactionDialog * gnc_ui_scheduled_xaction_dialog_create(void);
|
||||
void gnc_ui_scheduled_xaction_dialog_destroy(SchedXactionDialog *sxd);
|
||||
#ifdef __GTK_CLIST_H__
|
||||
void row_select_handler( GtkCList *clist, gint row, gint col,
|
||||
GdkEventButton *event, gpointer d );
|
||||
void row_unselect_handler( GtkCList *clist, gint row, gint col,
|
||||
GdkEventButton *event, gpointer d );
|
||||
#endif
|
||||
|
||||
void gnc_sxd_list_refresh( SchedXactionDialog *sxd );
|
||||
|
||||
SchedXactionEditorDialog *
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
|
||||
SchedXaction *sx,
|
||||
gboolean newSX );
|
||||
|
||||
void gnc_ui_scheduled_xaction_editor_dialog_destroy( SchedXactionEditorDialog *sxd );
|
||||
void gnc_ui_scheduled_xaction_editor_dialog_destroy(GncSxEditorDialog *sxd);
|
||||
|
||||
/**
|
||||
* Sets up a book opened hook. The function called may open a "since
|
@ -25,26 +25,25 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include "glib-compat.h"
|
||||
|
||||
#include "gnc-engine.h"
|
||||
#include "SX-book.h"
|
||||
#include "SX-book-p.h"
|
||||
#include "SX-ttinfo.h"
|
||||
#include "SchedXaction.h"
|
||||
#include "gnc-component-manager.h"
|
||||
#include "dialog-scheduledxaction.h"
|
||||
#include "dialog-sx-editor.h"
|
||||
#include "dialog-sx-from-trans.h"
|
||||
#include "dialog-utils.h"
|
||||
#include "glib-compat.h"
|
||||
#include "gnc-component-manager.h"
|
||||
#include "gnc-date-edit.h"
|
||||
#include "qof.h"
|
||||
#include "gnc-gconf-utils.h"
|
||||
#include "gnc-ui.h"
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-dense-cal-store.h"
|
||||
#include "gnc-dense-cal.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-gconf-utils.h"
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-ui.h"
|
||||
#include "qof.h"
|
||||
#include "SchedXaction.h"
|
||||
#include "SX-book.h"
|
||||
#include "SX-ttinfo.h"
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SX_GLADE_FILE "sched-xact.glade"
|
||||
#define SXFTD_DIALOG_GLADE_NAME "sx_from_real_trans"
|
||||
@ -78,11 +77,8 @@ static void gnc_sx_trans_window_response_cb(GtkDialog *dialog, gint response, gp
|
||||
|
||||
static void sxftd_destroy( GtkWidget *w, gpointer user_data );
|
||||
|
||||
typedef enum { NEVER_END, END_ON_DATE, END_AFTER_N_OCCS, BAD_END } endType;
|
||||
|
||||
typedef enum { FREQ_DAILY = 0, /* I know the =0 is redundant, but I'm using
|
||||
* the numeric equivalences explicitly here
|
||||
*/
|
||||
* the numeric equivalences explicitly here */
|
||||
FREQ_WEEKLY,
|
||||
FREQ_BIWEEKLY,
|
||||
FREQ_MONTHLY,
|
||||
@ -97,11 +93,8 @@ typedef struct
|
||||
Transaction *trans;
|
||||
SchedXaction *sx;
|
||||
|
||||
GncDenseCalStore *dense_cal_model;
|
||||
GncDenseCal *example_cal;
|
||||
/** Storage for the maximum possible number of marks we could put on the
|
||||
* calendar. */
|
||||
GDate **cal_marks;
|
||||
gint mark_id;
|
||||
|
||||
GNCDateEdit *startDateGDE, *endDateGDE;
|
||||
|
||||
@ -109,7 +102,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
endType type;
|
||||
gdcs_end_type type;
|
||||
GDate end_date;
|
||||
guint n_occurrences;
|
||||
} getEndTuple;
|
||||
@ -117,9 +110,6 @@ typedef struct
|
||||
static void sxftd_update_example_cal( SXFromTransInfo *sxfti );
|
||||
static void sxftd_update_excal_adapt( GObject *o, gpointer ud );
|
||||
|
||||
/* Stolen from jsled - nice and neat, actually (if a little light on
|
||||
* for typechecking, but we'll be careful) . . .
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
gchar *name;
|
||||
@ -127,11 +117,9 @@ typedef struct
|
||||
void (*handlerFn)();
|
||||
} widgetSignalHandlerTuple;
|
||||
|
||||
|
||||
static void sxftd_ok_clicked(SXFromTransInfo *sxfti);
|
||||
static void sxftd_advanced_clicked(SXFromTransInfo *sxfti);
|
||||
|
||||
|
||||
static void
|
||||
sxfti_attach_callbacks(SXFromTransInfo *sxfti)
|
||||
{
|
||||
@ -144,7 +132,6 @@ sxfti_attach_callbacks(SXFromTransInfo *sxfti)
|
||||
{ SXFTD_END_ON_DATE_BUTTON, "clicked", sxftd_update_excal_adapt },
|
||||
{ SXFTD_N_OCCURRENCES_BUTTON, "clicked", sxftd_update_excal_adapt },
|
||||
{ SXFTD_N_OCCURRENCES_ENTRY, "changed", sxftd_update_excal_adapt },
|
||||
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -370,20 +357,19 @@ sxftd_init( SXFromTransInfo *sxfti )
|
||||
|
||||
/* Setup the example calendar and related data structures. */
|
||||
{
|
||||
int i;
|
||||
int num_marks = SXFTD_EXCAL_NUM_MONTHS * 31;
|
||||
|
||||
w = GTK_WIDGET(glade_xml_get_widget( sxfti->gxml, SXFTD_EX_CAL_FRAME ));
|
||||
sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new());
|
||||
sxfti->dense_cal_model = gnc_dense_cal_store_new(num_marks);
|
||||
sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(sxfti->dense_cal_model)));
|
||||
// gobject-2.10: g_object_ref_sink(sxfti->example_cal);
|
||||
g_object_ref(G_OBJECT(sxfti->example_cal));
|
||||
gtk_object_sink(GTK_OBJECT(sxfti->example_cal));
|
||||
|
||||
g_assert( sxfti->example_cal );
|
||||
gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS );
|
||||
gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL );
|
||||
gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) );
|
||||
|
||||
sxfti->mark_id = -1;
|
||||
sxfti->cal_marks = g_new0( GDate*, (SXFTD_EXCAL_NUM_MONTHS * 31) );
|
||||
for ( i=0; i < SXFTD_EXCAL_NUM_MONTHS * 31; i++ ) {
|
||||
sxfti->cal_marks[i] = g_date_new();
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the start and end dates as GNCDateEdits */
|
||||
@ -551,7 +537,7 @@ static void
|
||||
sxftd_ok_clicked(SXFromTransInfo *sxfti)
|
||||
{
|
||||
QofBook *book;
|
||||
GList *sx_list;
|
||||
SchedXactions *sxes;
|
||||
guint sx_error = sxftd_compute_sx(sxfti);
|
||||
|
||||
if (sx_error != 0
|
||||
@ -559,23 +545,14 @@ sxftd_ok_clicked(SXFromTransInfo *sxfti)
|
||||
PERR( "Error in sxftd_compute_sx after ok_clicked [%d]", sx_error );
|
||||
}
|
||||
else {
|
||||
SchedXactionDialog *sxd;
|
||||
|
||||
if ( sx_error == SXFTD_ERRNO_UNBALANCED_XACTION ) {
|
||||
gnc_error_dialog( gnc_ui_get_toplevel(),
|
||||
_( "The Scheduled Transaction is unbalanced. "
|
||||
"You are strongly encouraged to correct this situation." ) );
|
||||
}
|
||||
book = gnc_get_current_book ();
|
||||
sx_list = gnc_book_get_schedxactions(book);
|
||||
sx_list = g_list_append(sx_list, sxfti->sx);
|
||||
gnc_book_set_schedxactions(book, sx_list);
|
||||
sxd = (SchedXactionDialog*)
|
||||
gnc_find_first_gui_component(
|
||||
DIALOG_SCHEDXACTION_CM_CLASS, NULL, NULL );
|
||||
if ( sxd ) {
|
||||
gnc_sxd_list_refresh( sxd );
|
||||
}
|
||||
sxes = gnc_book_get_schedxactions(book);
|
||||
gnc_sxes_add_sx(sxes, sxfti->sx);
|
||||
}
|
||||
|
||||
sxftd_close(sxfti, FALSE);
|
||||
@ -617,8 +594,7 @@ static void
|
||||
sxftd_advanced_clicked(SXFromTransInfo *sxfti)
|
||||
{
|
||||
guint sx_error = sxftd_compute_sx(sxfti);
|
||||
SchedXactionDialog *adv_dlg;
|
||||
SchedXactionEditorDialog *adv_edit_dlg;
|
||||
GncSxEditorDialog *adv_edit_dlg;
|
||||
GMainContext *context;
|
||||
|
||||
if ( sx_error != 0
|
||||
@ -634,10 +610,8 @@ sxftd_advanced_clicked(SXFromTransInfo *sxfti)
|
||||
context = g_main_context_default();
|
||||
while (g_main_context_iteration(context, FALSE));
|
||||
|
||||
adv_dlg = gnc_ui_scheduled_xaction_dialog_create();
|
||||
adv_edit_dlg =
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(adv_dlg,
|
||||
sxfti->sx,
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(sxfti->sx,
|
||||
TRUE /* newSX */);
|
||||
/* close ourself, since advanced editing entails us, and there are sync
|
||||
* issues otherwise. */
|
||||
@ -647,28 +621,21 @@ sxftd_advanced_clicked(SXFromTransInfo *sxfti)
|
||||
static void
|
||||
sxftd_destroy( GtkWidget *w, gpointer user_data )
|
||||
{
|
||||
int i;
|
||||
SXFromTransInfo *sxfti = (SXFromTransInfo*)user_data;
|
||||
|
||||
for ( i=0; i<SXFTD_EXCAL_NUM_MONTHS*31; i++ ) {
|
||||
g_date_free( sxfti->cal_marks[i] );
|
||||
}
|
||||
g_free( sxfti->cal_marks );
|
||||
|
||||
if ( sxfti->sx ) {
|
||||
xaccSchedXactionFree(sxfti->sx);
|
||||
sxfti->sx = NULL;
|
||||
}
|
||||
|
||||
g_object_unref(G_OBJECT(sxfti->dense_cal_model));
|
||||
g_object_unref(G_OBJECT(sxfti->example_cal));
|
||||
|
||||
/* FIXME: do we need to clean up the GladeXML pointer? */
|
||||
|
||||
g_free(sxfti);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
static void
|
||||
gnc_sx_trans_window_response_cb (GtkDialog *dialog,
|
||||
gint response,
|
||||
@ -696,7 +663,6 @@ gnc_sx_trans_window_response_cb (GtkDialog *dialog,
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the example calendar; make sure to take into account the end
|
||||
* specification.
|
||||
@ -707,11 +673,8 @@ sxftd_update_example_cal( SXFromTransInfo *sxfti )
|
||||
struct tm *tmpTm;
|
||||
time_t tmp_tt;
|
||||
GDate date, startDate;
|
||||
unsigned int i;
|
||||
FreqSpec *fs;
|
||||
getEndTuple get;
|
||||
gchar *name;
|
||||
GString *info;
|
||||
|
||||
fs = xaccFreqSpecMalloc( gnc_get_current_book() );
|
||||
get = sxftd_get_end_info( sxfti );
|
||||
@ -733,42 +696,26 @@ sxftd_update_example_cal( SXFromTransInfo *sxfti )
|
||||
xaccFreqSpecGetNextInstance( fs, &date, &date );
|
||||
startDate = date;
|
||||
|
||||
i = 0;
|
||||
while ( (i < (SXFTD_EXCAL_NUM_MONTHS * 31))
|
||||
&& g_date_valid( &date )
|
||||
/* Do checking against end restriction. */
|
||||
&& ( ( get.type == NEVER_END )
|
||||
|| ( get.type == END_ON_DATE
|
||||
&& g_date_compare( &date, &(get.end_date) ) <= 0 )
|
||||
|| ( get.type == END_AFTER_N_OCCS
|
||||
&& i < get.n_occurrences ) ) ) {
|
||||
switch (get.type)
|
||||
{
|
||||
case NEVER_END:
|
||||
gnc_dense_cal_store_update_no_end(sxfti->dense_cal_model, &startDate, fs);
|
||||
break;
|
||||
case END_ON_DATE:
|
||||
gnc_dense_cal_store_update_date_end(sxfti->dense_cal_model, &startDate, fs, &get.end_date);
|
||||
break;
|
||||
case END_AFTER_N_OCCS:
|
||||
gnc_dense_cal_store_update_count_end(sxfti->dense_cal_model, &startDate, fs, get.n_occurrences);
|
||||
break;
|
||||
default:
|
||||
printf("unknown get.type [%d]\n", get.type);
|
||||
break;
|
||||
}
|
||||
|
||||
*sxfti->cal_marks[i++] = date;
|
||||
xaccFreqSpecGetNextInstance( fs, &date, &date );
|
||||
}
|
||||
/* remove old marks */
|
||||
if ( sxfti->mark_id != -1 ) {
|
||||
gnc_dense_cal_mark_remove( sxfti->example_cal, sxfti->mark_id );
|
||||
sxfti->mark_id = -1;
|
||||
}
|
||||
if ( i > 0 ) {
|
||||
GtkWidget *w;
|
||||
gnc_dense_cal_set_month( sxfti->example_cal,
|
||||
g_date_get_month( &startDate ) );
|
||||
gnc_dense_cal_set_year( sxfti->example_cal,
|
||||
g_date_get_year( &startDate ) );
|
||||
w = glade_xml_get_widget( sxfti->gxml, SXFTD_NAME_ENTRY );
|
||||
name = gtk_editable_get_chars( GTK_EDITABLE(w), 0, -1 );
|
||||
info = g_string_sized_new( 16 );
|
||||
xaccFreqSpecGetFreqStr( fs, info );
|
||||
sxfti->mark_id =
|
||||
gnc_dense_cal_mark( sxfti->example_cal,
|
||||
i, sxfti->cal_marks,
|
||||
name, info->str );
|
||||
gtk_widget_queue_draw( GTK_WIDGET(sxfti->example_cal) );
|
||||
g_free( name );
|
||||
g_string_free( info, TRUE );
|
||||
}
|
||||
gnc_dense_cal_set_month( sxfti->example_cal,
|
||||
g_date_get_month( &startDate ) );
|
||||
gnc_dense_cal_set_year( sxfti->example_cal,
|
||||
g_date_get_year( &startDate ) );
|
||||
|
||||
xaccFreqSpecFree( fs );
|
||||
}
|
||||
@ -784,10 +731,6 @@ sxftd_update_excal_adapt( GObject *o, gpointer ud )
|
||||
sxftd_update_example_cal( sxfti );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
void
|
||||
gnc_sx_create_from_trans( Transaction *trans )
|
||||
{
|
||||
|
1105
src/gnome/dialog-sx-since-last-run.c
Normal file
1105
src/gnome/dialog-sx-since-last-run.c
Normal file
File diff suppressed because it is too large
Load Diff
52
src/gnome/dialog-sx-since-last-run.h
Normal file
52
src/gnome/dialog-sx-since-last-run.h
Normal file
@ -0,0 +1,52 @@
|
||||
/********************************************************************\
|
||||
* dialog-sx-since-last-run.h : dialog for scheduled transaction *
|
||||
* since-last-run processing. *
|
||||
* Copyright (C) 2006 Joshua Sled <jsled@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@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef DIALOG_SX_SINCE_LAST_RUN_H
|
||||
#define DIALOG_SX_SINCE_LAST_RUN_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gnc-sx-instance-model.h"
|
||||
#include "gnc-plugin-page-sx-list.h"
|
||||
|
||||
typedef struct _GncSxSlrTreeModelAdapter GncSxSlrTreeModelAdapter;
|
||||
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.
|
||||
**/
|
||||
GncSxSinceLastRunDialog* gnc_ui_sx_since_last_run_dialog(GncSxInstanceModel *sx_instances);
|
||||
|
||||
// eliminate...
|
||||
void gnc_ui_sxsincelast_dialog_create(void);
|
||||
|
||||
//void gnc_sx_slr_model_effect_change(GncSxSlrTreeModelAdapter *model, gboolean auto_create_only, GList **created_transaction_guids, GList **creation_errors);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,60 +0,0 @@
|
||||
/********************************************************************\
|
||||
* dialog-sxsincelast.h - SchedXaction "Since-Last-Run" dialog *
|
||||
* Copyright (c) 2001 Joshua Sled <jsled@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@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef DIALOG_SXSINCELAST_H
|
||||
#define DIALOG_SXSINCELAST_H
|
||||
|
||||
/**
|
||||
* @return The magnitude of the return value is the number of auto-created,
|
||||
* no-notification scheduled transactions created. This value is positive if
|
||||
* there are additionally other SXes which need user interaction and the
|
||||
* Druid has been displayed, or negative if there are not, and no Druid
|
||||
* window was realized. In the case where there the dialog has been
|
||||
* displayed but no auto-create-no-notify transactions have been created,
|
||||
* INT_MAX [limits.h] is returned. 0 is treated as negative, with no
|
||||
* transactions created and no dialog displayed. The caller can use this
|
||||
* value as appropriate to inform the user.
|
||||
*
|
||||
* [e.g., for book-open-hook: do nothing; for menu-selection: display an info
|
||||
* dialog stating there's nothing to do.]
|
||||
**/
|
||||
gint gnc_ui_sxsincelast_dialog_create( void );
|
||||
void gnc_sx_sxsincelast_book_opened (void);
|
||||
|
||||
/**
|
||||
* Returns the varaibles from the Splits of the given SchedXaction as the
|
||||
* keys of the given GHashTable.
|
||||
**/
|
||||
void sxsl_get_sx_vars( SchedXaction *sx, GHashTable *varHash );
|
||||
|
||||
/**
|
||||
* Returns the variables from the given formula [free-form non-numeric
|
||||
* character strings] as the keys of the given GHashTable.
|
||||
* @param result can be NULL if you're not interested in the result
|
||||
**/
|
||||
int parse_vars_from_formula( const char *formula,
|
||||
GHashTable *varHash,
|
||||
gnc_numeric *result );
|
||||
|
||||
void print_vars_helper( gpointer key, gpointer value, gpointer user_data );
|
||||
|
||||
#endif // !defined(DIALOG_SXSINCELAST_H)
|
@ -35,7 +35,6 @@
|
||||
|
||||
#include "SchedXaction.h"
|
||||
#include "SX-book.h"
|
||||
#include "SX-book-p.h"
|
||||
#include "SX-ttinfo.h"
|
||||
#include "druid-utils.h"
|
||||
#include "gnc-book.h"
|
||||
@ -1982,7 +1981,8 @@ void
|
||||
ld_create_sx_from_tcSX( LoanDruidData *ldd, toCreateSX *tcSX )
|
||||
{
|
||||
SchedXaction *sx;
|
||||
GList *ttxnList, *sxList;
|
||||
SchedXactions *sxes;
|
||||
GList *ttxnList;
|
||||
|
||||
sx = xaccSchedXactionMalloc( gnc_get_current_book() );
|
||||
xaccSchedXactionSetName( sx, tcSX->name );
|
||||
@ -2003,9 +2003,8 @@ ld_create_sx_from_tcSX( LoanDruidData *ldd, toCreateSX *tcSX )
|
||||
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;
|
||||
|
@ -77,7 +77,7 @@
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox105">
|
||||
<widget class="GtkVBox" id="editor-vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
@ -2983,360 +2983,6 @@ December</property>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="Scheduled Transaction List">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Scheduled Transactions</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">640</property>
|
||||
<property name="default_height">480</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="has_separator">True</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox18">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">8</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area18">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="close_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847992">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Transactions</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment34">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox123">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">12</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCList" id="sched_xact_list">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="n_columns">3</property>
|
||||
<property name="column_widths">127,140,80</property>
|
||||
<property name="selection_mode">GTK_SELECTION_SINGLE</property>
|
||||
<property name="show_titles">True</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847750">
|
||||
<property name="label" translatable="yes">Name</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847751">
|
||||
<property name="label" translatable="yes">Frequency</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847752">
|
||||
<property name="label" translatable="yes">Next Occurrence</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVButtonBox" id="vbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
|
||||
<property name="spacing">10</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="new_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-new</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="edit_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment24">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">0</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox179">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-properties</property>
|
||||
<property name="icon_size">4</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847980">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Edit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="delete_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-delete</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847993">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847970">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Upcoming</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment35">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="upcoming_cal_hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="sx_from_real_trans">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Make Scheduled Transaction</property>
|
||||
@ -6717,4 +6363,364 @@ Custom</property>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkWindow" id="sx list plugin page content">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">window1</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVPaned" id="sx-list-vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="position">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox183">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847992">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Transactions</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment34">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox123">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">12</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="sx_list">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">True</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="enable_search">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="shrink">True</property>
|
||||
<property name="resize">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="upcoming mumble">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847993">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label847970">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Upcoming</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment35">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="upcoming_cal_hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="shrink">True</property>
|
||||
<property name="resize">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="since-last-run-dialog">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Since Last Run...</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">640</property>
|
||||
<property name="default_height">480</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="has_separator">True</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox25">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area25">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancelbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="okbutton2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox182">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVPaned" id="paned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="position">240</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow21">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="instance_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="headers_visible">True</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="shrink">True</property>
|
||||
<property name="resize">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox179">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkFixed" id="fixed1">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="review_txn_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">_Review created transactions</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
||||
|
@ -41,8 +41,7 @@
|
||||
#include "dialog-chart-export.h"
|
||||
#include "dialog-fincalc.h"
|
||||
#include "dialog-find-transactions.h"
|
||||
#include "dialog-scheduledxaction.h"
|
||||
#include "dialog-sxsincelast.h"
|
||||
#include "dialog-sx-since-last-run.h"
|
||||
#include "dialog-totd.h"
|
||||
#include "druid-acct-period.h"
|
||||
#include "druid-loan.h"
|
||||
@ -55,6 +54,8 @@
|
||||
#include "gnc-window.h"
|
||||
#include "gnc-session.h"
|
||||
|
||||
#include "gnc-plugin-page-sx-list.h"
|
||||
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = GNC_MOD_GUI;
|
||||
|
||||
@ -434,35 +435,50 @@ gnc_main_window_cmd_edit_tax_options (GtkAction *action, GncMainWindowActionData
|
||||
static void
|
||||
gnc_main_window_cmd_actions_scheduled_transaction_editor (GtkAction *action, GncMainWindowActionData *data)
|
||||
{
|
||||
gnc_ui_scheduled_xaction_dialog_create ();
|
||||
GncPluginPage *page = gnc_plugin_page_sx_list_new();
|
||||
gnc_main_window_open_page(NULL, page);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_main_window_cmd_actions_since_last_run (GtkAction *action, GncMainWindowActionData *data)
|
||||
{
|
||||
GncMainWindow *window;
|
||||
gint ret;
|
||||
GncSxInstanceModel *sx_instances;
|
||||
GncSxSummary summary;
|
||||
const char *nothing_to_do_msg =
|
||||
_( "There are no Scheduled Transactions to be entered at this time." );
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
window = data->window;
|
||||
ret = gnc_ui_sxsincelast_dialog_create ();
|
||||
if ( ret == 0 ) {
|
||||
gnc_info_dialog (GTK_WIDGET(&window->gtk_window), nothing_to_do_msg);
|
||||
} else if ( ret < 0 ) {
|
||||
gnc_info_dialog (GTK_WIDGET(&window->gtk_window), ngettext
|
||||
/* Translators: %d is the number of transactions. This is a
|
||||
ngettext(3) message. */
|
||||
("There are no Scheduled Transactions to be entered at this time. "
|
||||
"(%d transaction automatically created)",
|
||||
"There are no Scheduled Transactions to be entered at this time. "
|
||||
"(%d transactions automatically created)",
|
||||
-(ret)),
|
||||
-(ret));
|
||||
} /* else { this else [>0 means dialog was created] intentionally left
|
||||
* blank. } */
|
||||
|
||||
sx_instances = gnc_sx_get_current_instances();
|
||||
gnc_sx_instance_model_summarize(sx_instances, &summary);
|
||||
gnc_sx_instance_model_effect_change(sx_instances, TRUE, NULL, NULL);
|
||||
if (summary.need_dialog)
|
||||
{
|
||||
gnc_ui_sx_since_last_run_dialog(sx_instances);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (summary.num_auto_create_no_notify_instances == 0)
|
||||
{
|
||||
gnc_info_dialog(GTK_WIDGET(&window->gtk_window), nothing_to_do_msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
gnc_info_dialog(GTK_WIDGET(&window->gtk_window), ngettext
|
||||
/* Translators: %d is the number of transactions. This is a
|
||||
ngettext(3) message. */
|
||||
("There are no Scheduled Transactions to be entered at this time. "
|
||||
"(%d transaction automatically created)",
|
||||
"There are no Scheduled Transactions to be entered at this time. "
|
||||
"(%d transactions automatically created)",
|
||||
summary.num_auto_create_no_notify_instances),
|
||||
summary.num_auto_create_no_notify_instances);
|
||||
}
|
||||
}
|
||||
g_object_unref(G_OBJECT(sx_instances));
|
||||
}
|
||||
|
||||
static void
|
||||
|
628
src/gnome/gnc-plugin-page-sx-list.c
Normal file
628
src/gnome/gnc-plugin-page-sx-list.c
Normal file
@ -0,0 +1,628 @@
|
||||
/*
|
||||
* gnc-plugin-page-sx-list.c
|
||||
*
|
||||
* Copyright (C) 2006 Josh Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
/* todo:
|
||||
* - ui, actions, menus
|
||||
* - icon
|
||||
*/
|
||||
|
||||
/** @addtogroup ContentPlugins
|
||||
@{ */
|
||||
/** @addtogroup GncPluginPageSxList A SX List Plugin Page
|
||||
@{ */
|
||||
/** @brief Functions providing the SX List as a plugin page.
|
||||
@author Josh Sled <jsled@asynchronous.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glade/glade-xml.h>
|
||||
#ifndef HAVE_GLIB26
|
||||
#include "gkeyfile.h"
|
||||
#endif
|
||||
#include "gnc-exp-parser.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "Transaction.h"
|
||||
#include "Split.h"
|
||||
#include "gnc-commodity.h"
|
||||
#include "gnc-event.h"
|
||||
#include "gnc-dense-cal.h"
|
||||
#include "gnc-glib-utils.h"
|
||||
#include "gnc-icons.h"
|
||||
#include "gnc-plugin-page-sx-list.h"
|
||||
#include "gnc-sx-instance-model.h"
|
||||
#include "gnc-sx-instance-dense-cal-adapter.h"
|
||||
#include "gnc-sx-list-tree-model-adapter.h"
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-main-window.h"
|
||||
#include "dialog-utils.h"
|
||||
#include "gnc-component-manager.h"
|
||||
#include "SX-book.h"
|
||||
#include "gnc-book.h"
|
||||
#include "dialog-sx-editor.h"
|
||||
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = GNC_MOD_GUI;
|
||||
|
||||
#define PLUGIN_PAGE_SX_LIST_CM_CLASS "plugin-page-sx-list"
|
||||
#define GCONF_SECTION "window/pages/sx_list"
|
||||
|
||||
typedef struct GncPluginPageSxListPrivate
|
||||
{
|
||||
gboolean disposed;
|
||||
|
||||
GtkWidget* widget;
|
||||
gint gnc_component_id;
|
||||
|
||||
GladeXML* gxml;
|
||||
GncSxInstanceDenseCalAdapter *dense_cal_model;
|
||||
GncDenseCal* gdcal;
|
||||
|
||||
GncSxInstanceModel* instances;
|
||||
GncSxListTreeModelAdapter* tree_model;
|
||||
GtkTreeView* tree_view;
|
||||
} GncPluginPageSxListPrivate;
|
||||
|
||||
#define GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_PAGE_SX_LIST, GncPluginPageSxListPrivate))
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
/************************************************************
|
||||
* Prototypes *
|
||||
************************************************************/
|
||||
/* Plugin Actions */
|
||||
static void gnc_plugin_page_sx_list_class_init (GncPluginPageSxListClass *klass);
|
||||
static void gnc_plugin_page_sx_list_init (GncPluginPageSxList *plugin_page);
|
||||
static void gnc_plugin_page_sx_list_dispose(GObject *object);
|
||||
static void gnc_plugin_page_sx_list_finalize(GObject *object);
|
||||
|
||||
static GtkWidget *gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page);
|
||||
static void gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page);
|
||||
static void gnc_plugin_page_sx_list_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
|
||||
static GncPluginPage *gnc_plugin_page_sx_list_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
|
||||
|
||||
static void gppsl_row_activated_cb(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data);
|
||||
|
||||
/* Callbacks */
|
||||
static void gnc_plugin_page_sx_list_cmd_new(GtkAction *action, GncPluginPageSxList *page);
|
||||
static void gnc_plugin_page_sx_list_cmd_edit(GtkAction *action, GncPluginPageSxList *page);
|
||||
static void gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page);
|
||||
|
||||
/* Command callbacks */
|
||||
|
||||
static GtkActionEntry gnc_plugin_page_sx_list_actions [] = {
|
||||
{ "SxListAction", NULL, N_("Scheduled"), NULL, NULL, NULL },
|
||||
{ "SxListNewAction", GNC_STOCK_NEW_ACCOUNT, N_("New"), NULL,
|
||||
N_("Create a new scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_new) },
|
||||
{ "SxListEditAction", GNC_STOCK_EDIT_ACCOUNT, N_("Edit"), NULL,
|
||||
N_("Edit the selected scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_edit) },
|
||||
{ "SxListDeleteAction", GNC_STOCK_DELETE_ACCOUNT, N_("Delete"), NULL,
|
||||
N_("Delete the selected scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_delete) },
|
||||
};
|
||||
/** The number of actions provided by this plugin. */
|
||||
static guint gnc_plugin_page_sx_list_n_actions = G_N_ELEMENTS (gnc_plugin_page_sx_list_actions);
|
||||
|
||||
GType
|
||||
gnc_plugin_page_sx_list_get_type (void)
|
||||
{
|
||||
static GType gnc_plugin_page_sx_list_type = 0;
|
||||
|
||||
if (gnc_plugin_page_sx_list_type == 0) {
|
||||
static const GTypeInfo our_info = {
|
||||
sizeof (GncPluginPageSxListClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gnc_plugin_page_sx_list_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GncPluginPageSxList),
|
||||
0,
|
||||
(GInstanceInitFunc) gnc_plugin_page_sx_list_init
|
||||
};
|
||||
|
||||
gnc_plugin_page_sx_list_type = g_type_register_static (GNC_TYPE_PLUGIN_PAGE,
|
||||
GNC_PLUGIN_PAGE_SX_LIST_NAME,
|
||||
&our_info, 0);
|
||||
}
|
||||
|
||||
return gnc_plugin_page_sx_list_type;
|
||||
}
|
||||
|
||||
GncPluginPage *
|
||||
gnc_plugin_page_sx_list_new (void)
|
||||
{
|
||||
GncPluginPageSxList *plugin_page;
|
||||
plugin_page = g_object_new(GNC_TYPE_PLUGIN_PAGE_SX_LIST, NULL);
|
||||
return GNC_PLUGIN_PAGE(plugin_page);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_class_init (GncPluginPageSxListClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent(klass);
|
||||
|
||||
object_class->dispose = gnc_plugin_page_sx_list_dispose;
|
||||
object_class->finalize = gnc_plugin_page_sx_list_finalize;
|
||||
|
||||
gnc_plugin_class->tab_icon = GNC_STOCK_ACCOUNT;
|
||||
gnc_plugin_class->plugin_name = GNC_PLUGIN_PAGE_SX_LIST_NAME;
|
||||
gnc_plugin_class->create_widget = gnc_plugin_page_sx_list_create_widget;
|
||||
gnc_plugin_class->destroy_widget = gnc_plugin_page_sx_list_destroy_widget;
|
||||
gnc_plugin_class->save_page = gnc_plugin_page_sx_list_save_page;
|
||||
gnc_plugin_class->recreate_page = gnc_plugin_page_sx_list_recreate_page;
|
||||
|
||||
g_type_class_add_private(klass, sizeof(GncPluginPageSxListPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_init (GncPluginPageSxList *plugin_page)
|
||||
{
|
||||
GtkActionGroup *action_group;
|
||||
GncPluginPageSxListPrivate *priv;
|
||||
GncPluginPage *parent;
|
||||
|
||||
ENTER("page %p", plugin_page);
|
||||
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
|
||||
|
||||
/* Init parent declared variables */
|
||||
parent = GNC_PLUGIN_PAGE(plugin_page);
|
||||
g_object_set(G_OBJECT(plugin_page),
|
||||
"page-name", _("Scheduled Transactions"),
|
||||
"page-uri", "default:",
|
||||
"ui-description", "gnc-plugin-page-sx-list-ui.xml",
|
||||
NULL);
|
||||
|
||||
/* change me when the system supports multiple books */
|
||||
gnc_plugin_page_add_book(parent, gnc_get_current_book());
|
||||
|
||||
/* Create menu and toolbar information */
|
||||
action_group =
|
||||
gnc_plugin_page_create_action_group(parent,
|
||||
"GncPluginPageSxListActions");
|
||||
gtk_action_group_add_actions(action_group,
|
||||
gnc_plugin_page_sx_list_actions,
|
||||
gnc_plugin_page_sx_list_n_actions,
|
||||
plugin_page);
|
||||
/* gnc_plugin_init_short_names (action_group, toolbar_labels); */
|
||||
|
||||
LEAVE("page %p, priv %p, action group %p",
|
||||
plugin_page, priv, action_group);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_dispose(GObject *object)
|
||||
{
|
||||
GncPluginPageSxList *page;
|
||||
GncPluginPageSxListPrivate *priv;
|
||||
|
||||
ENTER("object %p", object);
|
||||
|
||||
page = GNC_PLUGIN_PAGE_SX_LIST (object);
|
||||
g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST (page));
|
||||
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
g_return_if_fail(priv != NULL);
|
||||
|
||||
g_return_if_fail(!priv->disposed);
|
||||
priv->disposed = TRUE;
|
||||
|
||||
g_object_unref(G_OBJECT(priv->dense_cal_model));
|
||||
priv->dense_cal_model = NULL;
|
||||
gtk_widget_unref(GTK_WIDGET(priv->gdcal));
|
||||
priv->gdcal = NULL;
|
||||
g_object_unref(G_OBJECT(priv->instances));
|
||||
priv->instances = NULL;
|
||||
g_object_unref(G_OBJECT(priv->tree_model));
|
||||
priv->tree_model = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose(object);
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_finalize (GObject *object)
|
||||
{
|
||||
GncPluginPageSxList *page;
|
||||
GncPluginPageSxListPrivate *priv;
|
||||
|
||||
ENTER("object %p", object);
|
||||
|
||||
page = GNC_PLUGIN_PAGE_SX_LIST (object);
|
||||
g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST (page));
|
||||
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
g_return_if_fail(priv != NULL);
|
||||
|
||||
// by virtue of being a g_type_instance_..._private, does the private
|
||||
// data get freed somewhere else?
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
/* Virtual Functions */
|
||||
static void
|
||||
gnc_plugin_page_sx_list_refresh_cb (GHashTable *changes, gpointer user_data)
|
||||
{
|
||||
GncPluginPageSxList *page = user_data;
|
||||
GncPluginPageSxListPrivate *priv;
|
||||
|
||||
g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST(page));
|
||||
|
||||
/* We're only looking for forced updates here. */
|
||||
if (changes)
|
||||
return;
|
||||
|
||||
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
gtk_widget_queue_draw(priv->widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_close_cb (gpointer user_data)
|
||||
{
|
||||
GncPluginPage *plugin_page;
|
||||
GncPluginPageSxList *page;
|
||||
|
||||
plugin_page = GNC_PLUGIN_PAGE(user_data);
|
||||
page = GNC_PLUGIN_PAGE_SX_LIST (plugin_page);
|
||||
gnc_main_window_close_page(plugin_page);
|
||||
}
|
||||
|
||||
static void
|
||||
gppsl_selection_changed_cb(GtkTreeSelection *selection, gpointer user_data)
|
||||
{
|
||||
GncPluginPage *page;
|
||||
GtkAction *edit_action, *delete_action;
|
||||
gboolean selection_state = TRUE;
|
||||
|
||||
page = GNC_PLUGIN_PAGE(user_data);
|
||||
edit_action = gnc_plugin_page_get_action(page, "SxListEditAction");
|
||||
delete_action = gnc_plugin_page_get_action(page, "SxListDeleteAction");
|
||||
selection_state
|
||||
= gtk_tree_selection_count_selected_rows(selection) == 0
|
||||
? FALSE
|
||||
: TRUE;
|
||||
gtk_action_set_sensitive(edit_action, selection_state);
|
||||
gtk_action_set_sensitive(delete_action, selection_state);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
|
||||
{
|
||||
GncPluginPageSxList *page;
|
||||
GncPluginPageSxListPrivate *priv;
|
||||
|
||||
ENTER("page %p", plugin_page);
|
||||
page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
|
||||
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
if (priv->widget != NULL) {
|
||||
LEAVE("widget = %p", priv->widget);
|
||||
return priv->widget;
|
||||
}
|
||||
|
||||
priv->gxml = gnc_glade_xml_new("sched-xact.glade", "sx-list-vbox");
|
||||
priv->widget = glade_xml_get_widget(priv->gxml, "sx-list-vbox");
|
||||
|
||||
{
|
||||
//gint half_way;
|
||||
// half_way = plugin_page->notebook_page->allocation.height * 0.5;
|
||||
// fixme; get a real value:
|
||||
gtk_paned_set_position(GTK_PANED(priv->widget), 160);
|
||||
}
|
||||
|
||||
{
|
||||
GDate end;
|
||||
g_date_clear(&end, 1);
|
||||
g_date_set_time_t(&end, time(NULL));
|
||||
g_date_add_years(&end, 1);
|
||||
priv->instances = GNC_SX_INSTANCE_MODEL(gnc_sx_get_instances(&end));
|
||||
}
|
||||
|
||||
{
|
||||
GtkAction *edit_action, *delete_action;
|
||||
edit_action = gnc_plugin_page_get_action(GNC_PLUGIN_PAGE(page), "SxListEditAction");
|
||||
delete_action = gnc_plugin_page_get_action(GNC_PLUGIN_PAGE(page), "SxListDeleteAction");
|
||||
gtk_action_set_sensitive(edit_action, FALSE);
|
||||
gtk_action_set_sensitive(delete_action, FALSE);
|
||||
}
|
||||
|
||||
{
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
priv->tree_model = gnc_sx_list_tree_model_adapter_new(priv->instances);
|
||||
priv->tree_view = GTK_TREE_VIEW(glade_xml_get_widget(priv->gxml, "sx_list"));
|
||||
gtk_tree_view_set_model(priv->tree_view, GTK_TREE_MODEL(priv->tree_model));
|
||||
gtk_tree_view_set_headers_clickable(priv->tree_view, TRUE);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", SXLTMA_COL_NAME, NULL);
|
||||
gtk_tree_view_column_set_sort_column_id(column, SXLTMA_COL_NAME);
|
||||
gtk_tree_view_append_column(priv->tree_view, column);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Frequency", renderer, "text", SXLTMA_COL_FREQUENCY, NULL);
|
||||
gtk_tree_view_column_set_sort_column_id(column, SXLTMA_COL_FREQUENCY);
|
||||
gtk_tree_view_append_column(priv->tree_view, column);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Last Occur", renderer, "text", SXLTMA_COL_LAST_OCCUR, NULL);
|
||||
gtk_tree_view_column_set_sort_column_id(column, SXLTMA_COL_LAST_OCCUR);
|
||||
gtk_tree_view_append_column(priv->tree_view, column);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Next Occur", renderer, "text", SXLTMA_COL_NEXT_OCCUR, NULL);
|
||||
gtk_tree_view_column_set_sort_column_id(column, SXLTMA_COL_NEXT_OCCUR);
|
||||
gtk_tree_view_append_column(priv->tree_view, column);
|
||||
|
||||
selection = gtk_tree_view_get_selection(priv->tree_view);
|
||||
gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
|
||||
g_signal_connect(G_OBJECT(selection), "changed", (GCallback)gppsl_selection_changed_cb, (gpointer)page);
|
||||
|
||||
g_signal_connect(G_OBJECT(priv->tree_view), "row-activated", (GCallback)gppsl_row_activated_cb, (gpointer)page);
|
||||
}
|
||||
|
||||
{
|
||||
GtkWidget *w;
|
||||
|
||||
priv->dense_cal_model = gnc_sx_instance_dense_cal_adapter_new(GNC_SX_INSTANCE_MODEL(priv->instances));
|
||||
priv->gdcal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(priv->dense_cal_model)));
|
||||
// gobject-2.10: g_object_ref_sink(G_OBJECT(priv->gdcal));
|
||||
g_object_ref(G_OBJECT(priv->gdcal));
|
||||
gtk_object_sink(GTK_OBJECT(priv->gdcal));
|
||||
gnc_dense_cal_set_months_per_col(priv->gdcal, 4);
|
||||
gnc_dense_cal_set_num_months(priv->gdcal, 12);
|
||||
|
||||
w = glade_xml_get_widget(priv->gxml, "upcoming_cal_hbox");
|
||||
gtk_container_add(GTK_CONTAINER(w), GTK_WIDGET(priv->gdcal));
|
||||
gtk_widget_show_all(w);
|
||||
}
|
||||
|
||||
priv->gnc_component_id = gnc_register_gui_component("plugin-page-sx-list",
|
||||
gnc_plugin_page_sx_list_refresh_cb,
|
||||
gnc_plugin_page_sx_list_close_cb,
|
||||
page);
|
||||
|
||||
/* @@fixme */
|
||||
/* gnc_restore_window_size(SX_LIST_GCONF_SECTION, GTK_WINDOW(priv->widget)); */
|
||||
|
||||
return priv->widget;
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page)
|
||||
{
|
||||
GncPluginPageSxList *page;
|
||||
GncPluginPageSxListPrivate *priv;
|
||||
|
||||
ENTER("page %p", plugin_page);
|
||||
page = GNC_PLUGIN_PAGE_SX_LIST (plugin_page);
|
||||
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
|
||||
if (priv->widget) {
|
||||
g_object_unref(G_OBJECT(priv->widget));
|
||||
priv->widget = NULL;
|
||||
}
|
||||
|
||||
if (priv->gnc_component_id) {
|
||||
gnc_unregister_gui_component(priv->gnc_component_id);
|
||||
priv->gnc_component_id = 0;
|
||||
}
|
||||
|
||||
LEAVE("widget destroyed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Save enough information about this page that it can be recreated next time
|
||||
* the user starts gnucash.
|
||||
* @param page The page to save.
|
||||
* @param key_file A pointer to the GKeyFile data structure where the
|
||||
* page information should be written.
|
||||
* @param group_name The group name to use when saving data.
|
||||
**/
|
||||
static void
|
||||
gnc_plugin_page_sx_list_save_page (GncPluginPage *plugin_page,
|
||||
GKeyFile *key_file,
|
||||
const gchar *group_name)
|
||||
{
|
||||
GncPluginPageSxList *page;
|
||||
GncPluginPageSxListPrivate *priv;
|
||||
|
||||
g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST(plugin_page));
|
||||
g_return_if_fail(key_file != NULL);
|
||||
g_return_if_fail(group_name != NULL);
|
||||
|
||||
ENTER("page %p, key_file %p, group_name %s", plugin_page, key_file,
|
||||
group_name);
|
||||
|
||||
page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
|
||||
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
|
||||
#if 0
|
||||
gnc_tree_view_account_save(GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
|
||||
&priv->fd, key_file, group_name);
|
||||
#endif /* 0 */
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new sx list page based on the information saved during a previous
|
||||
* instantiation of gnucash.
|
||||
* @param window The window where this page should be installed.
|
||||
* @param key_file A pointer to the GKeyFile data structure where the
|
||||
* page information should be read.
|
||||
* @param group_name The group name to use when restoring data.
|
||||
**/
|
||||
static GncPluginPage *
|
||||
gnc_plugin_page_sx_list_recreate_page (GtkWidget *window,
|
||||
GKeyFile *key_file,
|
||||
const gchar *group_name)
|
||||
{
|
||||
GncPluginPageSxList *page;
|
||||
GncPluginPageSxListPrivate *priv;
|
||||
|
||||
g_return_val_if_fail(key_file, NULL);
|
||||
g_return_val_if_fail(group_name, NULL);
|
||||
ENTER("key_file %p, group_name %s", key_file, group_name);
|
||||
|
||||
/* Create the new page. */
|
||||
page = GNC_PLUGIN_PAGE_SX_LIST(gnc_plugin_page_sx_list_new());
|
||||
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
|
||||
/* Install it now so we can them manipulate the created widget */
|
||||
gnc_main_window_open_page(GNC_MAIN_WINDOW(window), GNC_PLUGIN_PAGE(page));
|
||||
|
||||
#if 0
|
||||
gnc_tree_view_account_restore(GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
|
||||
&priv->fd, key_file, group_name);
|
||||
#endif /* 0 */
|
||||
LEAVE(" ");
|
||||
return GNC_PLUGIN_PAGE(page);
|
||||
}
|
||||
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
static SchedXaction*
|
||||
_sx_for_path(gpointer data, gpointer user_data)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
|
||||
gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, (GtkTreePath*)data);
|
||||
return gnc_sx_list_tree_model_adapter_get_sx_instances(model, &iter)->sx;
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_cmd_new(GtkAction *action, GncPluginPageSxList *page)
|
||||
{
|
||||
FreqSpec *fs;
|
||||
SchedXaction *new_sx;
|
||||
gboolean new_sx_flag = TRUE;
|
||||
|
||||
new_sx = xaccSchedXactionMalloc(gnc_get_current_book());
|
||||
/* Give decent initial FreqSpec for SX */
|
||||
fs = xaccSchedXactionGetFreqSpec(new_sx);
|
||||
{
|
||||
GDate *now;
|
||||
now = g_date_new();
|
||||
g_date_set_time_t(now, time(NULL));
|
||||
xaccFreqSpecSetMonthly(fs, now, 1);
|
||||
xaccFreqSpecSetUIType(fs, UIFREQ_MONTHLY);
|
||||
g_date_free(now);
|
||||
}
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(new_sx, new_sx_flag);
|
||||
}
|
||||
|
||||
static void
|
||||
_edit_sx(gpointer data, gpointer user_data)
|
||||
{
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create((SchedXaction*)data, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_cmd_edit(GtkAction *action, GncPluginPageSxList *page)
|
||||
{
|
||||
GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
GtkTreeSelection *selection;
|
||||
GList *selected_paths, *to_edit;
|
||||
GtkTreeModel *model;
|
||||
|
||||
selection = gtk_tree_view_get_selection(priv->tree_view);
|
||||
selected_paths = gtk_tree_selection_get_selected_rows(selection, &model);
|
||||
if (g_list_length(selected_paths) == 0)
|
||||
{
|
||||
PERR("no selection edit.");
|
||||
return;
|
||||
}
|
||||
|
||||
to_edit = gnc_g_list_map(selected_paths, (GncGMapFunc)_sx_for_path, model);
|
||||
g_list_foreach(to_edit, (GFunc)_edit_sx, NULL);
|
||||
g_list_free(to_edit);
|
||||
g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
|
||||
g_list_free(selected_paths);
|
||||
}
|
||||
|
||||
static void
|
||||
gppsl_row_activated_cb(GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
gpointer user_data)
|
||||
{
|
||||
GncPluginPageSxList *page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
|
||||
GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
SchedXaction *sx = _sx_for_path(path, priv->tree_model);
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(sx, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_destroy_sx(gpointer data, gpointer user_data)
|
||||
{
|
||||
SchedXactions *sxes;
|
||||
SchedXaction *sx = (SchedXaction*)data;
|
||||
GNCBook *book;
|
||||
book = gnc_get_current_book();
|
||||
sxes = gnc_book_get_schedxactions(book);
|
||||
gnc_sxes_del_sx(sxes, sx);
|
||||
xaccSchedXactionFree(sx);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page)
|
||||
{
|
||||
GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
GtkTreeSelection *selection;
|
||||
GList *selected_paths, *to_delete = NULL;
|
||||
GtkTreeModel *model;
|
||||
|
||||
/* @@fixme -- add (suppressible?) confirmation dialog */
|
||||
|
||||
selection = gtk_tree_view_get_selection(priv->tree_view);
|
||||
selected_paths = gtk_tree_selection_get_selected_rows(selection, &model);
|
||||
if (g_list_length(selected_paths) == 0)
|
||||
{
|
||||
PERR("no selection for delete.");
|
||||
return;
|
||||
}
|
||||
|
||||
to_delete = gnc_g_list_map(selected_paths, (GncGMapFunc)_sx_for_path, model);
|
||||
{
|
||||
GList *list;
|
||||
for (list = to_delete; list != NULL; list = list->next)
|
||||
{
|
||||
DEBUG("to-delete [%s]\n", xaccSchedXactionGetName((SchedXaction*)list->data));
|
||||
}
|
||||
}
|
||||
g_list_foreach(to_delete, (GFunc)_destroy_sx, NULL);
|
||||
g_list_free(to_delete);
|
||||
g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
|
||||
g_list_free(selected_paths);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
81
src/gnome/gnc-plugin-page-sx-list.h
Normal file
81
src/gnome/gnc-plugin-page-sx-list.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* gnc-plugin-page-sx-list.h
|
||||
*
|
||||
* Copyright (C) 2006 Josh Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
/** @addtogroup ContentPlugins
|
||||
@{ */
|
||||
/** @addtogroup GncPluginPageSxList An Plugin Page for the SX List.
|
||||
@{ */
|
||||
/** @brief Functions providing a list of scheduled transactions as a plugin page.
|
||||
@author Josh Sled <jsled@asynchronous.org>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* type macros */
|
||||
#define GNC_TYPE_PLUGIN_PAGE_SX_LIST (gnc_plugin_page_sx_list_get_type ())
|
||||
#define GNC_PLUGIN_PAGE_SX_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_PLUGIN_PAGE_SX_LIST, GncPluginPageSxList))
|
||||
#define GNC_PLUGIN_PAGE_SX_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_PLUGIN_PAGE_SX_LIST, GncPluginPageSxListClass))
|
||||
#define GNC_IS_PLUGIN_PAGE_SX_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_PLUGIN_PAGE_SX_LIST))
|
||||
#define GNC_IS_PLUGIN_PAGE_SX_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_PLUGIN_PAGE_SX_LIST))
|
||||
#define GNC_PLUGIN_PAGE_SX_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_PLUGIN_PAGE_SX_LIST, GncPluginPageSxListClass))
|
||||
|
||||
#define GNC_PLUGIN_PAGE_SX_LIST_NAME "GncPluginPageSxList"
|
||||
|
||||
/* typedefs & structures */
|
||||
typedef struct
|
||||
{
|
||||
GncPluginPage gnc_plugin_page;
|
||||
} GncPluginPageSxList;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GncPluginPageClass gnc_plugin_page;
|
||||
} GncPluginPageSxListClass;
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
/**
|
||||
* Retrieve the type number for an "sx list" plugin page.
|
||||
* @return The type number.
|
||||
*/
|
||||
GType gnc_plugin_page_sx_list_get_type(void);
|
||||
|
||||
/**
|
||||
* @return The newly created plugin page.
|
||||
**/
|
||||
GncPluginPage *gnc_plugin_page_sx_list_new(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GNC_PLUGIN_PAGE_SX_LIST_H */
|
||||
/** @} */
|
||||
/** @} */
|
@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1998 Rob Browning <rlb@cs.utexas.edu> *
|
||||
* Copyright (C) 1999-2000 Dave Peticolas <dave@krondo.com> *
|
||||
* Copyright (C) 2001 Gnumatic, Inc. *
|
||||
* Copyright (C) 2002 Joshua Sled <jsled@asynchronous.org> *
|
||||
* Copyright (C) 2002,2006 Joshua Sled <jsled@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 @@ gsr_default_schedule_handler( GNCSplitReg *gsr, gpointer data )
|
||||
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 @@ gsr_default_schedule_handler( GNCSplitReg *gsr, gpointer data )
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
600
src/gnome/gnc-sx-list-tree-model-adapter.c
Normal file
600
src/gnome/gnc-sx-list-tree-model-adapter.c
Normal file
@ -0,0 +1,600 @@
|
||||
/*
|
||||
* gnc-sx-list-tree-model-adapter.c
|
||||
*
|
||||
* Copyright (C) 2006 Josh Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include "gnc-sx-instance-model.h"
|
||||
#include "gnc-sx-list-tree-model-adapter.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
struct _GncSxListTreeModelAdapter
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/* protected */
|
||||
gboolean disposed;
|
||||
GncSxInstanceModel *instances;
|
||||
GtkTreeStore *orig;
|
||||
GtkTreeModelSort *real;
|
||||
};
|
||||
|
||||
struct _GncSxListTreeModelAdapterClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
};
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
static void gnc_sx_list_tree_model_adapter_class_init(GncSxListTreeModelAdapterClass *klass);
|
||||
static void gsltma_tree_model_interface_init(gpointer g_iface, gpointer iface_data);
|
||||
static void gsltma_tree_sortable_interface_init(gpointer g_iface, gpointer iface_data);
|
||||
static void gnc_sx_list_tree_model_adapter_init(GTypeInstance *instance, gpointer klass);
|
||||
static void gnc_sx_list_tree_model_adapter_dispose(GObject *obj);
|
||||
static void gnc_sx_list_tree_model_adapter_finalize(GObject *obj);
|
||||
|
||||
static GncSxInstances* gsltma_get_sx_instances_from_orig_iter(GncSxListTreeModelAdapter *model, GtkTreeIter *orig_iter);
|
||||
|
||||
GType
|
||||
gnc_sx_list_tree_model_adapter_get_type(void)
|
||||
{
|
||||
static GType type = 0;
|
||||
if (type == 0) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (GncSxListTreeModelAdapterClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc)gnc_sx_list_tree_model_adapter_class_init, /* class_init */
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GncSxListTreeModelAdapter),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc)gnc_sx_list_tree_model_adapter_init /* instance_init */
|
||||
};
|
||||
static const GInterfaceInfo itree_model_info = {
|
||||
(GInterfaceInitFunc) gsltma_tree_model_interface_init, /* interface_init */
|
||||
NULL, /* interface_finalize */
|
||||
NULL /* interface_data */
|
||||
};
|
||||
static const GInterfaceInfo itree_sortable_info = {
|
||||
(GInterfaceInitFunc) gsltma_tree_sortable_interface_init, /* interface_init */
|
||||
NULL, /* interface_finalize */
|
||||
NULL /* interface_data */
|
||||
};
|
||||
|
||||
type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"GncSxListTreeModelAdapterType",
|
||||
&info, 0);
|
||||
g_type_add_interface_static(type,
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
&itree_model_info);
|
||||
g_type_add_interface_static(type,
|
||||
GTK_TYPE_TREE_SORTABLE,
|
||||
&itree_sortable_info);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_sx_list_tree_model_adapter_class_init(GncSxListTreeModelAdapterClass *klass)
|
||||
{
|
||||
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent(klass);
|
||||
|
||||
obj_class->dispose = gnc_sx_list_tree_model_adapter_dispose;
|
||||
obj_class->finalize = gnc_sx_list_tree_model_adapter_finalize;
|
||||
|
||||
}
|
||||
|
||||
static GtkTreeModelFlags
|
||||
gsltma_get_flags(GtkTreeModel *tree_model)
|
||||
{
|
||||
return gtk_tree_model_get_flags(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
|
||||
}
|
||||
|
||||
static gint
|
||||
gsltma_get_n_columns(GtkTreeModel *tree_model)
|
||||
{
|
||||
return gtk_tree_model_get_n_columns(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real));
|
||||
}
|
||||
|
||||
static GType
|
||||
gsltma_get_column_type(GtkTreeModel *tree_model, gint index)
|
||||
{
|
||||
return gtk_tree_model_get_column_type(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), index);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsltma_get_iter(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
return gtk_tree_model_get_iter(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, path);
|
||||
}
|
||||
|
||||
static GtkTreePath*
|
||||
gsltma_get_path(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
return gtk_tree_model_get_path(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_get_value(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
gint column,
|
||||
GValue *value)
|
||||
{
|
||||
gtk_tree_model_get_value(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, column, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsltma_iter_next(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
return gtk_tree_model_iter_next(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsltma_iter_children(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *parent)
|
||||
{
|
||||
return gtk_tree_model_iter_children(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsltma_iter_has_child(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
return gtk_tree_model_iter_has_child(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
|
||||
}
|
||||
|
||||
static gint
|
||||
gsltma_iter_n_children(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsltma_iter_nth_child(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *parent,
|
||||
gint n)
|
||||
{
|
||||
return gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, parent, n);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsltma_iter_parent(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *child)
|
||||
{
|
||||
return gtk_tree_model_iter_parent(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter, child);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_ref_node(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gtk_tree_model_ref_node(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_unref_node(GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gtk_tree_model_unref_node(GTK_TREE_MODEL(GNC_SX_LIST_TREE_MODEL_ADAPTER(tree_model)->real), iter);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_tree_model_interface_init(gpointer g_iface, gpointer iface_data)
|
||||
{
|
||||
GtkTreeModelIface *tree_model = (GtkTreeModelIface*)g_iface;
|
||||
tree_model->get_flags = gsltma_get_flags;
|
||||
tree_model->get_n_columns = gsltma_get_n_columns;
|
||||
tree_model->get_column_type = gsltma_get_column_type;
|
||||
tree_model->get_iter = gsltma_get_iter;
|
||||
tree_model->get_path = gsltma_get_path;
|
||||
tree_model->get_value = gsltma_get_value;
|
||||
tree_model->iter_next = gsltma_iter_next;
|
||||
tree_model->iter_children = gsltma_iter_children;
|
||||
tree_model->iter_has_child = gsltma_iter_has_child;
|
||||
tree_model->iter_n_children = gsltma_iter_n_children;
|
||||
tree_model->iter_nth_child = gsltma_iter_nth_child;
|
||||
tree_model->iter_parent = gsltma_iter_parent;
|
||||
tree_model->ref_node = gsltma_ref_node;
|
||||
tree_model->unref_node = gsltma_unref_node;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsltma_get_sort_column_id(GtkTreeSortable *sortable,
|
||||
gint *sort_column_id,
|
||||
GtkSortType *order)
|
||||
{
|
||||
return gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
|
||||
sort_column_id,
|
||||
order);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_set_sort_column_id(GtkTreeSortable *sortable,
|
||||
gint sort_column_id,
|
||||
GtkSortType order)
|
||||
{
|
||||
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
|
||||
sort_column_id,
|
||||
order);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_set_sort_func(GtkTreeSortable *sortable,
|
||||
gint sort_column_id,
|
||||
GtkTreeIterCompareFunc func,
|
||||
gpointer data,
|
||||
GtkDestroyNotify destroy)
|
||||
{
|
||||
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
|
||||
sort_column_id,
|
||||
func,
|
||||
data,
|
||||
destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_set_default_sort_func(GtkTreeSortable *sortable,
|
||||
GtkTreeIterCompareFunc func,
|
||||
gpointer data,
|
||||
GtkDestroyNotify destroy)
|
||||
{
|
||||
gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real),
|
||||
func, data, destroy);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsltma_has_default_sort_func(GtkTreeSortable *sortable)
|
||||
{
|
||||
return gtk_tree_sortable_has_default_sort_func(GTK_TREE_SORTABLE(GNC_SX_LIST_TREE_MODEL_ADAPTER(sortable)->real));
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_tree_sortable_interface_init(gpointer g_iface, gpointer iface_data)
|
||||
{
|
||||
GtkTreeSortableIface *tree_sortable = (GtkTreeSortableIface*)g_iface;
|
||||
tree_sortable->get_sort_column_id = gsltma_get_sort_column_id;
|
||||
tree_sortable->set_sort_column_id = gsltma_set_sort_column_id;
|
||||
tree_sortable->set_sort_func = gsltma_set_sort_func;
|
||||
tree_sortable->set_default_sort_func = gsltma_set_default_sort_func;
|
||||
tree_sortable->has_default_sort_func = gsltma_has_default_sort_func;
|
||||
tree_sortable->get_sort_column_id = gsltma_get_sort_column_id;
|
||||
tree_sortable->set_sort_column_id = gsltma_set_sort_column_id;
|
||||
tree_sortable->set_sort_func = gsltma_set_sort_func;
|
||||
tree_sortable->set_default_sort_func = gsltma_set_default_sort_func;
|
||||
tree_sortable->has_default_sort_func = gsltma_has_default_sort_func;
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_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
|
||||
gsltma_proxy_row_deleted(GtkTreeModel *treemodel,
|
||||
GtkTreePath *arg1,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit_by_name(user_data, "row-deleted", arg1);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_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
|
||||
gsltma_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
|
||||
gsltma_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
|
||||
gsltma_proxy_sort_column_changed(GtkTreeSortable *sortable, gpointer user_data)
|
||||
{
|
||||
g_signal_emit_by_name(user_data, "sort-column-changed");
|
||||
}
|
||||
|
||||
static gint
|
||||
_name_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
|
||||
{
|
||||
gint rtn;
|
||||
GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
|
||||
GncSxInstances *a_inst, *b_inst;
|
||||
gchar *a_caseless, *b_caseless;
|
||||
|
||||
a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
|
||||
b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
|
||||
|
||||
if (a_inst == NULL && b_inst == NULL) return 0;
|
||||
if (a_inst == NULL) return 1;
|
||||
if (b_inst == NULL) return -1;
|
||||
|
||||
a_caseless = g_utf8_casefold(xaccSchedXactionGetName(a_inst->sx), -1);
|
||||
b_caseless = g_utf8_casefold(xaccSchedXactionGetName(b_inst->sx), -1);
|
||||
rtn = safe_strcmp(a_caseless, b_caseless);
|
||||
g_free(a_caseless);
|
||||
g_free(b_caseless);
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static gint
|
||||
_freq_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
|
||||
{
|
||||
GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
|
||||
GncSxInstances *a_inst, *b_inst;
|
||||
|
||||
a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
|
||||
b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
|
||||
|
||||
if (a_inst == NULL && b_inst == NULL) return 0;
|
||||
if (a_inst == NULL) return 1;
|
||||
if (b_inst == NULL) return -1;
|
||||
|
||||
return gnc_freq_spec_compare(xaccSchedXactionGetFreqSpec(a_inst->sx),
|
||||
xaccSchedXactionGetFreqSpec(b_inst->sx));
|
||||
}
|
||||
|
||||
static gint
|
||||
_safe_invalidable_date_compare(GDate *a, GDate *b)
|
||||
{
|
||||
if (!g_date_valid(a) && !g_date_valid(b))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!g_date_valid(a))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (!g_date_valid(b))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return g_date_compare(a, b);
|
||||
}
|
||||
|
||||
static gint
|
||||
_last_occur_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
|
||||
{
|
||||
GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
|
||||
GncSxInstances *a_inst, *b_inst;
|
||||
|
||||
a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
|
||||
b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
|
||||
|
||||
return _safe_invalidable_date_compare(xaccSchedXactionGetLastOccurDate(a_inst->sx),
|
||||
xaccSchedXactionGetLastOccurDate(b_inst->sx));
|
||||
}
|
||||
|
||||
static gint
|
||||
_next_occur_comparator(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
|
||||
{
|
||||
GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
|
||||
GncSxInstances *a_inst, *b_inst;
|
||||
|
||||
a_inst = gsltma_get_sx_instances_from_orig_iter(adapter, a);
|
||||
b_inst = gsltma_get_sx_instances_from_orig_iter(adapter, b);
|
||||
|
||||
return _safe_invalidable_date_compare(&a_inst->next_instance_date,
|
||||
&b_inst->next_instance_date);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_sx_list_tree_model_adapter_init(GTypeInstance *instance, gpointer klass)
|
||||
{
|
||||
GncSxListTreeModelAdapter *adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(instance);
|
||||
adapter->orig = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
|
||||
adapter->real = GTK_TREE_MODEL_SORT(gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(adapter->orig)));
|
||||
|
||||
// setup sorting
|
||||
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NAME, _name_comparator, adapter, NULL);
|
||||
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_FREQUENCY, _freq_comparator, adapter, NULL);
|
||||
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_LAST_OCCUR, _last_occur_comparator, adapter, NULL);
|
||||
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NEXT_OCCUR, _next_occur_comparator, adapter, NULL);
|
||||
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(adapter->real), SXLTMA_COL_NEXT_OCCUR, GTK_SORT_ASCENDING);
|
||||
|
||||
g_signal_connect(adapter->real, "row-changed", G_CALLBACK(gsltma_proxy_row_changed), adapter);
|
||||
g_signal_connect(adapter->real, "row-deleted", G_CALLBACK(gsltma_proxy_row_deleted), adapter);
|
||||
g_signal_connect(adapter->real, "row-has-child-toggled", G_CALLBACK(gsltma_proxy_row_has_child_toggled), adapter);
|
||||
g_signal_connect(adapter->real, "row-inserted", G_CALLBACK(gsltma_proxy_row_inserted), adapter);
|
||||
g_signal_connect(adapter->real, "rows-reordered", G_CALLBACK(gsltma_proxy_rows_reordered), adapter);
|
||||
|
||||
g_signal_connect(adapter->real, "sort-column-changed", G_CALLBACK(gsltma_proxy_sort_column_changed), adapter);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_populate_tree_store(GncSxListTreeModelAdapter *model)
|
||||
{
|
||||
GtkTreeIter 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->orig, &iter, NULL);
|
||||
gtk_tree_store_set(model->orig, &iter,
|
||||
SXLTMA_COL_NAME, xaccSchedXactionGetName(instances->sx),
|
||||
SXLTMA_COL_FREQUENCY, frequency_str->str,
|
||||
SXLTMA_COL_LAST_OCCUR, last_occur_date_buf,
|
||||
SXLTMA_COL_NEXT_OCCUR, next_occur_date_buf,
|
||||
-1);
|
||||
g_string_free(frequency_str, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_added_cb(GncSxInstanceModel *instances, SchedXaction *sx_added, gpointer user_data)
|
||||
{
|
||||
GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
|
||||
gtk_tree_store_clear(model->orig);
|
||||
gsltma_populate_tree_store(model);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_updated_cb(GncSxInstanceModel *instances, SchedXaction *sx_updated, gpointer user_data)
|
||||
{
|
||||
GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
|
||||
gnc_sx_instance_model_update_sx_instances(instances, sx_updated);
|
||||
gtk_tree_store_clear(model->orig);
|
||||
gsltma_populate_tree_store(model);
|
||||
}
|
||||
|
||||
static void
|
||||
gsltma_removing_cb(GncSxInstanceModel *instances, SchedXaction *sx_removing, gpointer user_data)
|
||||
{
|
||||
GncSxListTreeModelAdapter *model = GNC_SX_LIST_TREE_MODEL_ADAPTER(user_data);
|
||||
gnc_sx_instance_model_remove_sx_instances(instances, sx_removing);
|
||||
gtk_tree_store_clear(model->orig);
|
||||
gsltma_populate_tree_store(model);
|
||||
}
|
||||
|
||||
GncSxListTreeModelAdapter*
|
||||
gnc_sx_list_tree_model_adapter_new(GncSxInstanceModel *instances)
|
||||
{
|
||||
GncSxListTreeModelAdapter *rtn;
|
||||
|
||||
rtn = GNC_SX_LIST_TREE_MODEL_ADAPTER(g_object_new(GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, NULL));
|
||||
rtn->instances = instances;
|
||||
g_object_ref(G_OBJECT(rtn->instances));
|
||||
|
||||
gsltma_populate_tree_store(rtn);
|
||||
|
||||
g_signal_connect(G_OBJECT(rtn->instances), "added", (GCallback)gsltma_added_cb, (gpointer)rtn);
|
||||
g_signal_connect(G_OBJECT(rtn->instances), "updated", (GCallback)gsltma_updated_cb, (gpointer)rtn);
|
||||
g_signal_connect(G_OBJECT(rtn->instances), "removing", (GCallback)gsltma_removing_cb, (gpointer)rtn);
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
GncSxInstances*
|
||||
gsltma_get_sx_instances_from_orig_iter(GncSxListTreeModelAdapter *model, GtkTreeIter *orig_iter)
|
||||
{
|
||||
GtkTreePath *path;
|
||||
gint *indices;
|
||||
gint index;
|
||||
|
||||
path = gtk_tree_model_get_path(GTK_TREE_MODEL(model->orig), orig_iter);
|
||||
if (gtk_tree_path_get_depth(path) > 1)
|
||||
{
|
||||
gtk_tree_path_free(path);
|
||||
return NULL;
|
||||
}
|
||||
indices = gtk_tree_path_get_indices(path);
|
||||
index = indices[0];
|
||||
|
||||
gtk_tree_path_free(path);
|
||||
return (GncSxInstances*)g_list_nth_data(model->instances->sx_instance_list, index);
|
||||
}
|
||||
|
||||
GncSxInstances*
|
||||
gnc_sx_list_tree_model_adapter_get_sx_instances(GncSxListTreeModelAdapter *model, GtkTreeIter *sort_iter)
|
||||
{
|
||||
GtkTreeIter translated_iter;
|
||||
gtk_tree_model_sort_convert_iter_to_child_iter(model->real,
|
||||
&translated_iter,
|
||||
sort_iter);
|
||||
return gsltma_get_sx_instances_from_orig_iter(model, &translated_iter);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_sx_list_tree_model_adapter_dispose(GObject *obj)
|
||||
{
|
||||
GncSxListTreeModelAdapter *adapter;
|
||||
|
||||
g_return_if_fail(obj != NULL);
|
||||
adapter = GNC_SX_LIST_TREE_MODEL_ADAPTER(obj);
|
||||
g_return_if_fail(adapter->disposed);
|
||||
adapter->disposed = TRUE;
|
||||
|
||||
g_object_unref(G_OBJECT(adapter->instances));
|
||||
adapter->instances = NULL;
|
||||
g_object_unref(G_OBJECT(adapter->real));
|
||||
adapter->real = NULL;
|
||||
g_object_unref(G_OBJECT(adapter->orig));
|
||||
adapter->orig = NULL;
|
||||
|
||||
G_OBJECT_CLASS(parent_class)->dispose(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_sx_list_tree_model_adapter_finalize(GObject *obj)
|
||||
{
|
||||
g_return_if_fail(obj != NULL);
|
||||
G_OBJECT_CLASS(parent_class)->finalize(obj);
|
||||
}
|
59
src/gnome/gnc-sx-list-tree-model-adapter.h
Normal file
59
src/gnome/gnc-sx-list-tree-model-adapter.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* gnc-sx-list-tree-model-adapter.h
|
||||
*
|
||||
* Copyright (C) 2006 Josh Sled <jsled@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@gnu.org
|
||||
*/
|
||||
|
||||
#ifndef _GNC_SX_LIST_TREE_MODEL_ADAPTER_H
|
||||
#define _GNC_SX_LIST_TREE_MODEL_ADAPTER_H
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "gnc-sx-instance-model.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER (gnc_sx_list_tree_model_adapter_get_type ())
|
||||
#define GNC_SX_LIST_TREE_MODEL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, GncSxListTreeModelAdapter))
|
||||
#define GNC_SX_LIST_TREE_MODEL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, GncSxListTreeModelAdapterClass))
|
||||
#define GNC_IS_SX_LIST_TREE_MODEL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER))
|
||||
#define GNC_IS_SX_LIST_TREE_MODEL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER))
|
||||
#define GNC_SX_LIST_TREE_MODEL_ADAPTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_SX_LIST_TREE_MODEL_ADAPTER, GncSxListTreeModelAdapterClass))
|
||||
|
||||
typedef struct _GncSxListTreeModelAdapter GncSxListTreeModelAdapter;
|
||||
typedef struct _GncSxListTreeModelAdapterClass GncSxListTreeModelAdapterClass;
|
||||
|
||||
// model columns
|
||||
enum {
|
||||
SXLTMA_COL_NAME = 0,
|
||||
SXLTMA_COL_FREQUENCY,
|
||||
SXLTMA_COL_LAST_OCCUR,
|
||||
SXLTMA_COL_NEXT_OCCUR
|
||||
};
|
||||
|
||||
GType gnc_sx_list_tree_model_adapter_get_type(void);
|
||||
GncSxListTreeModelAdapter* gnc_sx_list_tree_model_adapter_new(GncSxInstanceModel *instances);
|
||||
|
||||
GncSxInstances* gnc_sx_list_tree_model_adapter_get_sx_instances(GncSxListTreeModelAdapter *model, GtkTreeIter *iter);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // _GNC_SX_LIST_TREE_MODEL_ADAPTER_H
|
@ -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"
|
||||
|
@ -8,6 +8,7 @@ ui_DATA = \
|
||||
gnc-plugin-file-history-ui.xml \
|
||||
gnc-plugin-register-ui.xml \
|
||||
gnc-plugin-page-register-ui.xml \
|
||||
gnc-plugin-page-sx-list-ui.xml \
|
||||
gnc-plugin-page-sxregister-ui.xml \
|
||||
gnc-sxed-to-create-window-ui.xml \
|
||||
gnc-reconcile-window-ui.xml \
|
||||
|
20
src/gnome/ui/gnc-plugin-page-sx-list-ui.xml
Normal file
20
src/gnome/ui/gnc-plugin-page-sx-list-ui.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<ui>
|
||||
<menubar>
|
||||
<placeholder name="AdditionalMenusPlaceholder">
|
||||
<menu action="SxListAction">
|
||||
<menuitem name="SxListNew" action="SxListNewAction"/>
|
||||
<menuitem name="SxListEdit" action="SxListEditAction"/>
|
||||
<menuitem name="SxListDelete" action="SxListDeleteAction"/>
|
||||
</menu>
|
||||
</placeholder>
|
||||
</menubar>
|
||||
|
||||
<toolbar name="DefaultToolbar">
|
||||
<placeholder name="DefaultToolbarPlaceholder">
|
||||
<separator name="ToolbarSep2" />
|
||||
<toolitem name="SxListToolbarNew" action="SxListNewAction"/>
|
||||
<toolitem name="SxListToolbarEdit" action="SxListEditAction"/>
|
||||
<toolitem name="SxListToolbarDelete" action="SxListDeleteAction"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
</ui>
|
Loading…
Reference in New Issue
Block a user