mirror of
https://github.com/Gnucash/gnucash.git
synced 2026-09-03 20:53:02 -05:00
2002-10-06 Joshua Sled <jsled@asynchronous.org>
* src/gnome/druid-loan.c: The druid now enforces valid account selection for the GNCAccountSel widgets; fixes Bug#90784. * src/gnome/gnc-account-sel.c (gas_destroy): GNCAccountSel now cleans up after itself, especially with removing its engine event observation. Moved from src/gnome-utils/ to src/gnome/ because of circular dep introduced below. * src/dialog-account/dialog-account.c (gnc_ui_new_account_with_types): Added new function to create a NewAccount dialog with only a valid-types filtering list. * src/gnome-utils/gnc-account-sel.c (gnc_account_sel_set_acct_filters): Added support for filtering the accounts available through the GNCAccountSel. (gnc_account_sel_set_new_account_ability): Added support for a conditional "New..." button which allows the creation a new account. If the selector has a filter in place, the filter will apply to the new-account creation as well. * src/gnome-utils/gnc-account-sel.c: Added ifdefs, comments around regions pertaining to unimplemented feature of completion. Fix for Bug#90779. (gnc_account_sel_event_cb): Added support for updating list contents when the account tree changes; the current selection is respected if the account still exists; fixes Bug#94951. * src/gnome/dialog-sxsincelast.c (sxsld_process_to_create_instance): Handle the corner case of not incrementing the state while postponing/ignoring a never-been-created SX. Handle only incrementing the counters of newly-come-due SXes. * src/engine/SchedXaction.c (gnc_sx_create_temporal_state): Fix corner case of creating the temporal state of a never-been-created SX; fixes Bug#94947. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7283 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -1,3 +1,42 @@
|
||||
2002-10-06 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/gnome/druid-loan.c: The druid now enforces valid account
|
||||
selection for the GNCAccountSel widgets; fixes Bug#90784.
|
||||
|
||||
* src/gnome/gnc-account-sel.c (gas_destroy): GNCAccountSel
|
||||
now cleans up after itself, especially with removing its engine
|
||||
event observation. Moved from src/gnome-utils/ to src/gnome/
|
||||
because of circular dep introduced below.
|
||||
|
||||
* src/dialog-account/dialog-account.c
|
||||
(gnc_ui_new_account_with_types): Added new function to create a
|
||||
NewAccount dialog with only a valid-types filtering list.
|
||||
|
||||
* src/gnome-utils/gnc-account-sel.c
|
||||
(gnc_account_sel_set_acct_filters): Added support for filtering
|
||||
the accounts available through the GNCAccountSel.
|
||||
(gnc_account_sel_set_new_account_ability): Added support for a
|
||||
conditional "New..." button which allows the creation a new
|
||||
account. If the selector has a filter in place, the filter will
|
||||
apply to the new-account creation as well.
|
||||
|
||||
* src/gnome-utils/gnc-account-sel.c: Added ifdefs, comments around
|
||||
regions pertaining to unimplemented feature of completion.
|
||||
Fix for Bug#90779.
|
||||
(gnc_account_sel_event_cb): Added support for updating list
|
||||
contents when the account tree changes; the current selection is
|
||||
respected if the account still exists; fixes Bug#94951.
|
||||
|
||||
* src/gnome/dialog-sxsincelast.c
|
||||
(sxsld_process_to_create_instance): Handle the corner case of not
|
||||
incrementing the state while postponing/ignoring a
|
||||
never-been-created SX. Handle only incrementing the counters of
|
||||
newly-come-due SXes.
|
||||
|
||||
* src/engine/SchedXaction.c (gnc_sx_create_temporal_state): Fix
|
||||
corner case of creating the temporal state of a never-been-created
|
||||
SX; fixes Bug#94947.
|
||||
|
||||
2002-10-06 Christian Stimming <stimming@tuhh.de>
|
||||
|
||||
* src/import-export/hbci/gnc-hbci-gettrans.c, gnc-hbci-actions.c:
|
||||
|
||||
@@ -40,6 +40,15 @@ AccountWindow * gnc_ui_new_account_window_with_default(AccountGroup *group,
|
||||
Account * parent);
|
||||
AccountWindow * gnc_ui_edit_account_window (Account *account);
|
||||
|
||||
/**
|
||||
* @param unused The AccountGroup to create in; this isn't used.
|
||||
* @param valid_types A GList of GNCAccountType gints [as pointers] which are
|
||||
* allowed to be created. Unlike below, this function makes a copy of the
|
||||
* valid_types list.
|
||||
**/
|
||||
AccountWindow * gnc_ui_new_account_with_types( AccountGroup *unused,
|
||||
GList *valid_types );
|
||||
|
||||
Account * gnc_ui_new_accounts_from_name_window (const char *name);
|
||||
|
||||
/* Note that the caller owns the valid_types list */
|
||||
|
||||
@@ -363,6 +363,7 @@ test_files_in_dir(int argc, char **argv, gxpf_callback cb,
|
||||
{
|
||||
if(!S_ISDIR(file_info.st_mode))
|
||||
{
|
||||
printf( "testing load of file \"%s\":\n", argv[count] );
|
||||
test_load_file(to_open, cb, parser, parser_tag, book);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ for i in $SRCDIR/test-files/xml2/*.gml2 ; do
|
||||
FILES=`perl $SRCDIR/grab-types.pl "gnc:$j" $i "$j/dataXXX.xml"`
|
||||
if [ ! -z "$FILES" ] ; then
|
||||
echo "Testing file `basename $i`, section $j"
|
||||
|
||||
echo "[./test-xml-$j $FILES # from file $i]:"
|
||||
eval "./test-xml-$j $FILES"
|
||||
if [ $? != 0 ] ; then
|
||||
EXIT_VALUE=1
|
||||
|
||||
@@ -139,6 +139,11 @@ equals_node_val_vs_split_internal(xmlNodePtr node, Split* spl)
|
||||
gnc_numeric *num = dom_tree_to_gnc_numeric(mark);
|
||||
gnc_numeric val = xaccSplitGetAmount(spl);
|
||||
|
||||
if ( gnc_numeric_equal(*num, val)) {
|
||||
return g_strdup_printf( "quantities differ under _equal: %lld/%lld v %lld/%lld",
|
||||
(*num).num, (*num).denom,
|
||||
val.num, val.denom );
|
||||
}
|
||||
if(!gnc_numeric_eq(*num, val))
|
||||
{
|
||||
g_free(num);
|
||||
|
||||
@@ -147,6 +147,7 @@ delete_template_trans(SchedXaction *sx)
|
||||
void
|
||||
xaccSchedXactionFree( SchedXaction *sx )
|
||||
{
|
||||
GList *l;
|
||||
|
||||
if ( sx == NULL ) return;
|
||||
|
||||
@@ -171,10 +172,19 @@ xaccSchedXactionFree( SchedXaction *sx )
|
||||
|
||||
xaccAccountBeginEdit(sx->template_acct);
|
||||
xaccAccountDestroy(sx->template_acct);
|
||||
|
||||
for ( l = sx->deferredList; l; l = l->next ) {
|
||||
gnc_sx_destroy_temporal_state( l->data );
|
||||
l->data = NULL;
|
||||
}
|
||||
if ( sx->deferredList ) {
|
||||
g_list_free( sx->deferredList );
|
||||
sx->deferredList = NULL;
|
||||
}
|
||||
|
||||
g_free( sx );
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -489,12 +499,16 @@ xaccSchedXactionGetInstanceAfter( SchedXaction *sx,
|
||||
{
|
||||
GDate prev_occur, next_occur;
|
||||
|
||||
prev_occur = *date;
|
||||
g_date_clear( &prev_occur, 1 );
|
||||
if ( date ) {
|
||||
prev_occur = *date;
|
||||
}
|
||||
|
||||
if ( stateData != NULL ) {
|
||||
temporalStateData *tsd = (temporalStateData*)stateData;
|
||||
prev_occur = tsd->last_date;
|
||||
}
|
||||
|
||||
if ( ! g_date_valid( &prev_occur ) ) {
|
||||
/* We must be at the beginning. */
|
||||
prev_occur = sx->start_date;
|
||||
@@ -679,6 +693,10 @@ gnc_sx_create_temporal_state( SchedXaction *sx )
|
||||
temporalStateData *toRet =
|
||||
g_new0( temporalStateData, 1 );
|
||||
toRet->last_date = sx->last_date;
|
||||
if ( !g_date_valid( &toRet->last_date ) ) {
|
||||
toRet->last_date = sx->start_date;
|
||||
g_date_subtract_days( &toRet->last_date, 1 );
|
||||
}
|
||||
toRet->num_occur_rem = sx->num_occurances_remain;
|
||||
toRet->num_inst = sx->instance_num;
|
||||
return (void*)toRet;
|
||||
@@ -690,6 +708,7 @@ gnc_sx_incr_temporal_state( SchedXaction *sx, void *stateData )
|
||||
GDate unused;
|
||||
temporalStateData *tsd = (temporalStateData*)stateData;
|
||||
|
||||
g_date_clear( &unused, 1 );
|
||||
tsd->last_date =
|
||||
xaccSchedXactionGetInstanceAfter( sx,
|
||||
&unused,
|
||||
|
||||
@@ -25,7 +25,6 @@ libgncmod_gnome_utils_la_SOURCES = \
|
||||
dialog-options.c \
|
||||
dialog-utils.c \
|
||||
druid-utils.c \
|
||||
gnc-account-sel.c \
|
||||
gnc-account-tree.c \
|
||||
gnc-amount-edit.c \
|
||||
gnc-commodity-edit.c \
|
||||
@@ -53,7 +52,6 @@ gncinclude_HEADERS = \
|
||||
dialog-options.h \
|
||||
dialog-utils.h \
|
||||
druid-utils.h \
|
||||
gnc-account-sel.h \
|
||||
gnc-account-tree.h \
|
||||
gnc-amount-edit.h \
|
||||
gnc-commodity-edit.h \
|
||||
|
||||
@@ -1,301 +0,0 @@
|
||||
/**
|
||||
* gnc-account-sel.c -- combobox style account selection widget, with
|
||||
* auto-completion.
|
||||
*
|
||||
* Copyright (C) 2002 Joshua Sled <jsled@asynchronous.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Gnucash is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Gnucash 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
|
||||
* Library 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
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
**/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gnc-account-sel.h"
|
||||
#include "gnc-exp-parser.h"
|
||||
#include "messages.h"
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
#define ACCT_DATA_TAG "gnc-account-sel_acct"
|
||||
|
||||
/* Signal codes */
|
||||
enum
|
||||
{
|
||||
ACCOUNT_SEL_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static gint account_sel_signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void gnc_account_sel_init (GNCAccountSel *gas);
|
||||
static void gnc_account_sel_class_init (GNCAccountSelClass *class);
|
||||
static void gas_accounts_to_names( gpointer data, gpointer user_data );
|
||||
|
||||
#if 0
|
||||
static void gnc_account_sel_changed( GtkEditable *entry, gpointer ud );
|
||||
static void gnc_account_sel_list_clicked( GtkButton *b, gpointer ud );
|
||||
static gint gnc_account_sel_key_press( GtkWidget *widget,
|
||||
GdkEventKey *event );
|
||||
#endif /* 0 */
|
||||
|
||||
static GtkHBox *parent_class;
|
||||
|
||||
guint
|
||||
gnc_account_sel_get_type (void)
|
||||
{
|
||||
static guint account_sel_type = 0;
|
||||
|
||||
if (!account_sel_type){
|
||||
GtkTypeInfo account_sel_info = {
|
||||
"GNCAccountSel",
|
||||
sizeof (GNCAccountSel),
|
||||
sizeof (GNCAccountSelClass),
|
||||
(GtkClassInitFunc) gnc_account_sel_class_init,
|
||||
(GtkObjectInitFunc) gnc_account_sel_init,
|
||||
NULL,
|
||||
NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
account_sel_type = gtk_type_unique (GTK_TYPE_HBOX, &account_sel_info);
|
||||
}
|
||||
|
||||
return account_sel_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_account_sel_class_init (GNCAccountSelClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
GtkWidgetClass *widget_class;
|
||||
GtkHBoxClass *hbox_class;
|
||||
|
||||
object_class = (GtkObjectClass*) class;
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
hbox_class = (GtkHBoxClass*) class;
|
||||
|
||||
parent_class = gtk_type_class (gtk_entry_get_type ());
|
||||
|
||||
account_sel_signals [ACCOUNT_SEL_CHANGED] =
|
||||
gtk_signal_new ("account_sel_changed",
|
||||
GTK_RUN_FIRST, object_class->type,
|
||||
GTK_SIGNAL_OFFSET (GNCAccountSelClass,
|
||||
account_sel_changed),
|
||||
gtk_signal_default_marshaller,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
gtk_object_class_add_signals (object_class,
|
||||
account_sel_signals,
|
||||
LAST_SIGNAL);
|
||||
|
||||
class->account_sel_changed = NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GList **outList;
|
||||
char accountSep;
|
||||
} accounts_to_names_data;
|
||||
|
||||
static void
|
||||
gnc_account_sel_init (GNCAccountSel *gas)
|
||||
{
|
||||
gas->initDone = FALSE;
|
||||
gas->combo = GTK_COMBO(gtk_combo_new());
|
||||
gtk_container_add( GTK_CONTAINER(gas), GTK_WIDGET(gas->combo) );
|
||||
|
||||
gtk_editable_set_editable( GTK_EDITABLE(gas->combo->entry), FALSE );
|
||||
#if 0
|
||||
gtk_signal_connect( GTK_OBJECT(gas->combo->entry), "changed",
|
||||
GTK_SIGNAL_FUNC( gnc_account_sel_changed ),
|
||||
gas );
|
||||
#endif /* 0 */
|
||||
|
||||
/* Get the accounts, place into combo list and setup GCompletion */
|
||||
{
|
||||
accounts_to_names_data atnd;
|
||||
AccountGroup *ag;
|
||||
GList *accts, *nameList;
|
||||
|
||||
ag = gnc_book_get_group( gnc_get_current_book() );
|
||||
accts = (GList*)xaccGroupGetSubAccounts( ag );
|
||||
nameList = NULL;
|
||||
atnd.outList = &nameList;
|
||||
atnd.accountSep = gnc_get_account_separator();
|
||||
g_list_foreach( accts, gas_accounts_to_names,
|
||||
(gpointer)&atnd );
|
||||
g_list_free( accts );
|
||||
|
||||
gtk_combo_set_popdown_strings( gas->combo, nameList );
|
||||
|
||||
gas->completion = g_completion_new( NULL );
|
||||
g_completion_add_items( gas->completion, nameList );
|
||||
}
|
||||
gas->initDone = TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gas_accounts_to_names( gpointer data, gpointer user_data )
|
||||
{
|
||||
accounts_to_names_data *atnd;
|
||||
Account *a;
|
||||
|
||||
atnd = (accounts_to_names_data*)user_data;
|
||||
a = (Account*)data;
|
||||
*atnd->outList =
|
||||
g_list_append( *atnd->outList,
|
||||
xaccAccountGetFullName(a, atnd->accountSep) );
|
||||
}
|
||||
|
||||
#if 0 /* fscking gtk... */
|
||||
/*
|
||||
* There is apparently no way -- in GTK 1.x -- to programatically select a
|
||||
* region in the way we would like... so we've disallowed manual editing of
|
||||
* the Account string.
|
||||
*/
|
||||
static
|
||||
void
|
||||
gnc_account_sel_changed( GtkEditable *entry, gpointer ud )
|
||||
{
|
||||
gchar *s, *prefix;
|
||||
GNCAccountSel *gas = (GNCAccountSel*)ud;
|
||||
|
||||
if ( !gas->initDone ) {
|
||||
return;
|
||||
}
|
||||
s = gtk_editable_get_chars( entry, 0, -1 );
|
||||
g_completion_complete( gas->completion, s, &prefix );
|
||||
if ( prefix && (strlen(prefix) > 0) ) {
|
||||
printf( "changed into \"%s\"; longest completion: \"%s\"\n", s, prefix );
|
||||
gtk_signal_handler_block_by_func( GTK_OBJECT(gas->combo->entry),
|
||||
GTK_SIGNAL_FUNC(gnc_account_sel_changed),
|
||||
ud );
|
||||
gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), prefix );
|
||||
gtk_editable_select_region( GTK_EDITABLE(gas->combo->entry),
|
||||
strlen(s), -1 );
|
||||
{
|
||||
GdkEventKey k;
|
||||
gboolean ret;
|
||||
|
||||
k.type = GDK_KEY_RELEASE;
|
||||
k.send_event = TRUE;
|
||||
k.state = GDK_SHIFT_MASK;
|
||||
k.keyval = GDK_End;
|
||||
k.length = 0;
|
||||
k.string = "";
|
||||
printf( "foo [%d : \"%s\"]\n", k.length, k.string );
|
||||
//gtk_widget_event( GTK_WIDGET(gas->combo->entry), &e );
|
||||
gtk_signal_emit_by_name( GTK_OBJECT(gas->combo->entry),
|
||||
"key-press-event",
|
||||
gas->combo->entry, &k, NULL, &ret );
|
||||
printf( "bar\n" );
|
||||
}
|
||||
gtk_editable_set_position( GTK_EDITABLE(gas->combo->entry),
|
||||
strlen(s) );
|
||||
gtk_signal_handler_unblock_by_func( GTK_OBJECT(gas->combo->entry),
|
||||
GTK_SIGNAL_FUNC(gnc_account_sel_changed),
|
||||
ud );
|
||||
g_free( prefix );
|
||||
}
|
||||
g_free( s );
|
||||
}
|
||||
|
||||
static
|
||||
gint
|
||||
gnc_account_sel_key_press(GtkWidget *widget, GdkEventKey *event)
|
||||
{
|
||||
GNCAccountSel *gas = GNC_ACCOUNT_SEL(widget);
|
||||
gint result;
|
||||
|
||||
result = (* GTK_WIDGET_CLASS (parent_class)->key_press_event)(widget, event);
|
||||
|
||||
switch (event->keyval)
|
||||
{
|
||||
case GDK_Tab:
|
||||
/* FIXME: += equivalent. */
|
||||
break;
|
||||
#if 0
|
||||
case GDK_DOWN:
|
||||
/* dispaly combobox */
|
||||
break;
|
||||
#endif /* 0 */
|
||||
case GDK_Return:
|
||||
#if 0
|
||||
if (gae->evaluate_on_enter)
|
||||
break;
|
||||
#endif /* 0 */
|
||||
if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK))
|
||||
break;
|
||||
return result;
|
||||
case GDK_KP_Enter:
|
||||
break;
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
GtkWidget *
|
||||
gnc_account_sel_new (void)
|
||||
{
|
||||
GNCAccountSel *gas;
|
||||
|
||||
gas = gtk_type_new (gnc_account_sel_get_type ());
|
||||
|
||||
return GTK_WIDGET (gas);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gnc_account_sel_gtk_entry (GNCAccountSel *gas)
|
||||
{
|
||||
g_return_val_if_fail(gas != NULL, NULL);
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT_SEL(gas), NULL);
|
||||
|
||||
return (GtkWidget *)gas->combo->entry;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_sel_set_account( GNCAccountSel *gas, Account *acct )
|
||||
{
|
||||
gchar *acctStr;
|
||||
|
||||
if ( acct == NULL ) {
|
||||
gtk_list_select_item( GTK_LIST(gas->combo->list), 0 );
|
||||
return;
|
||||
}
|
||||
acctStr = xaccAccountGetFullName( acct,
|
||||
gnc_get_account_separator() );
|
||||
gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), acctStr );
|
||||
g_free( acctStr );
|
||||
}
|
||||
|
||||
Account*
|
||||
gnc_account_sel_get_account( GNCAccountSel *gas )
|
||||
{
|
||||
AccountGroup *ag;
|
||||
Account *ret;
|
||||
gchar *txt;
|
||||
|
||||
txt = gtk_editable_get_chars( GTK_EDITABLE(gas->combo->entry), 0, -1 );
|
||||
ag = gnc_book_get_group( gnc_get_current_book() );
|
||||
ret = xaccGetAccountFromFullName( ag, txt, gnc_get_account_separator() );
|
||||
g_free( txt );
|
||||
return ret;
|
||||
}
|
||||
@@ -43,6 +43,7 @@ libgncgnome_la_SOURCES = \
|
||||
druid-hierarchy.c \
|
||||
druid-loan.c \
|
||||
druid-stock-split.c \
|
||||
gnc-account-sel.c \
|
||||
gnc-network.c \
|
||||
gnc-splash.c \
|
||||
mainwindow-account-tree.c \
|
||||
@@ -79,6 +80,7 @@ noinst_HEADERS = \
|
||||
dialog-scheduledxaction.h \
|
||||
druid-hierarchy.h \
|
||||
druid-loan.h \
|
||||
gnc-account-sel.h \
|
||||
gnc-network.h \
|
||||
gnc-splash.h \
|
||||
gw-gnc.h \
|
||||
|
||||
@@ -1092,6 +1092,13 @@ sxsld_process_to_create_instance( sxSinceLastData *sxsld,
|
||||
break;
|
||||
}
|
||||
/* add to the postponed list. */
|
||||
{
|
||||
char tmpBuf[50];
|
||||
g_date_strftime( tmpBuf, 49, "%c", tci->date );
|
||||
DEBUG( "Adding defer instance on %s for %s",
|
||||
tmpBuf,
|
||||
xaccSchedXactionGetName( tci->parentTCT->sx ) );
|
||||
}
|
||||
gnc_sx_add_defer_instance( tci->parentTCT->sx, tci->sxStateData );
|
||||
break;
|
||||
case TO_CREATE:
|
||||
@@ -1128,11 +1135,18 @@ sxsld_process_to_create_instance( sxSinceLastData *sxsld,
|
||||
return;
|
||||
}
|
||||
xaccSchedXactionSetLastOccurDate( sx, tci->date );
|
||||
tmp = gnc_sx_get_instance_count( sx, NULL );
|
||||
gnc_sx_set_instance_count( sx, tmp+1 );
|
||||
if ( xaccSchedXactionHasOccurDef( sx ) ) {
|
||||
tmp = xaccSchedXactionGetRemOccur(sx);
|
||||
xaccSchedXactionSetRemOccur( sx, tmp-1 );
|
||||
|
||||
/* Handle an interesting corner case of postponing or
|
||||
* ignoring the first instance. We only want to incrment the
|
||||
* counters for newly-discovered-as-to-be-created SXes.
|
||||
*/
|
||||
if ( tci->origState == UNDEF ) {
|
||||
tmp = gnc_sx_get_instance_count( sx, NULL );
|
||||
gnc_sx_set_instance_count( sx, tmp+1 );
|
||||
if ( xaccSchedXactionHasOccurDef( sx ) ) {
|
||||
tmp = xaccSchedXactionGetRemOccur(sx);
|
||||
xaccSchedXactionSetRemOccur( sx, tmp-1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1288,6 +1302,8 @@ cancel_check( GnomeDruidPage *druid_page,
|
||||
"Are you sure you want to lose all "
|
||||
"Scheduled Transaction changes?" );
|
||||
|
||||
/* FIXME: This may now be a bug, as we might have changed the SX
|
||||
* states. */
|
||||
if ( g_list_length( sxsld->createdTxnGUIDList ) == 0 ) {
|
||||
/* There's nothing to cancel, so just do so... */
|
||||
return FALSE;
|
||||
@@ -1347,7 +1363,7 @@ cancel_check( GnomeDruidPage *druid_page,
|
||||
tciList = tciList->next ) {
|
||||
tci = (toCreateInstance*)tciList->data;
|
||||
if ( tci->prevState == POSTPONE
|
||||
&& tci->origState != POSTPONE ) {
|
||||
&& tci->origState != POSTPONE ) {
|
||||
/* Any valid [non-null] 'prevState !=
|
||||
* POSTPONE' sx temporal state
|
||||
* pointers will be destroyed at the
|
||||
@@ -1540,6 +1556,8 @@ generate_instances( SchedXaction *sx,
|
||||
g_assert( g_date_valid(end) );
|
||||
g_assert( g_date_valid(reminderEnd) );
|
||||
|
||||
g_date_clear( &gd, 1 );
|
||||
|
||||
/* Process valid next instances. */
|
||||
seqStateData = gnc_sx_create_temporal_state( sx );
|
||||
//gd = xaccSchedXactionGetNextInstance( sx, seqStateData );
|
||||
@@ -1961,7 +1979,6 @@ sxsincelast_populate( sxSinceLastData *sxsld )
|
||||
|
||||
GList *sxList, *instanceList, *l, **containingList;
|
||||
SchedXaction *sx;
|
||||
void *sx_state;
|
||||
GDate end, endPlusReminders;
|
||||
gint daysInAdvance;
|
||||
gboolean autocreateState, notifyState;
|
||||
@@ -1991,9 +2008,13 @@ sxsincelast_populate( sxSinceLastData *sxsld )
|
||||
"the first time?" );
|
||||
return FALSE;
|
||||
}
|
||||
sx_state = gnc_sx_create_temporal_state( sx );
|
||||
g_hash_table_insert( sxsld->sxInitStates,
|
||||
sx, sx_state );
|
||||
{
|
||||
void *sx_state;
|
||||
sx_state = gnc_sx_create_temporal_state( sx );
|
||||
g_hash_table_insert( sxsld->sxInitStates,
|
||||
sx, sx_state );
|
||||
sx_state = NULL;
|
||||
}
|
||||
|
||||
g_date_set_time( &end, time(NULL) );
|
||||
daysInAdvance = xaccSchedXactionGetAdvanceCreation( sx );
|
||||
@@ -3474,21 +3495,22 @@ gnc_sxsld_free_tci( toCreateInstance *tci )
|
||||
* but here's the rules...
|
||||
*
|
||||
* If we're not cancelling...
|
||||
* . If ignored, then destroy.
|
||||
* . If postponed, then don't.
|
||||
* . If ignored, destroy.
|
||||
* . If postponed, DON'T destroy.
|
||||
* . If to-create, destroy.
|
||||
*
|
||||
* If we are cancelling....
|
||||
* If we are cancelling...
|
||||
* . If ignored, destroy.
|
||||
* . If postponed, destroy.
|
||||
* . UNLESS previously postponed
|
||||
* . If to-create, destroy.
|
||||
*
|
||||
* So, we don't destroy postponed by default, and let the
|
||||
* cancel-specific case handle that destruction [thus the
|
||||
* valid-pointer check].
|
||||
*/
|
||||
if ( tci->prevState != POSTPONE
|
||||
&& tci->origState != POSTPONE
|
||||
if ( tci->prevState != POSTPONE
|
||||
&& tci->origState != POSTPONE
|
||||
&& tci->sxStateData != NULL ) {
|
||||
gnc_sx_destroy_temporal_state( tci->sxStateData );
|
||||
tci->sxStateData = NULL;
|
||||
|
||||
+62
-10
@@ -334,6 +334,7 @@ gnc_ui_sx_loan_druid_create()
|
||||
|
||||
a = GTK_ALIGNMENT(gtk_alignment_new( 0.0, 0.5, 0.25, 1.0 ));
|
||||
gas = GNC_ACCOUNT_SEL(gnc_account_sel_new());
|
||||
gnc_account_sel_set_new_account_ability( gas, TRUE );
|
||||
gtk_container_add( GTK_CONTAINER(a),
|
||||
GTK_WIDGET(gas) );
|
||||
gtk_table_attach( gas_data[i].table,
|
||||
@@ -402,6 +403,7 @@ gnc_ui_sx_loan_druid_create()
|
||||
GTK_SIGNAL_FUNC(ld_escrow_toggle), ldd );
|
||||
gtk_widget_set_sensitive( GTK_WIDGET(ldd->optEscrowHBox), FALSE );
|
||||
ldd->optEscrowGAS = GNC_ACCOUNT_SEL(gnc_account_sel_new());
|
||||
gnc_account_sel_set_new_account_ability( ldd->optEscrowGAS, TRUE );
|
||||
gtk_container_add( GTK_CONTAINER(ldd->optEscrowHBox),
|
||||
GTK_WIDGET(ldd->optEscrowGAS) );
|
||||
|
||||
@@ -820,6 +822,12 @@ ld_info_save( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
ldd = (LoanDruidData*)ud;
|
||||
|
||||
ldd->ld.primaryAcct = gnc_account_sel_get_account( ldd->prmAccountGAS );
|
||||
if ( ldd->ld.primaryAcct == NULL ) {
|
||||
gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog),
|
||||
"Please select a valid "
|
||||
"loan account." );
|
||||
return TRUE;
|
||||
}
|
||||
if ( ! ldd->ld.repPriAcct ) {
|
||||
ldd->ld.repPriAcct = ldd->ld.primaryAcct;
|
||||
}
|
||||
@@ -896,23 +904,30 @@ ld_info_prep( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gboolean
|
||||
ld_opts_save_state( LoanDruidData *ldd )
|
||||
{
|
||||
if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(ldd->optEscrowCb) ) ) {
|
||||
ldd->ld.escrowAcct =
|
||||
gnc_account_sel_get_account( ldd->optEscrowGAS );
|
||||
if ( ldd->ld.escrowAcct == NULL ) {
|
||||
gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog),
|
||||
"Please select a valid "
|
||||
"Escrow Account" );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
} else {
|
||||
ldd->ld.escrowAcct = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
ld_opts_tran( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
{
|
||||
ld_opts_save_state( (LoanDruidData*)ud );
|
||||
return FALSE;
|
||||
return ld_opts_save_state( (LoanDruidData*)ud );
|
||||
}
|
||||
|
||||
static
|
||||
@@ -944,7 +959,7 @@ ld_opts_prep( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gboolean
|
||||
ld_rep_save( LoanDruidData *ldd )
|
||||
{
|
||||
int i;
|
||||
@@ -961,10 +976,28 @@ ld_rep_save( LoanDruidData *ldd )
|
||||
|
||||
ldd->ld.repFromAcct =
|
||||
gnc_account_sel_get_account( ldd->repAssetsFromGAS );
|
||||
if ( ldd->ld.repFromAcct == NULL ) {
|
||||
gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog),
|
||||
"Please select a valid "
|
||||
"\"from\" account." );
|
||||
return TRUE;
|
||||
}
|
||||
ldd->ld.repPriAcct =
|
||||
gnc_account_sel_get_account( ldd->repPrincToGAS );
|
||||
if ( ldd->ld.repPriAcct == NULL ) {
|
||||
gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog),
|
||||
"Please select a valid "
|
||||
"\"to\" account." );
|
||||
return TRUE;
|
||||
}
|
||||
ldd->ld.repIntAcct =
|
||||
gnc_account_sel_get_account( ldd->repIntToGAS );
|
||||
if ( ldd->ld.repIntAcct == NULL ) {
|
||||
gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog),
|
||||
"Please select a valid "
|
||||
"\"interest\" account." );
|
||||
return TRUE;
|
||||
}
|
||||
ldd->ld.remainderChoice =
|
||||
gnc_option_menu_get_active( GTK_WIDGET(ldd->repRemainderOpt) );
|
||||
gnc_frequency_save_state( ldd->repGncFreq,
|
||||
@@ -979,6 +1012,7 @@ ld_rep_save( LoanDruidData *ldd )
|
||||
rod->from = ldd->ld.repFromAcct;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static
|
||||
@@ -989,7 +1023,9 @@ ld_rep_next( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
|
||||
ldd = (LoanDruidData*)ud;
|
||||
|
||||
ld_rep_save( ldd );
|
||||
if ( ld_rep_save( ldd ) != FALSE ) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( (ldd->currentIdx < 0)
|
||||
|| (ldd->currentIdx >= ldd->ld.repayOptCount)
|
||||
@@ -1019,8 +1055,7 @@ ld_rep_back( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
LoanDruidData *ldd;
|
||||
|
||||
ldd = (LoanDruidData*)ud;
|
||||
ld_rep_save(ldd);
|
||||
return FALSE;
|
||||
return ld_rep_save(ldd);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -1107,7 +1142,7 @@ ld_pay_prep( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gboolean
|
||||
ld_pay_save_current( LoanDruidData *ldd )
|
||||
{
|
||||
gchar *tmpStr;
|
||||
@@ -1131,7 +1166,19 @@ ld_pay_save_current( LoanDruidData *ldd )
|
||||
g_free( tmpStr );
|
||||
|
||||
rod->from = gnc_account_sel_get_account( ldd->payAcctFromGAS );
|
||||
if ( rod->from == NULL ) {
|
||||
gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog),
|
||||
"Please select a valid "
|
||||
"\"from\" account." );
|
||||
return TRUE;
|
||||
}
|
||||
rod->to = gnc_account_sel_get_account( ldd->payAcctToGAS );
|
||||
if ( rod->from == NULL ) {
|
||||
gnc_info_dialog_parented( GTK_WINDOW(ldd->dialog),
|
||||
"Please select a valid "
|
||||
"\"to\" account." );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* if ( rb toggled )
|
||||
* ensure freqspec/startdate setup
|
||||
@@ -1164,6 +1211,7 @@ ld_pay_save_current( LoanDruidData *ldd )
|
||||
rod->startDate = NULL;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static
|
||||
@@ -1175,7 +1223,9 @@ ld_pay_next( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
|
||||
ldd = (LoanDruidData*)ud;
|
||||
/* save current data */
|
||||
ld_pay_save_current( ldd );
|
||||
if ( ld_pay_save_current( ldd ) != FALSE ) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Go through opts list and select next enabled option. */
|
||||
for ( i=(++ldd->currentIdx);
|
||||
@@ -1200,7 +1250,9 @@ ld_pay_back( GnomeDruidPage *gdp, gpointer arg1, gpointer ud )
|
||||
ldd = (LoanDruidData*)ud;
|
||||
|
||||
/* save current data */
|
||||
ld_pay_save_current( ldd );
|
||||
if ( ld_pay_save_current( ldd ) != FALSE ) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for ( i=(--ldd->currentIdx);
|
||||
(i > -1) && !ldd->ld.repayOpts[i]->enabled;
|
||||
|
||||
@@ -5565,60 +5565,4 @@ Escrow
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkMenu</class>
|
||||
<name>Since Last Run popup</name>
|
||||
|
||||
<widget>
|
||||
<class>GtkMenuItem</class>
|
||||
<name>creation_state</name>
|
||||
<label>Creation State</label>
|
||||
<right_justify>False</right_justify>
|
||||
|
||||
<widget>
|
||||
<class>GtkMenu</class>
|
||||
<name>creation_state_menu</name>
|
||||
|
||||
<widget>
|
||||
<class>GtkPixmapMenuItem</class>
|
||||
<name>ignore</name>
|
||||
<signal>
|
||||
<name>activate</name>
|
||||
<handler>on_ignore_activate</handler>
|
||||
<last_modification_time>Fri, 23 Aug 2002 22:16:45 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Ignore</label>
|
||||
<right_justify>False</right_justify>
|
||||
<stock_icon>GNOME_STOCK_MENU_STOP</stock_icon>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkPixmapMenuItem</class>
|
||||
<name>postpone</name>
|
||||
<signal>
|
||||
<name>activate</name>
|
||||
<handler>on_postpone_activate</handler>
|
||||
<last_modification_time>Fri, 23 Aug 2002 22:16:45 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Postpone</label>
|
||||
<right_justify>False</right_justify>
|
||||
<stock_icon>GNOME_STOCK_MENU_TIMER_STOP</stock_icon>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkPixmapMenuItem</class>
|
||||
<name>create</name>
|
||||
<signal>
|
||||
<name>activate</name>
|
||||
<handler>on_create_activate</handler>
|
||||
<last_modification_time>Fri, 23 Aug 2002 22:16:45 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Create</label>
|
||||
<right_justify>False</right_justify>
|
||||
<stock_icon>GNOME_STOCK_MENU_TIMER</stock_icon>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
</GTK-Interface>
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
/**
|
||||
* gnc-account-sel.c -- combobox style account selection widget
|
||||
*
|
||||
* Copyright (C) 2002 Joshua Sled <jsled@asynchronous.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Gnucash is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Gnucash 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
|
||||
* Library 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
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
**/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "AccWindow.h"
|
||||
#include "gnc-account-sel.h"
|
||||
#include "gnc-exp-parser.h"
|
||||
#include "messages.h"
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-engine-util.h"
|
||||
#include "gnc-event.h"
|
||||
|
||||
#define ACCT_DATA_TAG "gnc-account-sel_acct"
|
||||
|
||||
/* Signal codes */
|
||||
enum
|
||||
{
|
||||
ACCOUNT_SEL_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static gint account_sel_signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void gnc_account_sel_init (GNCAccountSel *gas);
|
||||
static void gnc_account_sel_class_init (GNCAccountSelClass *class);
|
||||
static void gas_accounts_to_names( gpointer data, gpointer user_data );
|
||||
|
||||
static void gas_populate_list( GNCAccountSel *gas );
|
||||
static void gas_strcmp_adapter( gpointer a, gpointer b );
|
||||
static void gnc_account_sel_event_cb( GUID *entity,
|
||||
GNCEngineEventType event_type,
|
||||
gpointer user_data );
|
||||
|
||||
static void gas_new_account_click( GtkButton *b, gpointer ud );
|
||||
|
||||
static void gas_destroy( GtkObject *o, gpointer user_data );
|
||||
|
||||
#if 0 /* completion not implemented */
|
||||
static void gnc_account_sel_changed( GtkEditable *entry, gpointer ud );
|
||||
static void gnc_account_sel_list_clicked( GtkButton *b, gpointer ud );
|
||||
static gint gnc_account_sel_key_press( GtkWidget *widget,
|
||||
GdkEventKey *event );
|
||||
#endif /* 0 -- completion not implemented */
|
||||
|
||||
static GtkHBox *parent_class;
|
||||
|
||||
guint
|
||||
gnc_account_sel_get_type (void)
|
||||
{
|
||||
static guint account_sel_type = 0;
|
||||
|
||||
if (!account_sel_type){
|
||||
GtkTypeInfo account_sel_info = {
|
||||
"GNCAccountSel",
|
||||
sizeof (GNCAccountSel),
|
||||
sizeof (GNCAccountSelClass),
|
||||
(GtkClassInitFunc) gnc_account_sel_class_init,
|
||||
(GtkObjectInitFunc) gnc_account_sel_init,
|
||||
NULL,
|
||||
NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
account_sel_type = gtk_type_unique (GTK_TYPE_HBOX, &account_sel_info);
|
||||
}
|
||||
|
||||
return account_sel_type;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gnc_account_sel_event_cb( GUID *entity,
|
||||
GNCEngineEventType event_type,
|
||||
gpointer user_data )
|
||||
{
|
||||
if ( ! ( event_type == GNC_EVENT_CREATE
|
||||
|| event_type == GNC_EVENT_MODIFY
|
||||
|| event_type == GNC_EVENT_DESTROY )
|
||||
|| strcmp( xaccGUIDType( entity,
|
||||
gnc_get_current_book() ),
|
||||
GNC_ID_ACCOUNT ) != 0 ) {
|
||||
return;
|
||||
}
|
||||
gas_populate_list( (GNCAccountSel*)user_data );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gnc_account_sel_class_init (GNCAccountSelClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
GtkWidgetClass *widget_class;
|
||||
GtkHBoxClass *hbox_class;
|
||||
|
||||
object_class = (GtkObjectClass*) class;
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
hbox_class = (GtkHBoxClass*) class;
|
||||
|
||||
parent_class = gtk_type_class (gtk_entry_get_type ());
|
||||
|
||||
account_sel_signals [ACCOUNT_SEL_CHANGED] =
|
||||
gtk_signal_new ("account_sel_changed",
|
||||
GTK_RUN_FIRST, object_class->type,
|
||||
GTK_SIGNAL_OFFSET (GNCAccountSelClass,
|
||||
account_sel_changed),
|
||||
gtk_signal_default_marshaller,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
gtk_object_class_add_signals (object_class,
|
||||
account_sel_signals,
|
||||
LAST_SIGNAL);
|
||||
|
||||
class->account_sel_changed = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_account_sel_init (GNCAccountSel *gas)
|
||||
{
|
||||
gas->initDone = FALSE;
|
||||
gas->acctTypeFilters = FALSE;
|
||||
gas->newAccountButton = NULL;
|
||||
|
||||
gas->combo = GTK_COMBO(gtk_combo_new());
|
||||
gtk_combo_set_value_in_list( gas->combo, TRUE, TRUE );
|
||||
gtk_container_add( GTK_CONTAINER(gas), GTK_WIDGET(gas->combo) );
|
||||
|
||||
/* This is only because completion cannot be implemented. */
|
||||
gtk_editable_set_editable( GTK_EDITABLE(gas->combo->entry), FALSE );
|
||||
gtk_signal_connect( GTK_OBJECT(gas), "destroy",
|
||||
GTK_SIGNAL_FUNC( gas_destroy ),
|
||||
gas );
|
||||
|
||||
|
||||
#if 0 /* completion not implemented. */
|
||||
gtk_signal_connect( GTK_OBJECT(gas->combo->entry), "changed",
|
||||
GTK_SIGNAL_FUNC( gnc_account_sel_changed ),
|
||||
gas );
|
||||
#endif /* 0 -- completion not implemented. */
|
||||
|
||||
|
||||
/* Get the accounts, place into combo list */
|
||||
gas_populate_list( gas );
|
||||
|
||||
gas->eventHandlerId =
|
||||
gnc_engine_register_event_handler( gnc_account_sel_event_cb, gas );
|
||||
|
||||
gas->initDone = TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GNCAccountSel *gas;
|
||||
GList **outList;
|
||||
char accountSep;
|
||||
} accounts_to_names_data;
|
||||
|
||||
/**
|
||||
* Used in the g_list_foreach call in gas_populate_list to see if the given
|
||||
* string is in [via strcmp] the list, and to set the flag as necessary.
|
||||
**/
|
||||
typedef struct {
|
||||
char *str;
|
||||
gboolean flag;
|
||||
} findData;
|
||||
|
||||
static
|
||||
void
|
||||
gas_strcmp_adapter( gpointer listElt, gpointer ud )
|
||||
{
|
||||
findData *fd = (findData*)ud;
|
||||
fd->flag |= ( strcmp( (char*)listElt, (char*)fd->str ) == 0 );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gas_populate_list( GNCAccountSel *gas )
|
||||
{
|
||||
accounts_to_names_data atnd;
|
||||
AccountGroup *ag;
|
||||
GList *accts, *nameList;
|
||||
gchar *currentSel;
|
||||
|
||||
currentSel = gtk_editable_get_chars(
|
||||
GTK_EDITABLE(gas->combo->entry), 0, -1 );
|
||||
|
||||
ag = gnc_book_get_group( gnc_get_current_book() );
|
||||
accts = (GList*)xaccGroupGetSubAccounts( ag );
|
||||
|
||||
nameList = NULL;
|
||||
atnd.gas = gas;
|
||||
atnd.outList = &nameList;
|
||||
atnd.accountSep = gnc_get_account_separator();
|
||||
|
||||
g_list_foreach( accts, gas_accounts_to_names,
|
||||
(gpointer)&atnd );
|
||||
g_list_free( accts );
|
||||
|
||||
if ( g_list_length( nameList ) > 0 ) {
|
||||
gtk_combo_set_popdown_strings( gas->combo, nameList );
|
||||
}
|
||||
|
||||
/* If the account which was in the text box before still exists, then
|
||||
* reset to it. */
|
||||
{
|
||||
findData tmpfd;
|
||||
gint pos;
|
||||
tmpfd.str = currentSel;
|
||||
tmpfd.flag = FALSE;
|
||||
|
||||
g_list_foreach( nameList, gas_strcmp_adapter, &tmpfd );
|
||||
|
||||
if ( tmpfd.flag ) {
|
||||
gtk_editable_delete_text(
|
||||
GTK_EDITABLE(gas->combo->entry), 0, -1 );
|
||||
pos = 0;
|
||||
gtk_editable_insert_text(
|
||||
GTK_EDITABLE(gas->combo->entry),
|
||||
currentSel, strlen(currentSel), &pos );
|
||||
}
|
||||
}
|
||||
g_list_free( nameList );
|
||||
if ( currentSel ) {
|
||||
g_free( currentSel );
|
||||
}
|
||||
|
||||
#if 0 /* completion not implemented */
|
||||
gas->completion = g_completion_new( NULL );
|
||||
g_completion_add_items( gas->completion, nameList );
|
||||
#endif /* 0 -- completion not implemented */
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gas_accounts_to_names( gpointer data, gpointer user_data )
|
||||
{
|
||||
accounts_to_names_data *atnd;
|
||||
Account *a;
|
||||
|
||||
atnd = (accounts_to_names_data*)user_data;
|
||||
a = (Account*)data;
|
||||
/* Filter as we've been configured to do. */
|
||||
if ( atnd->gas->acctTypeFilters ) {
|
||||
/* g_list_find is the poor-mans '(member ...)', especially
|
||||
* easy when the data pointers in the list are just casted
|
||||
* account type identifiers. */
|
||||
if ( g_list_find( atnd->gas->acctTypeFilters,
|
||||
GINT_TO_POINTER(xaccAccountGetType( a )) )
|
||||
== NULL ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
*atnd->outList =
|
||||
g_list_append( *atnd->outList,
|
||||
xaccAccountGetFullName(a, atnd->accountSep) );
|
||||
}
|
||||
|
||||
#if 0 /* completion not implemented */
|
||||
/*
|
||||
* There is apparently no way -- in GTK 1.x -- to programatically select a
|
||||
* region in the way we would like... so we've disallowed manual editing of
|
||||
* the Account string.
|
||||
*/
|
||||
static
|
||||
void
|
||||
gnc_account_sel_changed( GtkEditable *entry, gpointer ud )
|
||||
{
|
||||
gchar *s, *prefix;
|
||||
GNCAccountSel *gas = (GNCAccountSel*)ud;
|
||||
|
||||
if ( !gas->initDone ) {
|
||||
return;
|
||||
}
|
||||
s = gtk_editable_get_chars( entry, 0, -1 );
|
||||
g_completion_complete( gas->completion, s, &prefix );
|
||||
if ( prefix && (strlen(prefix) > 0) ) {
|
||||
printf( "changed into \"%s\"; longest completion: \"%s\"\n", s, prefix );
|
||||
gtk_signal_handler_block_by_func( GTK_OBJECT(gas->combo->entry),
|
||||
GTK_SIGNAL_FUNC(gnc_account_sel_changed),
|
||||
ud );
|
||||
gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), prefix );
|
||||
gtk_editable_select_region( GTK_EDITABLE(gas->combo->entry),
|
||||
strlen(s), -1 );
|
||||
{
|
||||
GdkEventKey k;
|
||||
gboolean ret;
|
||||
|
||||
k.type = GDK_KEY_RELEASE;
|
||||
k.send_event = TRUE;
|
||||
k.state = GDK_SHIFT_MASK;
|
||||
k.keyval = GDK_End;
|
||||
k.length = 0;
|
||||
k.string = "";
|
||||
printf( "foo [%d : \"%s\"]\n", k.length, k.string );
|
||||
//gtk_widget_event( GTK_WIDGET(gas->combo->entry), &e );
|
||||
gtk_signal_emit_by_name( GTK_OBJECT(gas->combo->entry),
|
||||
"key-press-event",
|
||||
gas->combo->entry, &k, NULL, &ret );
|
||||
printf( "bar\n" );
|
||||
}
|
||||
gtk_editable_set_position( GTK_EDITABLE(gas->combo->entry),
|
||||
strlen(s) );
|
||||
gtk_signal_handler_unblock_by_func( GTK_OBJECT(gas->combo->entry),
|
||||
GTK_SIGNAL_FUNC(gnc_account_sel_changed),
|
||||
ud );
|
||||
g_free( prefix );
|
||||
}
|
||||
g_free( s );
|
||||
}
|
||||
|
||||
static
|
||||
gint
|
||||
gnc_account_sel_key_press(GtkWidget *widget, GdkEventKey *event)
|
||||
{
|
||||
GNCAccountSel *gas = GNC_ACCOUNT_SEL(widget);
|
||||
gint result;
|
||||
|
||||
result = (* GTK_WIDGET_CLASS (parent_class)->key_press_event)(widget, event);
|
||||
|
||||
switch (event->keyval)
|
||||
{
|
||||
case GDK_Tab:
|
||||
/* FIXME: += equivalent keys. */
|
||||
break;
|
||||
if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK))
|
||||
break;
|
||||
return result;
|
||||
case GDK_KP_Enter:
|
||||
break;
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* 0 -- completion not implemented */
|
||||
|
||||
GtkWidget *
|
||||
gnc_account_sel_new (void)
|
||||
{
|
||||
GNCAccountSel *gas;
|
||||
|
||||
gas = gtk_type_new (gnc_account_sel_get_type ());
|
||||
|
||||
return GTK_WIDGET (gas);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gnc_account_sel_gtk_entry (GNCAccountSel *gas)
|
||||
{
|
||||
g_return_val_if_fail(gas != NULL, NULL);
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT_SEL(gas), NULL);
|
||||
|
||||
return (GtkWidget *)gas->combo->entry;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_sel_set_account( GNCAccountSel *gas, Account *acct )
|
||||
{
|
||||
gchar *acctStr;
|
||||
|
||||
if ( acct == NULL ) {
|
||||
gtk_list_select_item( GTK_LIST(gas->combo->list), 0 );
|
||||
return;
|
||||
}
|
||||
acctStr = xaccAccountGetFullName( acct,
|
||||
gnc_get_account_separator() );
|
||||
gtk_entry_set_text( GTK_ENTRY(gas->combo->entry), acctStr );
|
||||
g_free( acctStr );
|
||||
}
|
||||
|
||||
Account*
|
||||
gnc_account_sel_get_account( GNCAccountSel *gas )
|
||||
{
|
||||
AccountGroup *ag;
|
||||
Account *ret;
|
||||
gchar *txt;
|
||||
|
||||
ret = NULL;
|
||||
txt = gtk_editable_get_chars( GTK_EDITABLE(gas->combo->entry), 0, -1 );
|
||||
g_assert( txt != NULL );
|
||||
if ( strlen(txt) == 0 ) {
|
||||
goto cleanup;
|
||||
}
|
||||
ag = gnc_book_get_group( gnc_get_current_book() );
|
||||
ret = xaccGetAccountFromFullName( ag, txt, gnc_get_account_separator() );
|
||||
cleanup:
|
||||
g_free( txt );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gnc_account_sel_set_acct_filters( GNCAccountSel *gas, GList *filters )
|
||||
{
|
||||
if ( gas->acctTypeFilters != NULL ) {
|
||||
g_list_free( gas->acctTypeFilters );
|
||||
gas->acctTypeFilters = NULL;
|
||||
}
|
||||
/* If it's null, then no filters exist. */
|
||||
if ( ! filters ) {
|
||||
return;
|
||||
}
|
||||
/* This works because the GNCAccountTypes in the list are
|
||||
* ints-casted-as-pointers. */
|
||||
gas->acctTypeFilters = g_list_copy( filters );
|
||||
gas_populate_list( gas );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gas_destroy( GtkObject *o, gpointer user_data )
|
||||
{
|
||||
GNCAccountSel *gas = (GNCAccountSel*)user_data;
|
||||
if ( gas->acctTypeFilters ) {
|
||||
g_list_free( gas->acctTypeFilters );
|
||||
}
|
||||
gnc_engine_unregister_event_handler( gas->eventHandlerId );
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_sel_set_new_account_ability( GNCAccountSel *gas,
|
||||
gboolean state )
|
||||
{
|
||||
g_assert( gas );
|
||||
if ( state == (gas->newAccountButton != NULL) ) {
|
||||
/* We're already in that state; don't do anything. */
|
||||
return;
|
||||
}
|
||||
|
||||
if ( gas->newAccountButton ) {
|
||||
g_assert( state == TRUE );
|
||||
/* destroy the existing button. */
|
||||
gtk_container_remove( GTK_CONTAINER(gas),
|
||||
gas->newAccountButton );
|
||||
gtk_widget_destroy( gas->newAccountButton );
|
||||
gas->newAccountButton = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* create the button. */
|
||||
gas->newAccountButton = gtk_button_new_with_label( _("New...") );
|
||||
gtk_signal_connect( GTK_OBJECT(gas->newAccountButton),
|
||||
"clicked",
|
||||
GTK_SIGNAL_FUNC( gas_new_account_click ),
|
||||
gas );
|
||||
gtk_box_pack_start( GTK_BOX(gas), gas->newAccountButton,
|
||||
FALSE, FALSE, 2 );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gas_new_account_click( GtkButton *b, gpointer ud )
|
||||
{
|
||||
GNCAccountSel *gas = (GNCAccountSel*)ud;
|
||||
gnc_ui_new_account_with_types( NULL, gas->acctTypeFilters );
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
/**
|
||||
* gnc-account-sel.h -- combobox style account selection widget, with
|
||||
* auto-completion.
|
||||
* gnc-account-sel.h -- combobox style account selection widget.
|
||||
*
|
||||
* Note that this widget will track changes in the account tree, and update
|
||||
* itself accordingly. If an account with the same name exists in the
|
||||
* freshly-retreived account list, the widget will re-select that account.
|
||||
*
|
||||
* Copyright (C) 2002 Joshua Sled <jsled@asynchronous.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* GnuCash is free software; you can redistribute it and/or modify
|
||||
**/
|
||||
|
||||
/* GnuCash is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
@@ -21,7 +25,7 @@
|
||||
* Free Software Foundation Voice: +1-617-542-5942
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef GNC_ACCOUNT_SEL_H
|
||||
#define GNC_ACCOUNT_SEL_H
|
||||
@@ -37,18 +41,26 @@ BEGIN_GNOME_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkHBox hbox;
|
||||
gboolean initDone;
|
||||
GtkCombo *combo;
|
||||
GCompletion *completion;
|
||||
GtkHBox hbox;
|
||||
gboolean initDone;
|
||||
GtkCombo *combo;
|
||||
GList *acctTypeFilters;
|
||||
gint eventHandlerId;
|
||||
/* The state of this pointer also serves as a flag about what state
|
||||
* the widget is in WRT the new-account-button ability. */
|
||||
GtkWidget *newAccountButton;
|
||||
|
||||
#if 0 /* completion not implemented. */
|
||||
GCompletion *completion;
|
||||
#endif /* 0 - completion not implemented */
|
||||
} GNCAccountSel;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkHBoxClass parent_class;
|
||||
GtkHBoxClass parent_class;
|
||||
|
||||
/* Signals for notification/filtering of changes */
|
||||
void (*account_sel_changed) (GNCAccountSel *gas);
|
||||
/* Signals for notification/filtering of changes */
|
||||
void (*account_sel_changed) (GNCAccountSel *gas);
|
||||
} GNCAccountSelClass;
|
||||
|
||||
guint gnc_account_sel_get_type(void);
|
||||
@@ -66,6 +78,21 @@ void gnc_account_sel_set_account( GNCAccountSel *gas, Account *acct );
|
||||
**/
|
||||
Account* gnc_account_sel_get_account( GNCAccountSel *gas );
|
||||
|
||||
/**
|
||||
* The GNCAccountSel can be setup to filter the accounts displayed.
|
||||
* @param filters A GList of GNCAccountType identifiers which are allowed.
|
||||
* The list is copied, of course.
|
||||
**/
|
||||
void gnc_account_sel_set_acct_filters( GNCAccountSel *gas, GList *filters );
|
||||
|
||||
/**
|
||||
* Conditional inclusion of a new-account button to the right of the
|
||||
* combobox.
|
||||
* @param state TRUE if the new-account button is desired, FALSE otherwise.
|
||||
**/
|
||||
void gnc_account_sel_set_new_account_ability( GNCAccountSel *gas,
|
||||
gboolean state );
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* !ndef GNC_ACCOUNT_SEL_H */
|
||||
@@ -852,7 +852,7 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo)
|
||||
static GnomeUIInfo gnc_sched_xaction_tools_submenu_template[] =
|
||||
{
|
||||
{ GNOME_APP_UI_ITEM,
|
||||
N_("_List and Editor"),
|
||||
N_("_Scheduled Transaction Editor"),
|
||||
N_("The list of Scheduled Transactions"),
|
||||
gnc_main_window_sched_xaction_cb, NULL, NULL,
|
||||
GNOME_APP_PIXMAP_NONE, NULL,
|
||||
|
||||
Reference in New Issue
Block a user