Register rewrite Update.

The main things in this patch is I think the model is working correctly now,
you can add, change and delete same currency transactions along with different
currencies asking for exchange rates and also share accounts.

Other changes:
- use the default GTK_TREE_VIEW sort mechanism.
- Added cut, copy & paste
- Added right-click context menu.

Author: Robert Fewell Register rewrite Update.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@22815 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Geert Janssens 2013-02-28 09:52:12 +00:00
parent 3b9a438507
commit 9a267d805d
21 changed files with 5023 additions and 2866 deletions

View File

@ -312,6 +312,7 @@ src/gnome-utils/gnc-recurrence.c
src/gnome-utils/gnc-splash.c
src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
src/gnome-utils/gnc-sx-list-tree-model-adapter.c
src/gnome-utils/gnc-tree-control-split-reg.c
src/gnome-utils/gnc-tree-model-account.c
src/gnome-utils/gnc-tree-model-account-types.c
src/gnome-utils/gnc-tree-model-budget.c

View File

@ -432,6 +432,39 @@ xaccSplitClone (const Split *s)
return split;
}
/*################## Added for Reg2 #################*/
/* This is really a helper for xaccTransCopyOnto. It doesn't reparent
the 'to' split to from's transaction, because xaccTransCopyOnto is
responsible for parenting the split to the correct transaction.
Also, from's parent transaction may not even be a valid
transaction, so this function may not modify anything about 'from'
or from's transaction.
*/
void
xaccSplitCopyOnto(const Split *from_split, Split *to_split)
{
if (!from_split || !to_split) return;
xaccTransBeginEdit (to_split->parent);
xaccSplitSetMemo(to_split, xaccSplitGetMemo(from_split));
xaccSplitSetAction(to_split, xaccSplitGetAction(from_split));
xaccSplitSetAmount(to_split, xaccSplitGetAmount(from_split));
xaccSplitSetValue(to_split, xaccSplitGetValue(from_split));
/* Setting the account is okay here because, even though the from
split might not really belong to the account it claims to,
setting the account won't cause any event involving from. */
xaccSplitSetAccount(to_split, xaccSplitGetAccount(from_split));
/* N.B. Don't set parent. */
qof_instance_set_dirty(QOF_INSTANCE(to_split));
xaccTransCommitEdit(to_split->parent);
}
/*################## Added for Reg2 #################*/
#ifdef DUMP_FUNCTIONS
void
xaccSplitDump (const Split *split, const char *tag)

View File

@ -113,6 +113,17 @@ void xaccSplitReinit(Split * split);
*/
gboolean xaccSplitDestroy (Split *split);
/*################## Added for Reg2 #################*/
/** This is really a helper for xaccTransCopyOnto. It doesn't reparent
* the 'to' split to from's transaction, because xaccTransCopyOnto is
* responsible for parenting the split to the correct transaction.
* Also, from's parent transaction may not even be a valid
* transaction, so this function may not modify anything about 'from'
* or from's transaction.
*/
void xaccSplitCopyOnto(const Split *from_split, Split *to_split);
/*################## Added for Reg2 #################*/
/** Returns the book of this split, i.e. the entity where this split
* is stored. */
QofBook * xaccSplitGetBook (const Split *split);

View File

@ -564,10 +564,10 @@ xaccDupeTransaction (const Transaction *from)
return to;
}
/*
/********************************************************************\
* Use this routine to externally duplicate a transaction. It creates
* a full fledged transaction with unique guid, splits, etc.
*/
\********************************************************************/
Transaction *
xaccTransClone (const Transaction *from)
{
@ -606,10 +606,90 @@ xaccTransClone (const Transaction *from)
return to;
}
/*################## Added for Reg2 #################*/
/********************************************************************\
* Copy a transaction to the 'clipboard' transaction using
* xaccDupeTransaction. The 'clipboard' transaction must never
* be dereferenced.
\********************************************************************/
Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
{
Transaction *to_trans;
if (!from_trans)
return NULL;
to_trans = xaccDupeTransaction(from_trans);
return to_trans;
}
/********************************************************************\
* Copy a transaction to another using the function below without
* changing any account information.
\********************************************************************/
void
xaccTransCopyOnto(const Transaction *from_trans, Transaction *to_trans)
{
xaccTransCopyFromClipBoard(from_trans, to_trans, NULL, NULL);
}
/********************************************************************\
* This function explicitly must robustly handle some unusual input.
*
* 'from_trans' may be a duped trans (see xaccDupeTransaction), so its
* splits may not really belong to the accounts that they say they do.
*
* 'from_acc' need not be a valid account. It may be an already freed
* Account. Therefore, it must not be dereferenced at all.
*
* Neither 'from_trans', nor 'from_acc', nor any of 'from's splits may be modified
* in any way.
*
* The 'to_trans' transaction will end up with valid copies of from's
* splits. In addition, the copies of any of from's splits that were
* in from_acc (or at least claimed to be) will end up in to_acc.
\********************************************************************/
void
xaccTransCopyFromClipBoard(const Transaction *from_trans, Transaction *to_trans,
const Account *from_acc, Account *to_acc)
{
Timespec ts = {0,0};
gboolean change_accounts = FALSE;
GList *node;
if (!from_trans || !to_trans)
return;
change_accounts = from_acc && GNC_IS_ACCOUNT(to_acc) && from_acc != to_acc;
xaccTransBeginEdit(to_trans);
FOR_EACH_SPLIT(to_trans, xaccSplitDestroy(s));
xaccTransSetCurrency(to_trans, xaccTransGetCurrency(from_trans));
xaccTransSetDescription(to_trans, xaccTransGetDescription(from_trans));
xaccTransSetNum(to_trans, xaccTransGetNum(from_trans));
xaccTransSetNotes(to_trans, xaccTransGetNotes(from_trans));
xaccTransGetDatePostedTS(from_trans, &ts);
xaccTransSetDatePostedTS(to_trans, &ts);
/* Each new split will be parented to 'to' */
for (node = from_trans->splits; node; node = node->next)
{
Split *new_split = xaccMallocSplit( qof_instance_get_book(QOF_INSTANCE(from_trans)));
xaccSplitCopyOnto(node->data, new_split);
if (change_accounts && xaccSplitGetAccount(node->data) == from_acc)
xaccSplitSetAccount(new_split, to_acc);
xaccSplitSetParent(new_split, to_trans);
}
xaccTransCommitEdit(to_trans);
}
/*################## Added for Reg2 #################*/
/********************************************************************\
Free the transaction.
\********************************************************************/
static void
xaccFreeTransaction (Transaction *trans)
{
@ -1021,36 +1101,42 @@ xaccTransGetAccountAmount (const Transaction *trans, const Account *acc)
gboolean
xaccTransGetRateForCommodity(const Transaction *trans,
const gnc_commodity *split_com,
const Split *split_to_exclude, gnc_numeric *rate)
const Split *split, gnc_numeric *rate)
{
GList *splits;
gnc_commodity *trans_curr;
trans_curr = xaccTransGetCurrency(trans);
if (gnc_commodity_equal(trans_curr, split_com)) {
trans_curr = xaccTransGetCurrency (trans);
if (gnc_commodity_equal (trans_curr, split_com))
{
if (rate)
*rate = gnc_numeric_create(1, 1);
*rate = gnc_numeric_create (1, 1);
return TRUE;
}
for (splits = trans->splits; splits; splits = splits->next) {
for (splits = trans->splits; splits; splits = splits->next)
{
Split *s = splits->data;
gnc_commodity *comm;
if (s == split_to_exclude) continue;
if (!xaccTransStillHasSplit(trans, s)) continue;
if (!xaccTransStillHasSplit (trans, s)) continue;
comm = xaccAccountGetCommodity(xaccSplitGetAccount(s));
if (gnc_commodity_equal(split_com, comm)) {
gnc_numeric amt = xaccSplitGetAmount(s);
gnc_numeric val = xaccSplitGetValue(s);
if (s == split)
{
comm = xaccAccountGetCommodity (xaccSplitGetAccount(s));
if (gnc_commodity_equal (split_com, comm))
{
gnc_numeric amt = xaccSplitGetAmount (s);
gnc_numeric val = xaccSplitGetValue (s);
if (!gnc_numeric_zero_p(xaccSplitGetValue(s)) &&
!gnc_numeric_zero_p(xaccSplitGetValue(s))) {
if (rate)
*rate = gnc_numeric_div(amt, val, GNC_DENOM_AUTO,
GNC_HOW_DENOM_REDUCE);
return TRUE;
if (!gnc_numeric_zero_p (xaccSplitGetAmount (s)) &&
!gnc_numeric_zero_p (xaccSplitGetValue (s)))
{
if (rate)
*rate = gnc_numeric_div (amt, val, GNC_DENOM_AUTO,
GNC_HOW_DENOM_REDUCE);
return TRUE;
}
}
}
}
@ -1983,6 +2069,14 @@ xaccTransGetDate (const Transaction *trans)
return trans ? trans->date_posted.tv_sec : 0;
}
/*################## Added for Reg2 #################*/
time64
xaccTransGetDateEntered (const Transaction *trans)
{
return trans ? trans->date_entered.tv_sec : 0;
}
/*################## Added for Reg2 #################*/
void
xaccTransGetDatePostedTS (const Transaction *trans, Timespec *ts)
{

View File

@ -220,6 +220,40 @@ gboolean xaccTransIsOpen (const Transaction *trans);
Transaction * xaccTransLookup (const GncGUID *guid, QofBook *book);
#define xaccTransLookupDirect(g,b) xaccTransLookup(&(g),b)
/*################## Added for Reg2 #################*/
/** Copy a transaction to the 'clipboard' transaction using
* xaccDupeTransaction. The 'clipboard' transaction must never
* be dereferenced.
*/
Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans);
/** Copy a transaction to another using the function below without
* changing any account information.
*/
void xaccTransCopyOnto(const Transaction *from_trans, Transaction *to_trans);
/** This function explicitly must robustly handle some unusual input.
*
* 'from_trans' may be a duped trans (see xaccDupeTransaction), so its
* splits may not really belong to the accounts that they say they do.
*
* 'from_acc' need not be a valid account. It may be an already freed
* Account. Therefore, it must not be dereferenced at all.
*
* Neither 'from_trans', nor 'from_acc', nor any of 'from's splits may be modified
* in any way.
*
* The 'to_trans' transaction will end up with valid copies of from's
* splits. In addition, the copies of any of from's splits that were
* in from_acc (or at least claimed to be) will end up in to_acc.
*/
void xaccTransCopyFromClipBoard(const Transaction *from_trans, Transaction *to_trans,
const Account *from_acc, Account *to_acc);
/*################## Added for Reg2 #################*/
Split * xaccTransFindSplitByAccount(const Transaction *trans,
const Account *acc);
@ -560,6 +594,11 @@ Timespec xaccTransRetDatePostedTS (const Transaction *trans);
the date when this transaction was posted at the bank. */
GDate xaccTransGetDatePostedGDate (const Transaction *trans);
/*################## Added for Reg2 #################*/
/** Retrieve the date of when the transaction was entered. The entered
* date is the date when the register entry was made.*/
time64 xaccTransGetDateEntered (const Transaction *trans);
/*################## Added for Reg2 #################*/
/** Retrieve the date of when the transaction was entered. The entered
* date is the date when the register entry was made.*/
void xaccTransGetDateEnteredTS (const Transaction *trans, Timespec *ts);

View File

@ -83,6 +83,7 @@ libgncmod_gnome_utils_la_SOURCES = \
gnc-splash.c \
gnc-sx-instance-dense-cal-adapter.c \
gnc-sx-list-tree-model-adapter.c \
gnc-tree-control-split-reg.c \
gnc-tree-model.c \
gnc-tree-model-account-types.c \
gnc-tree-model-account.c \
@ -160,6 +161,7 @@ gncinclude_HEADERS = \
gnc-splash.h \
gnc-sx-instance-dense-cal-adapter.h \
gnc-sx-list-tree-model-adapter.h \
gnc-tree-control-split-reg.h \
gnc-tree-model.h \
gnc-tree-model-account-types.h \
gnc-tree-model-account.h \

View File

@ -1695,6 +1695,7 @@ gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData)
SCM quotes_func;
SCM book_scm;
SCM scm_window;
gboolean have_price = FALSE;
g_return_if_fail (xferData);
@ -1736,6 +1737,22 @@ gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData)
rate = gnc_price_get_value (prc);
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit), rate);
gnc_price_unref (prc);
have_price = TRUE;
}
/* Lets try reversing the commodities */
if(!have_price)
{
prc = gnc_pricedb_lookup_latest (xferData->pricedb, to, from);
if (prc)
{
rate = gnc_numeric_div (gnc_numeric_create (1, 1), gnc_price_get_value (prc),
GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit), rate);
gnc_price_unref (prc);
have_price = TRUE;
}
}
LEAVE("quote retrieved");

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
/********************************************************************\
* gnc-tree-control-split-reg.h -- GtkTreeView implementation *
* to display registers in a GtkTreeView. *
* *
* Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker@cox.net> *
* Copyright (C) 2012 Robert Fewell *
* *
* 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 __GNC_TREE_CONTROL_SPLIT_REG_H
#define __GNC_TREE_CONTROL_SPLIT_REG_H
#include "gnc-tree-model-split-reg.h"
#include "gnc-tree-view-split-reg.h"
G_BEGIN_DECLS
/*****************************************************************************/
void gnc_tree_control_split_reg_exchange_rate (GncTreeViewSplitReg *view);
void gnc_tree_control_split_reg_void_current_trans (GncTreeViewSplitReg *view, const char *reason);
void gnc_tree_control_split_reg_unvoid_current_trans (GncTreeViewSplitReg *view);
void gnc_tree_control_split_reg_jump_to_blank (GncTreeViewSplitReg *view);
void gnc_tree_control_split_reg_jump_to_split (GncTreeViewSplitReg *view, Split *split);
void gnc_tree_control_split_reg_cancel_edit (GncTreeViewSplitReg *view, gboolean reg_closing);
void gnc_tree_control_split_reg_goto_rel_trans_row (GncTreeViewSplitReg *view, gint relative);
void gnc_tree_control_split_reg_enter (GncTreeViewSplitReg *view, gboolean next_transaction);
void gnc_tree_control_split_reg_reinit (GncTreeViewSplitReg *view, gpointer data);
void gnc_tree_control_split_reg_reverse_current (GncTreeViewSplitReg *view);
void gnc_tree_control_split_reg_delete (GncTreeViewSplitReg *view, gpointer data);
Transaction * gnc_tree_control_split_reg_get_blank_trans (GncTreeViewSplitReg *view);
Split * gnc_tree_control_split_reg_get_current_trans_split (GncTreeViewSplitReg *view);
Split * gnc_tree_control_split_reg_get_blank_split (GncTreeViewSplitReg *view);
gboolean gnc_tree_control_split_reg_duplicate_current (GncTreeViewSplitReg *view);
gboolean gnc_tree_control_split_reg_save (GncTreeViewSplitReg *view, gboolean reg_closing);
gboolean gnc_tree_control_split_reg_recn_change (GncTreeViewSplitReg *view);
gboolean gnc_tree_control_split_reg_recn_test (GncTreeViewSplitReg *view);
/*****************************************************************************/
/* Cut transaction and copy to clipboard */
void gnc_tree_control_split_reg_cut_trans (GncTreeViewSplitReg *view);
/* Copy transaction to clipboard */
void gnc_tree_control_split_reg_copy_trans (GncTreeViewSplitReg *view);
/* Paste transaction from clipboard */
void gnc_tree_control_split_reg_paste_trans (GncTreeViewSplitReg *view);
/*****************************************************************************/
/* Sort changed callback */
void gnc_tree_control_split_reg_sort_changed_cb (GtkTreeSortable *sortable, gpointer user_data);
/* Sort by date */
gint gnc_tree_control_split_reg_sort_by_date (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
gpointer user_data);
/* Sort by Description / Notes / Memo */
gint gnc_tree_control_split_reg_sort_by_dnm (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
gpointer user_data);
/* Sort function for Number / Action column */
gint gnc_tree_control_split_reg_sort_by_numact (GtkTreeModel *tm, GtkTreeIter *a, GtkTreeIter *b,
gpointer user_data);
/* Sort function for Reconcile column */
gint gnc_tree_control_split_reg_sort_by_recn (GtkTreeModel *tm, GtkTreeIter *a, GtkTreeIter *b,
gpointer user_data);
/*****************************************************************************/
G_END_DECLS
#endif /* __GNC_TREE_CONTROL_SPLIT_REG_H */

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,8 @@
* gnc-tree-model-split-reg.h -- GtkTreeView implementation to *
* display registers in a GtkTreeView. *
* *
* Copyright (C) 2012 Robert Fewell *
* Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker@cox.net> *
* Copyright (C) 2012 Robert Fewell *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@ -33,7 +33,6 @@
#include "Query.h"
G_BEGIN_DECLS
/* type macros */
@ -98,10 +97,9 @@ typedef enum
GNC_TREE_MODEL_SPLIT_REG_COL_LAST_VISIBLE = GNC_TREE_MODEL_SPLIT_REG_COL_RECN, //6
/* internal hidden columns */
GNC_TREE_MODEL_SPLIT_REG_COL_COLOR, //7
GNC_TREE_MODEL_SPLIT_REG_COL_RO, //8
GNC_TREE_MODEL_SPLIT_REG_COL_RO, //7
GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS //9
GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS //8
} GncTreeModelSplitRegColumn;
/* typedefs & structures */
@ -120,31 +118,36 @@ typedef struct
gboolean is_template;
gboolean do_auto_complete; /**<FIXME Not setup - whether to use auto-competion */
gboolean use_accounting_labels; /**< whether to use accounting Labels */
gboolean separator_changed; /**< whether the separator has changed */
gboolean alt_colors_by_txn; /**< whether to use alternative colors by transaction */
gboolean use_colors; /**< whether to use theme colors */
gboolean use_theme_colors; /**< whether to use theme colors */
gboolean read_only; /**< register is read only */
}GncTreeModelSplitReg;
/** The class data structure for an account tree model. */
typedef struct
{
GncTreeModelClass gnc_tree_model; /**< The parent object data. */
GncTreeModelClass gnc_tree_model; /**< The parent object data. */
/* This signal is emitted to refresh the view */
void (*refresh_signal) (GncTreeModelSplitReg *model, gpointer user_data);
void (*refresh_view) (GncTreeModelSplitReg *model, gpointer user_data);
/* This signal is emitted to refresh the status bar */
void (*refresh_status_bar) (GncTreeModelSplitReg *model, gpointer user_data);
/* This signal is emitted before a transaction delete, the pointer has
the transaction */
void (*trans_delete) (GncTreeModelSplitReg *model, gpointer item);
} GncTreeModelSplitRegClass;
/** Callback function type */
/*FIXME Not sure if this is needed or what it is for yet*/
/** Callback function type - Used to get parent window */
typedef GtkWidget *(*SRGetParentCallback2) (gpointer user_data);
/** Get the type of split register tree plugin.
@ -153,83 +156,100 @@ typedef GtkWidget *(*SRGetParentCallback2) (gpointer user_data);
*/
GType gnc_tree_model_split_reg_get_type (void);
/** Create new model and set options for register. */
GncTreeModelSplitReg *
gnc_tree_model_split_reg_new (SplitRegisterType2 reg_type, SplitRegisterStyle2 style,
gboolean use_double_line, gboolean is_template);
/** Load the model from a slist and set default account for register. */
void gnc_tree_model_split_reg_load (GncTreeModelSplitReg *model, GList * slist, Account *default_account);
/** FIXME Not sure what this is for yet. */
void gnc_tree_model_split_reg_set_template_account (GncTreeModelSplitReg *model, Account *template_account);
/** Destroy the model. */
void gnc_tree_model_split_reg_destroy (GncTreeModelSplitReg *model);
/** Sets the user data and callback hooks for the register. */
void gnc_tree_model_split_reg_set_data (GncTreeModelSplitReg *model, gpointer user_data,
SRGetParentCallback2 get_parent);
/** Returns the parent Window of the register. */
GtkWidget * gnc_tree_model_split_reg_get_parent (GncTreeModelSplitReg *model);
/** Set style and type for register. */
void gnc_tree_model_split_reg_config (GncTreeModelSplitReg *model, SplitRegisterType2 newtype,
SplitRegisterStyle2 newstyle, gboolean use_double_line);
/** Return the default account for this register model. */
Account * gnc_tree_model_split_reg_get_anchor (GncTreeModelSplitReg *model);
void gnc_tree_model_split_reg_commit_split (GncTreeModelSplitReg *model, Split *split);
/** Commit the blank split. */
void gnc_tree_model_split_reg_commit_blank_split (GncTreeModelSplitReg *model);
/** Set display general ledger and show sub accounts. */
void gnc_tree_model_split_reg_set_display (GncTreeModelSplitReg *model, gboolean subacc, gboolean gl);
/* These are to do with autocompletion */
GtkListStore *
gnc_tree_model_split_reg_get_description_list (GncTreeModelSplitReg *model);
GtkListStore * gnc_tree_model_split_reg_get_description_list (GncTreeModelSplitReg *model);
GtkListStore *
gnc_tree_model_split_reg_get_notes_list (GncTreeModelSplitReg *model);
GtkListStore * gnc_tree_model_split_reg_get_notes_list (GncTreeModelSplitReg *model);
GtkListStore *
gnc_tree_model_split_reg_get_memo_list (GncTreeModelSplitReg *model);
GtkListStore * gnc_tree_model_split_reg_get_memo_list (GncTreeModelSplitReg *model);
GtkListStore *
gnc_tree_model_split_reg_get_numact_list (GncTreeModelSplitReg *model);
GtkListStore * gnc_tree_model_split_reg_get_numact_list (GncTreeModelSplitReg *model);
GtkListStore *
gnc_tree_model_split_reg_get_acct_list (GncTreeModelSplitReg *model);
GtkListStore * gnc_tree_model_split_reg_get_acct_list (GncTreeModelSplitReg *model);
void
gnc_tree_model_split_reg_get_num_list (GncTreeModelSplitReg *model);
void gnc_tree_model_split_reg_get_num_list (GncTreeModelSplitReg *model);
void
gnc_tree_model_split_reg_get_action_list (GncTreeModelSplitReg *model);
void gnc_tree_model_split_reg_get_action_list (GncTreeModelSplitReg *model);
void
gnc_tree_model_split_reg_update_completion (GncTreeModelSplitReg *model);
void gnc_tree_model_split_reg_update_completion (GncTreeModelSplitReg *model);
/* Get the split and transaction */
gboolean
gnc_tree_model_split_reg_get_split_and_trans (
GncTreeModelSplitReg *model, GtkTreeIter *iter,
gboolean *is_trow1, gboolean *is_trow2, gboolean *is_split,
gboolean *is_blank, Split **split, Transaction **trans);
gboolean gnc_tree_model_split_reg_get_split_and_trans (
GncTreeModelSplitReg *model, GtkTreeIter *iter,
gboolean *is_trow1, gboolean *is_trow2, gboolean *is_split,
gboolean *is_blank, Split **split, Transaction **trans);
/* Return FALSE if failure */
gboolean
gnc_tree_model_split_reg_set_blank_split_parent (
GncTreeModelSplitReg *model, Transaction *trans);
gboolean gnc_tree_model_split_reg_set_blank_split_parent (
GncTreeModelSplitReg *model, Transaction *trans, gboolean remove_only);
/* Return the blank split */
Split *
gnc_tree_model_split_get_blank_split (GncTreeModelSplitReg *model);
Split * gnc_tree_model_split_get_blank_split (GncTreeModelSplitReg *model);
/* Return the blank trans */
Transaction * gnc_tree_model_split_get_blank_trans (GncTreeModelSplitReg *model);
/* If 'trans' is NULL, use split's parent. If 'split' is NULL, just
get the transaction iter. */
gboolean
gnc_tree_model_split_reg_get_iter_from_trans_and_split (
GncTreeModelSplitReg *model, Transaction *trans, Split *split,
GtkTreeIter *iter1, GtkTreeIter *iter2);
gboolean gnc_tree_model_split_reg_get_iter_from_trans_and_split (
GncTreeModelSplitReg *model, Transaction *trans, Split *split,
GtkTreeIter *iter1, GtkTreeIter *iter2);
/* Return the row color for the view */
gchar * gnc_tree_model_split_reg_get_row_color (GncTreeModelSplitReg *model, gboolean is_trow1,
gboolean is_trow2, gboolean is_split, gint num);
/* Return TRUE if this transaction is read only for the view */
gboolean
gnc_tree_model_split_reg_get_read_only (GncTreeModelSplitReg *model, Transaction *trans);
/*FIXME this may not be required in the long run, return TRUE if this is a sub account view */
gboolean
gnc_tree_model_split_reg_get_sub_account (GncTreeModelSplitReg *model);
/* Return the tree path, if split and trans are null, last in list returned */
GtkTreePath *
gnc_tree_model_split_reg_get_path_to_split_and_trans (GncTreeModelSplitReg *model, Split *split, Transaction *trans);
GtkTreePath * gnc_tree_model_split_reg_get_path_to_split_and_trans (
GncTreeModelSplitReg *model, Split *split, Transaction *trans);
/* Returns TRUE if iter is a blank transaction */
gboolean gnc_tree_model_split_reg_is_blank_trans (GncTreeModelSplitReg *model, GtkTreeIter *iter);
/*****************************************************************************/
G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,8 @@
* gnc-tree-view-split-reg.h -- GtkTreeView implementation to *
* display registers in a GtkTreeView. *
* *
* Copyright (C) 2012 Robert Fewell *
* Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker@cox.net> *
* Copyright (C) 2012 Robert Fewell *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@ -48,14 +48,21 @@ typedef struct GncTreeViewSplitRegPrivate GncTreeViewSplitRegPrivate;
typedef struct
{
GncTreeView gnc_tree_view;
GncTreeView gnc_tree_view;
GncTreeViewSplitRegPrivate *priv;
int stamp;
int stamp;
GFunc moved_cb;
gpointer moved_cb_data;
GtkWidget *window; // Parent Window.
GFunc moved_cb; // Used for page gui update
gpointer moved_cb_data; // Used for page gui update
gchar *help_text;
gchar *help_text; // This is the help text to be displayed.
gint sort_depth; // This is the row the sort direction is based on.
gint sort_col; // This is the column the sort direction is based on.
gint sort_direction; // This is the direction of sort, 1 for ascending or -1 rest
gboolean reg_closing; // This is set when closing the register.
gboolean change_allowed; // This is set when we allow the reconciled split to change.
gboolean editing_now; // This is set while editing of a cell.
} GncTreeViewSplitReg;
@ -78,6 +85,7 @@ typedef enum {
SPLIT3, //3
}RowDepth;
/* Standard g_object type */
GType gnc_tree_view_split_reg_get_type (void);
@ -89,43 +97,49 @@ void gnc_tree_view_split_reg_default_selection (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_set_read_only (GncTreeViewSplitReg *view, gboolean read_only);
/*************************************************************************************/
void gnc_tree_view_split_reg_set_value_for (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input, gboolean force);
void gnc_tree_view_split_reg_set_dirty_trans (GncTreeViewSplitReg *view, Transaction *trans);
Transaction * gnc_tree_view_split_reg_get_current_trans (GncTreeViewSplitReg *view);
Split * gnc_tree_view_split_reg_get_current_split (GncTreeViewSplitReg *view);
Split * gnc_tree_view_split_reg_get_blank_split (GncTreeViewSplitReg *view);
Transaction * gnc_tree_view_split_reg_get_dirty_trans (GncTreeViewSplitReg *view);
Split * gnc_tree_view_reg_get_current_trans_split (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_set_current_path (GncTreeViewSplitReg *view, GtkTreePath *path);
GtkTreePath * gnc_tree_view_split_reg_get_current_path (GncTreeViewSplitReg *view);
RowDepth gnc_tree_view_reg_get_selected_row_depth (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_moved_cb (GncTreeViewSplitReg *view, GFunc cb, gpointer cb_data);
void gnc_tree_view_split_reg_refresh_from_gconf (GncTreeViewSplitReg *view);
GtkWidget * gnc_tree_view_split_reg_get_parent (GncTreeViewSplitReg *view);
gboolean gnc_tree_view_split_reg_trans_expanded (GncTreeViewSplitReg *view, Transaction *trans);
void gnc_tree_view_split_reg_expand_trans (GncTreeViewSplitReg *view, Transaction *trans);
void gnc_tree_view_split_reg_collapse_trans (GncTreeViewSplitReg *view, Transaction *trans);
/*************************************************************************************/
void gnc_tree_view_split_reg_delete_current_split (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_delete_current_trans (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_jump_to_blank (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_jump_to_split (GncTreeViewSplitReg *view, Split *split);
void gnc_tree_view_split_reg_reinit_trans (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_goto_rel_trans_row (GncTreeViewSplitReg *view, gint relative);
gboolean gnc_tree_view_split_reg_enter (GncTreeViewSplitReg *view);
gboolean gnc_tree_view_split_reg_current_trans_expanded (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_cancel_edit (GncTreeViewSplitReg *view, gboolean reg_closing);
Transaction * gnc_tree_view_split_reg_get_current_trans (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_finish_edit (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_cancel_edit (GncTreeViewSplitReg *view);
void gnc_tree_view_split_reg_expand_current_trans (GncTreeViewSplitReg *view, gboolean expand);
void gnc_tree_view_split_reg_moved_cb (GncTreeViewSplitReg *view, GFunc cb, gpointer cb_data);
void gnc_tree_view_split_reg_void_current_trans (GncTreeViewSplitReg *view, const char *reason);
void gnc_tree_view_split_reg_unvoid_current_trans (GncTreeViewSplitReg *view);
G_END_DECLS

View File

@ -111,6 +111,9 @@ typedef struct GncTreeViewPrivate
GtkWidget *column_menu;
gboolean show_column_menu;
/* Sort callback user_data */
gpointer sort_user_data;
/* Gconf related values */
gchar *gconf_section;
gboolean seen_gconf_visibility;
@ -235,6 +238,7 @@ gnc_tree_view_init (GncTreeView *view, GncTreeViewClass *klass)
priv = GNC_TREE_VIEW_GET_PRIVATE(view);
priv->column_menu = NULL;
priv->show_column_menu = FALSE;
priv->sort_user_data = NULL;
priv->gconf_section = NULL;
priv->seen_gconf_visibility = FALSE;
priv->columns_changed_cb_id = 0;
@ -954,6 +958,7 @@ gnc_tree_view_set_sort_column (GncTreeView *view,
if (!gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(s_model),
&current, &order))
order = GTK_SORT_ASCENDING;
g_signal_handler_block(s_model, priv->sort_column_changed_cb_id);
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
model_column, order);
@ -1053,6 +1058,7 @@ gnc_tree_view_gconf_changed (GConfClient *client,
priv = GNC_TREE_VIEW_GET_PRIVATE(view);
key = gconf_entry_get_key(entry);
value = gconf_entry_get_value(entry);
if (!value)
{
/* Values can be unset */
@ -1601,11 +1607,70 @@ void gnc_tree_view_expand_columns (GncTreeView *view,
va_end (args);
gtk_tree_view_column_set_visible (priv->spacer_column, !hide_spacer);
gtk_tree_view_column_set_visible (priv->selection_column, !hide_spacer);
LEAVE(" ");
}
/* Links the cell backgrounds of the two control columns to the model or
cell data function */
static void
update_control_cell_renderers_background (GncTreeView *view, GtkTreeViewColumn *col, gint column, GtkTreeCellDataFunc func )
{
GList *renderers;
GtkCellRenderer *cell;
GList *node;
renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (col));
/* Update the cell background in the list of renderers */
for (node = renderers; node; node = node->next)
{
cell = node->data;
if (func == NULL)
gtk_tree_view_column_add_attribute (col, cell, "cell-background", column);
else
gtk_tree_view_column_set_cell_data_func (col, cell, func, view, NULL);
}
g_list_free (renderers);
}
/* This function links the cell backgrounds of the two control columns to a column
in the model that has color strings or a cell data function */
void
gnc_tree_view_set_control_column_background (GncTreeView *view, gint column, GtkTreeCellDataFunc func )
{
GncTreeViewPrivate *priv;
g_return_if_fail (GNC_IS_TREE_VIEW (view));
ENTER("view %p, column %d, func %p", view, column, func);
priv = GNC_TREE_VIEW_GET_PRIVATE (view);
update_control_cell_renderers_background (view, priv->spacer_column, column, func);
update_control_cell_renderers_background (view, priv->selection_column, column, func);
LEAVE(" ");
}
/* This set the user_data value used in the sort callback */
void
gnc_tree_view_set_sort_user_data (GncTreeView *view, gpointer user_data)
{
GncTreeViewPrivate *priv;
g_return_if_fail (GNC_IS_TREE_VIEW (view));
ENTER("view %p, user_data %p", view, user_data);
priv = GNC_TREE_VIEW_GET_PRIVATE (view);
priv->sort_user_data = user_data;
LEAVE(" ");
}
/** This function is called to set the "show-column-menu" property on
* this view. This function has no visible effect if the
* "gconf-section" property has not been set.
@ -1838,7 +1903,14 @@ gnc_tree_view_column_properties (GncTreeView *view,
gtk_tree_view_column_set_sort_column_id (column, data_column);
if (column_sort_fn)
{
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(s_model),
priv = GNC_TREE_VIEW_GET_PRIVATE(view);
if (priv->sort_user_data != NULL)
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(s_model),
data_column, column_sort_fn,
priv->sort_user_data,
NULL /* destroy fn */);
else
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(s_model),
data_column, column_sort_fn,
GINT_TO_POINTER(data_column),
NULL /* destroy fn */);

View File

@ -383,10 +383,41 @@ void gnc_tree_view_set_gconf_section (GncTreeView *view,
*/
const gchar *gnc_tree_view_get_gconf_section (GncTreeView *view);
/** This function set the columns that will be allocated the free space
* in the view.
*
* @param view The tree view.
*
* @param list of column names.
*/
void gnc_tree_view_expand_columns (GncTreeView *view,
gchar *first_column_name,
...);
/** This function links the cell backgrounds of the two control columns
* to a column in the model that has color strings or a cell data function
* that sets the "cell-background" property.
*
* @param view The tree view.
*
* @param column The column in the model containg color strings.
*
* @param func This is a cell data function that sets the "cell-background".
*/
void
gnc_tree_view_set_control_column_background (GncTreeView *view, gint column,
GtkTreeCellDataFunc func);
/** This function sets the user_data value used in the sort callback
*
* @param view The tree view.
*
* @param user_data pointer to the user_data to be used.
*/
void
gnc_tree_view_set_sort_user_data (GncTreeView *view, gpointer user_data);
/** This function is called to set the "show-column-menu" property on
* this view. This function has no visible effect if the
* "gconf-section" property has not been set.

File diff suppressed because it is too large Load Diff

View File

@ -133,6 +133,14 @@ GNCSplitReg2 *
gnc_plugin_page_register2_get_gsr (GncPluginPage *plugin_page);
/** Get the GNCLedgerDisplay data structure associated with this register page.
*
* @param plugin_page A "register" page.
*/
GNCLedgerDisplay2 *
gnc_plugin_page_register2_get_ledger (GncPluginPage *plugin_page);
/** Get the Account associated with this register page.
*
* @param page A "register" page.

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
* Copyright (C) 1999-2000 Dave Peticolas <dave@krondo.com> *
* Copyright (C) 2001 Gnumatic, Inc. *
* Copyright (C) 2002,2006 Joshua Sled <jsled@asynchronous.org> *
* Copyright (C) 2012 Robert Fewell *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@ -95,24 +96,9 @@ struct _GNCSplitReg2Class
GtkVBoxClass parent_class;
/* Signal defaults */
void (*enter_ent_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*cancel_ent_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*delete_ent_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*reinit_ent_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*dup_ent_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*schedule_ent_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*expand_ent_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*blank_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*jump_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*cut_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*cut_txn_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*copy_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*copy_txn_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*paste_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*paste_txn_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*void_txn_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*unvoid_txn_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*reverse_txn_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*help_changed_cb) ( GNCSplitReg2 *w, gpointer user_data );
void (*include_date_cb) ( GNCSplitReg2 *w, time64 date, gpointer user_data );
};
@ -120,21 +106,8 @@ struct _GNCSplitReg2Class
#ifdef skip // Coming from original gnc-split-reg.h
typedef enum
{
ENTER,
CANCEL,
DELETE,
REINIT,
DUPLICATE,
SCHEDULE,
SPLIT,
BLANK,
JUMP,
CUT,
CUT_TXN,
COPY,
COPY_TXN,
PASTE,
PASTE_TXN,
SORT_ORDER_SUBMENU,
STYLE_SUBMENU,
} GNC_SPLIT_REG2_ITEM;
@ -212,13 +185,6 @@ void gnc_split_reg2_change_style (GNCSplitReg2 *gsr, SplitRegisterStyle2 style);
**/
GtkWidget *gnc_split_reg2_get_summarybar (GNCSplitReg2 *gsr );
/**
* These will manipulate the in-GNCSplitReg state-reflecting widgets as
* appropriate.
**/
void gnc_split_reg2_set_split_state (GNCSplitReg2 *gsr, gboolean split );
void gnc_split_reg2_set_double_line (GNCSplitReg2 *gsr, gboolean doubleLine );
void gnc_split_reg2_raise (GNCSplitReg2 *gsr );
/**
@ -228,13 +194,6 @@ void gnc_split_reg2_raise (GNCSplitReg2 *gsr );
**/
gboolean gnc_split_reg2_get_read_only (GNCSplitReg2 *gsr );
/*
* Function to jump to various places in the register
*/
void gnc_split_reg2_jump_to_blank (GNCSplitReg2 *gsr);
void gnc_split_reg2_jump_to_split (GNCSplitReg2 *gsr, Split *split);
void gnc_split_reg2_jump_to_split_amount (GNCSplitReg2 *gsr, Split *split);
/*
* Create a transaction entry with given amount and date. One account is
* specified, the other is undefined i.e. it defaults to orphan account.
@ -245,11 +204,6 @@ void gnc_split_reg2_jump_to_split_amount (GNCSplitReg2 *gsr, Split *split);
void gnc_split_reg2_balancing_entry (GNCSplitReg2 *gsr, Account *account,
time64 statement_date, gnc_numeric balancing_amount);
void gsr2_default_delete_handler (GNCSplitReg2 *gsr, gpointer data );
void gnc_split_reg2_enter (GNCSplitReg2 *gsr, gboolean next_transaction );
void gsr2_default_delete_handler (GNCSplitReg2 *gsr, gpointer data );
void gsr2_default_reinit_handler (GNCSplitReg2 *gsr, gpointer data );
void gsr2_default_expand_handler (GNCSplitReg2 *gsr, gpointer data );
void gsr2_default_schedule_handler (GNCSplitReg2 *gsr, gpointer data );
void gnc_split_reg2_set_moved_cb (GNCSplitReg2 *gsr, GFunc cb, gpointer cb_data );

View File

@ -4,6 +4,7 @@
* *
* Copyright (C) 1997 Robin D. Clark *
* Copyright (C) 1997, 1998 Linas Vepstas *
* Copyright (C) 2012 Robert Fewell *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@ -614,7 +615,7 @@ refresh_handler (GHashTable *changes, gpointer user_data)
*/
splits = qof_query_run (ld->query);
// gnc_ledger_display2_set_watches (ld, splits);
//FIXME Not Needed ? gnc_ledger_display2_set_watches (ld, splits);
gnc_ledger_display2_refresh_internal (ld, splits);
LEAVE(" ");
@ -625,9 +626,11 @@ close_handler (gpointer user_data)
{
GNCLedgerDisplay2 *ld = user_data;
ENTER(" ");
if (!ld)
return;
//g_print("ledger close_handler\n");
gnc_unregister_gui_component (ld->component_id);
if (ld->destroy)
@ -640,6 +643,7 @@ close_handler (gpointer user_data)
qof_query_destroy (ld->query);
ld->query = NULL;
LEAVE(" ");
g_free (ld);
}
@ -822,12 +826,12 @@ gnc_ledger_display2_internal (Account *lead_account, Query *q,
gnc_tree_model_split_reg_set_data (ld->model, ld, gnc_ledger_display2_parent);
g_signal_connect (G_OBJECT (ld->model), "refresh_signal",
G_CALLBACK ( gnc_ledger_display2_refresh_cb ), ld );
//FIXME Not Needed ? g_signal_connect (G_OBJECT (ld->model), "refresh_signal",
// G_CALLBACK ( gnc_ledger_display2_refresh_cb ), ld );
splits = qof_query_run (ld->query);
// gnc_ledger_display2_set_watches (ld, splits);
//FIXME Not Needed ? gnc_ledger_display2_set_watches (ld, splits);
gnc_ledger_display2_refresh_internal (ld, splits);
@ -880,10 +884,6 @@ gnc_ledger_display2_find_by_query (Query *q)
static void
gnc_ledger_display2_refresh_internal (GNCLedgerDisplay2 *ld, GList *splits)
{
GtkTreeModel *smodel, *model;
g_print("gnc_ledger_display2_refresh_internal ledger %p and splits %p\n", ld, splits);
if (!ld || ld->loading)
return;
@ -896,32 +896,10 @@ g_print("gnc_ledger_display2_refresh_internal ledger %p and splits %p\n", ld, sp
else
{
ld->loading = TRUE;
/*FIXME All this may not be required !!!!! */
smodel = gtk_tree_view_get_model (GTK_TREE_VIEW (ld->view)); // this is the sort model
model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (smodel)); // our model
//g_print("view is %p model is %p and smodel is %p\n", ld->view, model, smodel);
g_object_ref (smodel);
g_object_ref (model);
gnc_tree_view_split_reg_block_selection (ld->view, TRUE); // This blocks the tree selection
gtk_tree_view_set_model (GTK_TREE_VIEW (ld->view), NULL); // Detach sort model from view
gnc_tree_model_split_reg_load (ld->model, splits, gnc_ledger_display2_leader (ld)); //reload splits
//Not needed smodel = gtk_tree_model_sort_new_with_model (model); // create new sort model
gtk_tree_view_set_model (GTK_TREE_VIEW(ld->view), GTK_TREE_MODEL (smodel)); // Re-attach sort model to view
//g_print("view is %p model is %p and smodel is %p\n", ld->view, model, smodel);
gnc_tree_view_split_reg_block_selection (ld->view, FALSE); // This unblocks the tree selection
/* Set the default selection start position */
gnc_tree_view_split_reg_default_selection (ld->view);
g_object_unref (model);
g_object_unref (smodel);
ld->loading = FALSE;
}
}
@ -1001,7 +979,6 @@ static void
gnc_ledger_display2_refresh_cb (GncTreeModelSplitReg *model, gpointer user_data)
{
GNCLedgerDisplay2 *ld = user_data;
//g_print("refresh model %p user_data %p\n", model, user_data);
/* Refresh the view when idle */
g_idle_add ((GSourceFunc)gnc_ledger_display2_refresh, ld);
@ -1013,6 +990,6 @@ gnc_ledger_display2_close (GNCLedgerDisplay2 *ld)
{
if (!ld)
return;
//g_print("gnc_ledger_display2_close\n");
gnc_close_gui_component (ld->component_id);
}

View File

@ -5,6 +5,7 @@
* Copyright (C) 1997 Robin D. Clark *
* Copyright (C) 1997, 1998 Linas Vepstas *
* Copyright (C) 2001 Linux Developers Group *
* Copyright (C) 2012 Robert Fewell *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *