mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
updates from Rob Browning
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@886 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
f17dc96166
commit
e3facf3f20
@ -42,7 +42,8 @@ OTHER_OBJS := ../obj/gnome/*.o ../engine/obj/*.o ../register/obj/gnome/*.o
|
||||
|
||||
######################################################################
|
||||
# See Makefile.common for information about these variables.
|
||||
GNOME_SRCS := main.c MainWindow.c MenuBar.c RegWindow.c Dialogs.c
|
||||
GNOME_SRCS := main.c MainWindow.c MenuBar.c RegWindow.c Dialogs.c xtutil.c \
|
||||
RecnWindow.c
|
||||
# AccWindow.c AccountMenu.c AdjBWindow.c \
|
||||
# BuildMenu.c Destroy.c FileBox.c HelpWindow.c \
|
||||
# RecnWindow.c RegWindow.c Reports.c TextBox.c \
|
||||
|
631
src/gnome/RecnWindow.c
Normal file
631
src/gnome/RecnWindow.c
Normal file
@ -0,0 +1,631 @@
|
||||
/********************************************************************\
|
||||
* RecnWindow.c -- the reconcile window *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* *
|
||||
* 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, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <gnome.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "Account.h"
|
||||
#include "date.h"
|
||||
#include "Group.h"
|
||||
#include "RecnWindow.h"
|
||||
#include "RegWindow.h"
|
||||
#include "MainWindow.h"
|
||||
#include "messages.h"
|
||||
#include "util.h"
|
||||
//#include "xtutil.h"
|
||||
|
||||
/** STRUCTS *********************************************************/
|
||||
struct _RecnWindow
|
||||
{
|
||||
Account *acc; /* The account that we are reconciling */
|
||||
double ddiff; /* The amount to reconcile */
|
||||
GtkWidget *dialog; /* The reconcile window dialog */
|
||||
GtkWidget *difference; /* Text field, amount left to reconcile */
|
||||
GtkWidget *totDebit; /* Text field, total debit reconciled */
|
||||
GtkWidget *totCredit; /* Text field, total credit reconciled */
|
||||
GtkWidget *debit; /* Debit matrix show unreconciled debit */
|
||||
GtkWidget *credit; /* Credit matrix, shows credits... */
|
||||
char * symbol; /* Currency symbol or 's' for shares */
|
||||
};
|
||||
|
||||
/** PROTOTYPES ******************************************************/
|
||||
static void recnRecalculateBalance( RecnWindow *recnData );
|
||||
|
||||
static void recnClose(GtkWidget *w, gpointer data);
|
||||
static void recnOkCB(GtkWidget *w, gpointer data);
|
||||
static void recnCancelCB(GtkWidget *w, gpointer data);
|
||||
static void recnCB(GtkWidget *w, gpointer data);
|
||||
|
||||
/** GLOBALS *********************************************************/
|
||||
|
||||
static RecnWindow **recnList = NULL;
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/********************************************************************\
|
||||
* recnRefresh *
|
||||
* refreshes the transactions in the reconcile window *
|
||||
* *
|
||||
* Args: recnData -- the reconcile window to refresh *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
recnRefresh(Account *acc)
|
||||
{
|
||||
int i;
|
||||
Split *split;
|
||||
RecnWindow *recnData;
|
||||
GList *debit_items = NULL;
|
||||
GList *credit_items = NULL;
|
||||
|
||||
FIND_IN_LIST (RecnWindow, recnList, acc, acc, recnData);
|
||||
if(!recnData) return;
|
||||
|
||||
/* Build lists of the non-reconciled transactions */
|
||||
i=0;
|
||||
split = xaccAccountGetSplit(acc, i);
|
||||
while(split)
|
||||
{
|
||||
char *item_str = NULL;
|
||||
Transaction *trans = xaccSplitGetParent (split);
|
||||
const char split_recn = xaccSplitGetReconcile(split);
|
||||
|
||||
if( YREC != split_recn)
|
||||
{
|
||||
double themount;
|
||||
int acc_type;
|
||||
|
||||
/* for stock accounts, show share quantity,
|
||||
* not currency amount */
|
||||
acc_type = xaccAccountGetType (acc);
|
||||
if((STOCK == acc_type) || (MUTUAL == acc_type)) {
|
||||
themount = xaccSplitGetShareAmount (split);
|
||||
} else {
|
||||
themount = xaccSplitGetValue (split);
|
||||
}
|
||||
|
||||
asprintf(&item_str, "%c %s %s %s %.2f",
|
||||
split_recn,
|
||||
xaccTransGetNum(trans),
|
||||
xaccTransGetDateStr(trans),
|
||||
xaccTransGetDescription(trans),
|
||||
DABS(themount));
|
||||
|
||||
{
|
||||
GtkWidget *list_item = gtk_list_item_new();
|
||||
GtkWidget *check_button = gtk_check_button_new_with_label(item_str);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(check_button), "toggled",
|
||||
recnCB, (gpointer) recnData);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(list_item), check_button);
|
||||
gtk_widget_show(list_item);
|
||||
gtk_widget_show(check_button);
|
||||
|
||||
gtk_object_set_user_data(GTK_OBJECT(check_button), (gpointer) split);
|
||||
|
||||
if(themount < 0)
|
||||
{
|
||||
fprintf(stderr, "Adding debit: %s\n", item_str);
|
||||
debit_items = g_list_append(debit_items, (gpointer) list_item);
|
||||
} else {
|
||||
fprintf(stderr, "Adding credit: %s\n", item_str);
|
||||
credit_items = g_list_append(credit_items, (gpointer) list_item);
|
||||
}
|
||||
|
||||
free(item_str);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
split = xaccAccountGetSplit (acc, i);
|
||||
}
|
||||
|
||||
/* NOTE: an improvement of the current design would be to use the
|
||||
* user-data in the rows to detect where transactions need
|
||||
* to be inserted/delete, instead of deleting and re-inserting
|
||||
* all the transactions! */
|
||||
|
||||
/* Delete all the entries in the debit and credit matrices */
|
||||
gtk_list_clear_items(GTK_LIST(recnData->debit), 0, -1);
|
||||
gtk_list_clear_items(GTK_LIST(recnData->credit), 0, -1);
|
||||
|
||||
/* the gtk list becomes the owner of the item lists, so don't free */
|
||||
gtk_list_append_items(GTK_LIST(recnData->debit), debit_items);
|
||||
gtk_list_append_items(GTK_LIST(recnData->credit), credit_items);
|
||||
|
||||
recnRecalculateBalance(recnData);
|
||||
}
|
||||
|
||||
static void
|
||||
recn_recalc_share_balance_helper(gpointer item, gpointer data) {
|
||||
double *total = (double *) data;
|
||||
GtkListItem *li = GTK_LIST_ITEM(item);
|
||||
GtkCheckButton *checkbutton = GTK_CHECK_BUTTON(li->item.bin.child);
|
||||
Split *split = gtk_object_get_user_data(GTK_OBJECT(checkbutton));
|
||||
const char recn = xaccSplitGetReconcile(split);
|
||||
|
||||
if(GTK_TOGGLE_BUTTON(checkbutton)->active) {
|
||||
*total += xaccSplitGetShareAmount(split);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recn_recalc_non_share_balance_helper(gpointer item, gpointer data) {
|
||||
double *total = (double *) data;
|
||||
GtkListItem *li = GTK_LIST_ITEM(item);
|
||||
GtkCheckButton *checkbutton = GTK_CHECK_BUTTON(li->item.bin.child);
|
||||
Split *split = gtk_object_get_user_data(GTK_OBJECT(checkbutton));
|
||||
const char recn = xaccSplitGetReconcile(split);
|
||||
|
||||
if(GTK_TOGGLE_BUTTON(checkbutton)->active) {
|
||||
*total += xaccSplitGetValue(split);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* recnRecalculateBalance *
|
||||
* refreshes the balances in the reconcile window *
|
||||
* *
|
||||
* Args: recnData -- the reconcile window to refresh *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
static void
|
||||
recnRecalculateBalance(RecnWindow *recnData)
|
||||
{
|
||||
Account *acc = recnData ->acc;
|
||||
char *amt;
|
||||
double ddebit = 0.0;
|
||||
double dcredit = 0.0;
|
||||
double ddiff = 0.0;
|
||||
short shrs = 0;
|
||||
int acc_type;
|
||||
|
||||
acc_type = xaccAccountGetType (acc);
|
||||
if ((STOCK == acc_type) || (MUTUAL == acc_type)) shrs = 1;
|
||||
|
||||
/* Calculate the total debit: */
|
||||
ddebit = 0.0;
|
||||
|
||||
{
|
||||
const GFunc func = (shrs) ?
|
||||
(GFunc) recn_recalc_share_balance_helper :
|
||||
(GFunc) recn_recalc_non_share_balance_helper;
|
||||
|
||||
/* Calculate the total debit and credit */
|
||||
g_list_foreach(GTK_LIST(recnData->debit)->children, func, &ddebit);
|
||||
g_list_foreach(GTK_LIST(recnData->credit)->children, func, &dcredit);
|
||||
}
|
||||
|
||||
shrs *= PRTSHR;
|
||||
shrs |= PRTSYM;
|
||||
|
||||
/* Update the difference field, and the total fields */
|
||||
amt = xaccPrintAmount(DABS(ddebit), shrs);
|
||||
{
|
||||
char *str = NULL;
|
||||
asprintf(&str, "%s %s", DEBITS_C_STR, amt);
|
||||
gtk_frame_set_label(GTK_FRAME(recnData->totDebit), str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
amt = xaccPrintAmount(dcredit, shrs);
|
||||
{
|
||||
char *str = NULL;
|
||||
asprintf(&str, "%s %s", CREDITS_C_STR, amt);
|
||||
gtk_frame_set_label(GTK_FRAME(recnData->totCredit), str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
ddiff = recnData->ddiff + dcredit + ddebit;
|
||||
amt = xaccPrintAmount(ddiff, shrs);
|
||||
gtk_label_set(GTK_LABEL(recnData->difference), amt);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* startRecnWindow: gets the ending balance for reconcile window *
|
||||
\********************************************************************/
|
||||
static void
|
||||
startRecnOkCB(GtkWidget *w, gpointer data)
|
||||
{
|
||||
*((int *) data) = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
startRecnCancelCB(GtkWidget *w, gpointer data)
|
||||
{
|
||||
*((int *) data) = 0;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* startRecnWindow *
|
||||
* opens up the window to prompt the user to enter the ending *
|
||||
* balance from bank statement *
|
||||
* *
|
||||
* NOTE: This dialog does not return until the user presses "Ok" *
|
||||
* or "Cancel" *
|
||||
* *
|
||||
* Args: parent - the parent of this window *
|
||||
* acc - the account to reconcile *
|
||||
* diff - returns the amount from ending balance field *
|
||||
* Return: True, if the user presses "Ok", else False *
|
||||
* Global: app - the app context *
|
||||
\********************************************************************/
|
||||
gboolean
|
||||
startRecnWindow(GtkWidget *parent, Account *acc, double *diff)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
char * amt;
|
||||
double dendBalance;
|
||||
int result;
|
||||
short shrs = 0;
|
||||
int acc_type;
|
||||
char *title = NULL;
|
||||
|
||||
setBusyCursor(parent);
|
||||
|
||||
/* Get the previous ending balance. Use the published
|
||||
* account interface for this, since the ending balance
|
||||
* may have to be adjusted for stock price fluctuations.
|
||||
*/
|
||||
dendBalance = xaccAccountGetReconciledBalance(acc);
|
||||
|
||||
acc_type = xaccAccountGetType(acc);
|
||||
if((STOCK == acc_type) || (MUTUAL == acc_type)) shrs = 1;
|
||||
|
||||
shrs *= PRTSHR;
|
||||
shrs |= PRTSYM;
|
||||
amt = xaccPrintAmount (dendBalance, shrs);
|
||||
|
||||
/* Create the dialog box... */
|
||||
asprintf(&title, "%s: %s", xaccAccountGetName(acc), RECONCILE_STR);
|
||||
|
||||
dialog = gnome_dialog_new(title,
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_CANCEL,
|
||||
GNOME_STOCK_BUTTON_HELP,
|
||||
NULL);
|
||||
free(title);
|
||||
|
||||
gnome_dialog_set_modal(GNOME_DIALOG(dialog));
|
||||
gnome_dialog_set_default(GNOME_DIALOG(dialog), 1);
|
||||
gnome_dialog_set_close(GNOME_DIALOG(dialog), FALSE);
|
||||
gnome_dialog_close_hides(GNOME_DIALOG(dialog), FALSE);
|
||||
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(dialog), 0,
|
||||
GTK_SIGNAL_FUNC(startRecnOkCB),
|
||||
(gpointer) &result);
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(dialog), 1,
|
||||
GTK_SIGNAL_FUNC(startRecnCancelCB),
|
||||
(gpointer) &result);
|
||||
|
||||
fprintf(stderr, "Not implemented: helpMenubarCB\n");
|
||||
/*
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(dialog), 2,
|
||||
GTK_SIGNAL_FUNC(helpMenubarCB),
|
||||
(gpointer) HMB_RECNWIN);
|
||||
*/
|
||||
|
||||
{
|
||||
GtkWidget *main_area = gtk_hbox_new(TRUE, 0);
|
||||
GtkWidget *left_column = gtk_vbox_new(FALSE, 0);
|
||||
GtkWidget *right_column = gtk_vbox_new(FALSE, 0);
|
||||
GtkWidget *prev_title = gtk_label_new(PREV_BALN_C_STR);
|
||||
GtkWidget *end_title = gtk_label_new(END_BALN_C_STR);
|
||||
GtkWidget *prev_value = gtk_label_new(amt);
|
||||
GtkWidget *end_value = gtk_entry_new();
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), main_area,
|
||||
TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(main_area), left_column, TRUE, TRUE, 0);
|
||||
gtk_box_pack_end(GTK_BOX(main_area), right_column, TRUE, TRUE, 0);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(left_column), prev_title, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(left_column), end_title, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(right_column), prev_value, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(right_column), end_value, TRUE, TRUE, 0);
|
||||
|
||||
gtk_widget_show(main_area);
|
||||
gtk_widget_show(left_column);
|
||||
gtk_widget_show(right_column);
|
||||
gtk_widget_show(prev_title);
|
||||
gtk_widget_show(end_title);
|
||||
gtk_widget_show(prev_value);
|
||||
gtk_widget_show(end_value);
|
||||
gtk_widget_show(dialog);
|
||||
|
||||
unsetBusyCursor(parent);
|
||||
|
||||
|
||||
result = -1;
|
||||
while(result == -1) {
|
||||
while(result == -1) {
|
||||
gtk_main_iteration();
|
||||
}
|
||||
|
||||
/* Get the amount from the "end-balance" field */
|
||||
{
|
||||
gchar *str = gtk_entry_get_text(GTK_ENTRY(end_value));
|
||||
double val=0.0;
|
||||
|
||||
if(result == 1) {
|
||||
if(sscanf(str, "%lf", &val ) == 1) {
|
||||
*diff = dendBalance - val;
|
||||
} else {
|
||||
errorBox(dialog, "Ending balance must be a number.");
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gnome_dialog_close(dialog);
|
||||
}
|
||||
fprintf(stderr, "Returning result: %d\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* recnWindow *
|
||||
* opens up the window to reconcile an account *
|
||||
* *
|
||||
* Args: parent - the parent of this window *
|
||||
* account - the account to reconcile *
|
||||
* Return: recnData - the instance of this RecnWindow *
|
||||
\********************************************************************/
|
||||
RecnWindow *
|
||||
recnWindow(GtkWidget *parent, Account *acc)
|
||||
{
|
||||
int position;
|
||||
RecnWindow *recnData;
|
||||
double ddiff;
|
||||
gchar *title = NULL;
|
||||
|
||||
/* Popup a little window to prompt the user to enter the
|
||||
* ending balance for his/her bank statement */
|
||||
if(!startRecnWindow(parent,acc,&ddiff) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FETCH_FROM_LIST(RecnWindow, recnList, acc, acc, recnData);
|
||||
|
||||
setBusyCursor(parent);
|
||||
|
||||
recnData->ddiff = ddiff;
|
||||
|
||||
asprintf(&title, "%s: %s", xaccAccountGetName (acc), RECONCILE_STR);
|
||||
|
||||
recnData->dialog = gnome_dialog_new(title,
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_CANCEL,
|
||||
GNOME_STOCK_BUTTON_HELP,
|
||||
NULL);
|
||||
free(title);
|
||||
|
||||
/* here we connect the "destroy" event to a signal handler.
|
||||
* This event occurs when we call gtk_widget_destroy() on the window,
|
||||
* or if we return 'FALSE' in the "delete_event" callback. */
|
||||
gtk_signal_connect (GTK_OBJECT (recnData->dialog), "destroy",
|
||||
GTK_SIGNAL_FUNC(recnClose), (gpointer) recnData);
|
||||
|
||||
|
||||
gnome_dialog_set_modal(GNOME_DIALOG(recnData->dialog));
|
||||
gnome_dialog_set_default(GNOME_DIALOG(recnData->dialog), 1);
|
||||
gnome_dialog_set_close(GNOME_DIALOG(recnData->dialog), FALSE);
|
||||
gnome_dialog_close_hides(GNOME_DIALOG(recnData->dialog), FALSE);
|
||||
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(recnData->dialog), 0,
|
||||
GTK_SIGNAL_FUNC(recnOkCB),
|
||||
(gpointer) recnData);
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(recnData->dialog), 1,
|
||||
GTK_SIGNAL_FUNC(recnCancelCB),
|
||||
(gpointer) recnData);
|
||||
|
||||
fprintf(stderr, "Not implemented: helpMenubarCB\n");
|
||||
/*
|
||||
XtAddCallback( widget, XmNactivateCallback,
|
||||
helpMenubarCB, (XtPointer)HMB_RECNWIN );
|
||||
*/
|
||||
|
||||
//String labels[] = {"", NUM_STR, DATE_STR, DESC_STR, AMT_STR };
|
||||
//unsigned char alignments[] = {XmALIGNMENT_CENTER,
|
||||
// XmALIGNMENT_END,
|
||||
// XmALIGNMENT_CENTER,
|
||||
// XmALIGNMENT_BEGINNING,
|
||||
// XmALIGNMENT_END};
|
||||
|
||||
{
|
||||
GtkWidget *main_area = gtk_vbox_new(FALSE, 0);
|
||||
GtkWidget *debcred_area = gtk_hbox_new(TRUE, 0);
|
||||
GtkWidget *debits_frame = gtk_frame_new(DEBITS_C_STR);
|
||||
GtkWidget *credits_frame = gtk_frame_new(CREDITS_C_STR);
|
||||
GtkWidget *debits_list = gtk_list_new();
|
||||
GtkWidget *credits_list = gtk_list_new();
|
||||
|
||||
GtkWidget *difference_align = gtk_alignment_new(0.5, 0.5, 0, 0);
|
||||
GtkWidget *difference_box = gtk_hbox_new(FALSE, 0);
|
||||
GtkWidget *difference_label = gtk_label_new(DIFF_C_STR);
|
||||
GtkWidget *difference_value = gtk_label_new("");
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(recnData->dialog)->vbox),
|
||||
main_area, TRUE, TRUE, 0);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(main_area), debcred_area, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(debcred_area), debits_frame, TRUE, TRUE, 0);
|
||||
gtk_box_pack_end(GTK_BOX(debcred_area), credits_frame, TRUE, TRUE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(debits_frame), debits_list);
|
||||
gtk_container_add(GTK_CONTAINER(credits_frame), credits_list);
|
||||
|
||||
gtk_box_pack_end(GTK_BOX(main_area), difference_align, TRUE, TRUE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(difference_align), difference_box);
|
||||
gtk_box_pack_start(GTK_BOX(difference_box), difference_label,
|
||||
TRUE, TRUE, 0);
|
||||
gtk_box_pack_end(GTK_BOX(difference_box), difference_value,
|
||||
TRUE, TRUE, 0);
|
||||
|
||||
recnData->debit = debits_list;
|
||||
recnData->totDebit = debits_frame;
|
||||
recnData->credit = credits_list;
|
||||
recnData->totCredit = credits_frame;
|
||||
recnData->difference = difference_value;
|
||||
|
||||
gtk_widget_show(main_area);
|
||||
gtk_widget_show(debcred_area);
|
||||
gtk_widget_show(debits_frame);
|
||||
gtk_widget_show(credits_frame);
|
||||
gtk_widget_show(debits_list);
|
||||
gtk_widget_show(credits_list);
|
||||
gtk_widget_show(difference_align);
|
||||
gtk_widget_show(difference_box);
|
||||
gtk_widget_show(difference_label);
|
||||
gtk_widget_show(difference_value);
|
||||
gtk_widget_show(recnData->dialog);
|
||||
}
|
||||
|
||||
/* now that the matices are set up, fill 'em in with transactions: */
|
||||
recnRefresh (acc);
|
||||
|
||||
/* and then refresh the total/difference balance fields: */
|
||||
recnRecalculateBalance(recnData);
|
||||
|
||||
unsetBusyCursor(parent);
|
||||
|
||||
return recnData;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
* Don't delete any structures -- the close callback will handle this *
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccDestroyRecnWindow(Account *acc)
|
||||
{
|
||||
RecnWindow *recnData;
|
||||
|
||||
FIND_IN_LIST(RecnWindow, recnList, acc, acc, recnData);
|
||||
if(!recnData) return;
|
||||
gnome_dialog_close(recnData->dialog);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
* recnClose *
|
||||
* frees memory allocated for an recnWindow, and other cleanup *
|
||||
* stuff *
|
||||
* *
|
||||
* Args: mw - the widget that called us *
|
||||
* cd - recnData - the data struct for this window *
|
||||
* cb - *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
static void
|
||||
recnClose(GtkWidget *w, gpointer data)
|
||||
{
|
||||
RecnWindow *recnData = (RecnWindow *) data;
|
||||
Account *acc = recnData->acc;
|
||||
|
||||
REMOVE_FROM_LIST (RecnWindow, recnList, acc, acc);
|
||||
free(recnData);
|
||||
|
||||
DEBUG("closed RecnWindow");
|
||||
}
|
||||
|
||||
static void
|
||||
recn_ok_cb_set_reconciled_helper(gpointer item, gpointer data) {
|
||||
double *total = (double *) data;
|
||||
GtkListItem *li = GTK_LIST_ITEM(item);
|
||||
GtkCheckButton *checkbutton = GTK_CHECK_BUTTON(li->item.bin.child);
|
||||
Split *split = gtk_object_get_user_data(GTK_OBJECT(checkbutton));
|
||||
const char recn = xaccSplitGetReconcile(split);
|
||||
|
||||
if(GTK_TOGGLE_BUTTON(checkbutton)->active) {
|
||||
xaccSplitSetReconcile (split, YREC);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* recnOkCB *
|
||||
* saves account stuff, when the user clicks "Ok" *
|
||||
* *
|
||||
* Args: mw - the widget that called us *
|
||||
* cd - recnData - the data struct for this window *
|
||||
* cb - *
|
||||
* Return: none *
|
||||
* Global: data *
|
||||
\********************************************************************/
|
||||
static void
|
||||
recnOkCB(GtkWidget *w, gpointer data)
|
||||
{
|
||||
RecnWindow *recnData = (RecnWindow *) data;
|
||||
|
||||
/* Update the debit and credit transactions reconciled state */
|
||||
g_list_foreach(GTK_LIST(recnData->debit)->children,
|
||||
recn_ok_cb_set_reconciled_helper, NULL);
|
||||
g_list_foreach(GTK_LIST(recnData->credit)->children,
|
||||
recn_ok_cb_set_reconciled_helper, NULL);
|
||||
|
||||
/* refresh the register window */
|
||||
accRefresh(recnData->acc);
|
||||
|
||||
gnome_dialog_close(recnData->dialog);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
recnCancelCB(GtkWidget *w, gpointer data)
|
||||
{
|
||||
RecnWindow *recnData = (RecnWindow *) data;
|
||||
fprintf(stderr, "X\n");
|
||||
gnome_dialog_close(recnData->dialog);
|
||||
fprintf(stderr, "Y\n");
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* recnCB *
|
||||
* called whenever the users does anything in the debit/credit *
|
||||
* matrices *
|
||||
* *
|
||||
* Args: mw - the matrix widget that called us *
|
||||
* cd - recnData - the data struct for this window *
|
||||
* cb - *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
static void
|
||||
recnCB(GtkWidget *w, gpointer data)
|
||||
{
|
||||
RecnWindow *recnData = (RecnWindow *) data;
|
||||
|
||||
/* recalculate the total/difference balance fields: */
|
||||
recnRecalculateBalance(recnData);
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
tab-width: 2
|
||||
indent-tabs-mode: nil
|
||||
eval: (c-set-style "gnu")
|
||||
End:
|
||||
*/
|
50
src/gnome/RecnWindow.h
Normal file
50
src/gnome/RecnWindow.h
Normal file
@ -0,0 +1,50 @@
|
||||
/********************************************************************\
|
||||
* RecnWindow.h -- the reconcile window *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* *
|
||||
* 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, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __RECONCILE_H__
|
||||
#define __RECONCILE_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "Account.h"
|
||||
|
||||
/** GLOBALS *********************************************************/
|
||||
|
||||
/** STRUCTS *********************************************************/
|
||||
typedef struct _RecnWindow RecnWindow;
|
||||
|
||||
/** PROTOTYPES ******************************************************/
|
||||
void recnRefresh(Account *account);
|
||||
RecnWindow *recnWindow(GtkWidget *parent, Account *account);
|
||||
|
||||
/*
|
||||
* The xaccDestroyRecnWindow() subroutine can be called from
|
||||
* anywhere to shut down the Register window. Used primarily when
|
||||
* destroying the underlying account.
|
||||
*/
|
||||
void xaccDestroyRecnWindow(Account *);
|
||||
|
||||
#endif
|
@ -34,6 +34,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "Account.h"
|
||||
#include "AccountP.h"
|
||||
//#include "AdjBWindow.h"
|
||||
//#include "BuildMenu.h"
|
||||
#include "Group.h"
|
||||
@ -42,7 +43,7 @@
|
||||
#include "MainWindow.h"
|
||||
#include "main.h"
|
||||
#include "messages.h"
|
||||
//#include "RecnWindow.h"
|
||||
#include "RecnWindow.h"
|
||||
#include "RegWindow.h"
|
||||
#include "Transaction.h"
|
||||
#include "util.h"
|
||||
@ -65,7 +66,6 @@ struct _RegWindow {
|
||||
/* display widgets */
|
||||
GtkWidget * dialog;
|
||||
GtkWidget * reg; /* The matrix widget... */
|
||||
GtkWidget * balance; /* The balance text field */
|
||||
GtkWidget * record; /* the record transaction button */
|
||||
|
||||
};
|
||||
@ -85,13 +85,14 @@ void regRefresh (RegWindow *regData);
|
||||
|
||||
static void closeRegWindow(GtkWidget * mw, gpointer data);
|
||||
|
||||
static void startRecnCB(GtkWidget *w, gpointer data);
|
||||
static void deleteCB(GtkWidget *w, gpointer data);
|
||||
static void recordCB(GtkWidget *w, gpointer data);
|
||||
static void cancelCB(GtkWidget *w, gpointer data);
|
||||
|
||||
#if 0
|
||||
|
||||
static void startRecnCB( GtkWidget * mw, XtPointer cd, XtPointer cb );
|
||||
static void startAdjBCB( GtkWidget * mw, XtPointer cd, XtPointer cb );
|
||||
static void recordCB( GtkWidget * mw, XtPointer cd, XtPointer cb );
|
||||
static void deleteCB( GtkWidget * mw, XtPointer cd, XtPointer cb );
|
||||
static void cancelCB( GtkWidget * mw, XtPointer cd, XtPointer cb );
|
||||
|
||||
#endif
|
||||
|
||||
@ -187,9 +188,9 @@ ledgerIsMember (RegWindow *reg, Account * acc) {
|
||||
\********************************************************************/
|
||||
RegWindow *
|
||||
regWindowSimple(Account *acc) {
|
||||
RegWindow *retval;
|
||||
RegWindow *retval = (RegWindow *) 1; /* for error case later */
|
||||
int acc_type;
|
||||
int reg_type;
|
||||
int reg_type = 0;
|
||||
|
||||
acc_type = xaccAccountGetType (acc);
|
||||
|
||||
@ -223,9 +224,14 @@ regWindowSimple(Account *acc) {
|
||||
case EQUITY:
|
||||
reg_type = EQUITY_REGISTER;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"regWindowSimple: Unknown account type (serious error)\n");
|
||||
retval = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
retval = regWindowLedger (acc, NULL, reg_type);
|
||||
if(retval) retval = regWindowLedger (acc, NULL, reg_type);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -337,11 +343,11 @@ RegWindow *
|
||||
regWindowLedger(Account *lead_acc, Account **acclist, int ledger_type)
|
||||
{
|
||||
RegWindow *regData = NULL;
|
||||
//GtkWidget * menubar, pane, buttonform, frame, reg, widget;
|
||||
GtkWidget *reg = NULL;
|
||||
int position=0;
|
||||
char *windowname;
|
||||
//char buf [BUFSIZE];
|
||||
GtkWidget *register_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
GtkWidget *register_vbox = gtk_vbox_new(FALSE, 0);
|
||||
GtkWidget *table_frame = gtk_frame_new(NULL);
|
||||
|
||||
fprintf(stderr, "regWindowLedger(%p, %p, %d)\n",
|
||||
lead_acc, acclist, ledger_type);
|
||||
@ -452,13 +458,13 @@ regWindowLedger(Account *lead_acc, Account **acclist, int ledger_type)
|
||||
switch (regData->type) {
|
||||
case GENERAL_LEDGER:
|
||||
case INCOME_LEDGER:
|
||||
asprintf(&windowname, "%s General Ledger", acc_name);
|
||||
asprintf(&windowname, "%s (general ledger)", acc_name);
|
||||
break;
|
||||
case PORTFOLIO:
|
||||
asprintf(&windowname, "%s Portfolio", acc_name);
|
||||
asprintf(&windowname, "%s (portfolio)", acc_name);
|
||||
break;
|
||||
default:
|
||||
asprintf(&windowname, "%s Register", acc_name);
|
||||
asprintf(&windowname, "%s (register)", acc_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -467,11 +473,17 @@ regWindowLedger(Account *lead_acc, Account **acclist, int ledger_type)
|
||||
assert(windowname);
|
||||
|
||||
//setBusyCursor(parent);
|
||||
|
||||
regData->dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(register_vbox), table_frame, TRUE, TRUE, 0);
|
||||
regData->dialog = table_frame;
|
||||
|
||||
///* Initialize callbacks */
|
||||
//gtk_signal_connect(GTK_OBJECT(toolBar[exit]), "clicked",
|
||||
// GTK_SIGNAL_FUNC (file_cmd_quit), NULL);
|
||||
|
||||
gtk_window_set_title(GTK_WINDOW(regData->dialog), windowname);
|
||||
|
||||
|
||||
gtk_window_set_title(GTK_WINDOW(register_window), windowname);
|
||||
|
||||
/* when the window is given the "delete_event" signal (this is given
|
||||
* by the window manager (usually the 'close' option, or on the
|
||||
@ -735,7 +747,56 @@ regWindowLedger(Account *lead_acc, Account **acclist, int ledger_type)
|
||||
gtk_widget_set_usize(regData->dialog, list_width + 80, 500);
|
||||
}
|
||||
|
||||
gtk_widget_show(regData->dialog);
|
||||
/* Add controls at the bottom. */
|
||||
{
|
||||
GtkWidget *hb = gtk_handle_box_new();
|
||||
GtkWidget *toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
|
||||
GTK_TOOLBAR_TEXT);
|
||||
gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
|
||||
"Record",
|
||||
"Commit modifications to "
|
||||
"the current transaction.",
|
||||
"Commit modifications to "
|
||||
"the current transaction.",
|
||||
NULL,
|
||||
GTK_SIGNAL_FUNC(recordCB), (gpointer) regData);
|
||||
|
||||
gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
|
||||
"Cancel",
|
||||
"Cancel modifications to "
|
||||
"the current transaction.",
|
||||
"Cancel modifications to "
|
||||
"the current transaction.",
|
||||
NULL,
|
||||
GTK_SIGNAL_FUNC(cancelCB), (gpointer) regData);
|
||||
|
||||
gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
|
||||
"Delete",
|
||||
"Delete the current transaction.",
|
||||
"Delete the current transaction.",
|
||||
NULL,
|
||||
GTK_SIGNAL_FUNC(deleteCB), (gpointer) regData);
|
||||
|
||||
gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
|
||||
"Reconcile",
|
||||
"Reconcile transactions with bank statement.",
|
||||
"Reconcile transactions with bank statement.",
|
||||
NULL,
|
||||
GTK_SIGNAL_FUNC(startRecnCB),
|
||||
(gpointer) regData);
|
||||
|
||||
gtk_box_pack_end(GTK_BOX(register_vbox), hb, FALSE, FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(hb), toolbar);
|
||||
gtk_widget_show(toolbar);
|
||||
gtk_widget_show(hb);
|
||||
}
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(register_window), register_vbox);
|
||||
|
||||
gtk_widget_show(table_frame);
|
||||
gtk_widget_show(register_vbox);
|
||||
gtk_widget_show(register_window);
|
||||
|
||||
if(windowname) free(windowname);
|
||||
return regData;
|
||||
}
|
||||
@ -760,23 +821,34 @@ void regRefresh (RegWindow *regData)
|
||||
xaccAccountGetSplitList (regData->leader),
|
||||
regData->leader);
|
||||
|
||||
|
||||
xaccAccountRecomputeBalance(regData->leader);
|
||||
/* hack alert -- this is incorrect for multi-account ledgers */
|
||||
if( NULL != regData->balance ) {
|
||||
char buf [BUFSIZE];
|
||||
char * amt;
|
||||
double prt_balance, prt_clearedBalance;
|
||||
if( NULL != regData->dialog ) {
|
||||
char *reglabel = NULL;
|
||||
char *balance_str, *cleared_balance_str, *reconciled_balance_str;
|
||||
double prt_balance, prt_clearedBalance, prt_reconciledBalance;
|
||||
prt_balance = xaccAccountGetBalance (regData->leader);
|
||||
prt_clearedBalance = xaccAccountGetClearedBalance (regData->leader);
|
||||
|
||||
amt = xaccPrintAmount (prt_balance, PRTSYM);
|
||||
strcpy (buf, amt);
|
||||
strcat (buf, "\n");
|
||||
amt = xaccPrintAmount (prt_clearedBalance, PRTSYM);
|
||||
strcat (buf, amt);
|
||||
|
||||
//XmTextSetString( regData->balance, buf );
|
||||
|
||||
prt_reconciledBalance =
|
||||
xaccAccountGetReconciledBalance (regData->leader);
|
||||
|
||||
balance_str = strdup(xaccPrintAmount(prt_balance, PRTSYM));
|
||||
cleared_balance_str = strdup(xaccPrintAmount(prt_clearedBalance, PRTSYM));
|
||||
reconciled_balance_str =
|
||||
strdup(xaccPrintAmount(prt_reconciledBalance, PRTSYM));
|
||||
|
||||
asprintf(®label, "%s (Reconciled: %s) (Cleared: %s) (Final: %s)",
|
||||
xaccAccountGetName(regData->leader),
|
||||
reconciled_balance_str,
|
||||
cleared_balance_str,
|
||||
balance_str
|
||||
);
|
||||
|
||||
gtk_frame_set_label(GTK_FRAME(regData->dialog), reglabel);
|
||||
free(balance_str);
|
||||
free(cleared_balance_str);
|
||||
free(reconciled_balance_str);
|
||||
free(reglabel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -888,6 +960,8 @@ closeRegWindow( GtkWidget * mw, gpointer data)
|
||||
RegWindow *regData = (RegWindow *)data;
|
||||
Account *acc = regData->leader;
|
||||
|
||||
fprintf(stderr, "Closing register safely\n");
|
||||
|
||||
/* Save any unsaved changes */
|
||||
xaccSaveRegEntry (regData->ledger);
|
||||
|
||||
@ -933,6 +1007,8 @@ startAdjBCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
adjBWindow( toplevel, acc );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/********************************************************************\
|
||||
* startRecnCB -- open up the reconcile window... called from *
|
||||
* menubar. *
|
||||
@ -943,9 +1019,9 @@ startAdjBCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
static void
|
||||
startRecnCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
startRecnCB(GtkWidget * w, gpointer data)
|
||||
{
|
||||
RegWindow *regData = (RegWindow *)cd;
|
||||
RegWindow *regData = (RegWindow *) data;
|
||||
Account *acc;
|
||||
|
||||
/* Must have number of accounts be one. If not one,
|
||||
@ -958,7 +1034,7 @@ startRecnCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
if (1 != regData->numAcc) return;
|
||||
acc = regData->blackacc[0];
|
||||
}
|
||||
recnWindow( toplevel, acc );
|
||||
recnWindow(w, acc);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -970,9 +1046,9 @@ startRecnCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
static void
|
||||
recordCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
recordCB( GtkWidget *w, gpointer data)
|
||||
{
|
||||
RegWindow *regData = (RegWindow *)cd;
|
||||
RegWindow *regData = (RegWindow *) data;
|
||||
|
||||
xaccSaveRegEntry (regData->ledger);
|
||||
}
|
||||
@ -987,9 +1063,9 @@ recordCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
\********************************************************************/
|
||||
|
||||
static void
|
||||
deleteCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
deleteCB(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
RegWindow *regData = (RegWindow *)cd;
|
||||
RegWindow *regData = (RegWindow *) data;
|
||||
Split * split;
|
||||
Transaction *trans;
|
||||
char buf[BUFSIZE];
|
||||
@ -1004,7 +1080,7 @@ deleteCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
* permanent damage */
|
||||
trans = xaccSplitGetParent (split);
|
||||
sprintf (buf, TRANS_DEL_MSG, xaccTransGetDescription (trans));
|
||||
if (!verifyBox (toplevel, buf)) return;
|
||||
if (!verifyBox(toplevel, buf)) return;
|
||||
|
||||
/* make a copy of all of the accounts that will be
|
||||
* affected by this deletion, so that we can update
|
||||
@ -1036,17 +1112,16 @@ deleteCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
static void
|
||||
cancelCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
cancelCB( GtkWidget *w, gpointer data)
|
||||
{
|
||||
RegWindow *regData = (RegWindow *)cd;
|
||||
Split * split;
|
||||
|
||||
RegWindow *regData = (RegWindow *) data;
|
||||
Split * split;
|
||||
|
||||
/* when cancelling edits, reload the cursor from the transaction */
|
||||
split = xaccGetCurrentSplit (regData->ledger);
|
||||
xaccLoadRegEntry (regData->ledger, split);
|
||||
xaccRefreshTableGUI (regData->ledger->table);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/************************** END OF FILE *************************/
|
||||
|
||||
@ -1054,8 +1129,6 @@ cancelCB( GtkWidget * mw, XtPointer cd, XtPointer cb )
|
||||
Local Variables:
|
||||
tab-width: 2
|
||||
indent-tabs-mode: nil
|
||||
mode: c
|
||||
c-indentation-style: gnu
|
||||
eval: (c-set-offset 'substatement-open 0)
|
||||
eval: (c-set-style "gnu")
|
||||
End:
|
||||
*/
|
||||
|
@ -111,6 +111,36 @@ void file_cmd_quit (GtkWidget *widget, gpointer data)
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
static void
|
||||
foreach_split_in_group(AccountGroup *g, void (*f)(Split *)) {
|
||||
const int num_accts = xaccGroupGetNumAccounts(g);
|
||||
Account **acc_list = (Account **) _malloc((num_accts + 1) *
|
||||
sizeof(Account *));
|
||||
Account *acct;
|
||||
int i, pos;
|
||||
Split **splits;
|
||||
Split **split_cursor;
|
||||
|
||||
for(i = 0, pos = 0; i < num_accts; i++) {
|
||||
acct = xaccGetAccountFromID(g, i);
|
||||
if(acct) {
|
||||
acc_list[pos++] = acct;
|
||||
}
|
||||
}
|
||||
acc_list[pos] = NULL;
|
||||
|
||||
splits = accListGetSortedSplits(acc_list);
|
||||
|
||||
split_cursor = splits;
|
||||
while(*split_cursor) {
|
||||
f(*split_cursor);
|
||||
split_cursor++;
|
||||
}
|
||||
_free(splits);
|
||||
_free(acc_list);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
* main *
|
||||
* the entry point for the program... sets up the top level widget *
|
||||
@ -172,7 +202,7 @@ main( int argc, char *argv[] )
|
||||
|
||||
/* load the accounts data from datafile*/
|
||||
topgroup = xaccReadAccountGroup (datafile);
|
||||
|
||||
|
||||
if ( topgroup == NULL )
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
@ -224,8 +254,8 @@ prepare_app()
|
||||
Local Variables:
|
||||
tab-width: 2
|
||||
indent-tabs-mode: nil
|
||||
mode: c-mode
|
||||
mode: c
|
||||
c-indentation-style: gnu
|
||||
eval: (c-set-offset 'block-open '-)
|
||||
eval: (c-set-offset 'substatement-open 0)
|
||||
End:
|
||||
*/
|
||||
|
353
src/gnome/xtutil.c
Normal file
353
src/gnome/xtutil.c
Normal file
@ -0,0 +1,353 @@
|
||||
/********************************************************************\
|
||||
* util.c -- utility functions that are used everywhere else for *
|
||||
* xacc (X-Accountant) *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* *
|
||||
* 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, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "messages.h"
|
||||
#include "util.h"
|
||||
#include "xtutil.h"
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
/** GLOBALS *********************************************************/
|
||||
|
||||
extern XtAppContext app;
|
||||
extern int realized;
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
* dateCB -- ensures the data the user enters in the date field *
|
||||
* is in a valid format. *
|
||||
* *
|
||||
* Args: mw - the widget that called us *
|
||||
* cd - *
|
||||
* cb - the callback struct *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
dateCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
{
|
||||
XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)cb;
|
||||
char input;
|
||||
|
||||
/* TODO: ??? add support for date field accelerator keys!! */
|
||||
if( cbs->text->ptr != NULL )
|
||||
{
|
||||
input = (cbs->text->ptr)[0];
|
||||
|
||||
switch( input )
|
||||
{
|
||||
case '/':
|
||||
case '.':
|
||||
case '-':
|
||||
/* Make sure that there is at most two separators */
|
||||
{
|
||||
String str = XmTextGetString(mw);
|
||||
int i,count=0;
|
||||
|
||||
for( i=0; str[i] != '\0'; i++ )
|
||||
if( str[i] == input )
|
||||
count++;
|
||||
if( count >= 2 )
|
||||
cbs->doit = False;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0:
|
||||
/* if delete key (for example) is hit, then input string */
|
||||
/* will be an empty string. In such a case, allow the input */
|
||||
cbs->doit = True;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* only accept the input if it is a number */
|
||||
cbs->doit = isNum(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* amountCB -- ensures the data entered in the amount field is in *
|
||||
* a valid format. *
|
||||
* *
|
||||
* Args: mw - the widget that called us *
|
||||
* cd - *
|
||||
* cb - the callback struct *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
amountCB(GtkWidget *w, gpointer data)
|
||||
{
|
||||
XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)cb;
|
||||
char input;
|
||||
|
||||
if( cbs->text->ptr != NULL )
|
||||
{
|
||||
input = (cbs->text->ptr)[0];
|
||||
|
||||
switch( input )
|
||||
{
|
||||
case '.':
|
||||
/* Make sure that there is only one '.' */
|
||||
{
|
||||
String str = XmTextGetString(mw);
|
||||
int i,count=0;
|
||||
|
||||
for( i=0; str[i] != '\0'; i++ )
|
||||
if( str[i] == '.' )
|
||||
count++;
|
||||
if( count >= 1 )
|
||||
cbs->doit = False;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* only accept the input if it is a number */
|
||||
cbs->doit = isNum(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* noeditCB *
|
||||
* makes an Xbae matrix non-editable *
|
||||
* *
|
||||
* Args: mw - the widget that called us *
|
||||
* cd - *
|
||||
* cb - *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
noeditCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
{
|
||||
XbaeMatrixEnterCellCallbackStruct *cbs =
|
||||
(XbaeMatrixEnterCellCallbackStruct * )cb;
|
||||
|
||||
cbs->doit = False;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* destroyShellCB *
|
||||
* a callback to destroy a widget (cd, not w, because we want to *
|
||||
* destroy a window, not a button!) *
|
||||
* *
|
||||
* Args: mw - the widget that called us *
|
||||
* cd - the widget to destroy *
|
||||
* cb - *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
destroyShellCB( Widget w, XtPointer cd, XtPointer cb )
|
||||
{
|
||||
Widget window = (Widget)cd;
|
||||
|
||||
XtDestroyWidget(window);
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************\
|
||||
* setBusyCursor *
|
||||
* sets the cursor to the busy watch *
|
||||
* *
|
||||
* Args: w - the widget over which to make cursor busy *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
setBusyCursor(GtkWidget *w)
|
||||
{
|
||||
fprintf(stderr, "Unimplemented: setBusyCursor\n");
|
||||
|
||||
#if 0
|
||||
if( realized )
|
||||
{
|
||||
static Cursor watch = 0;
|
||||
|
||||
if( watch == 0 )
|
||||
watch = XCreateFontCursor(XtDisplay(w),XC_watch);
|
||||
|
||||
XDefineCursor(XtDisplay(w),XtWindow(w),watch);
|
||||
XmUpdateDisplay(w);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* unsetBusyCursor *
|
||||
* sets the cursor to the default cursor *
|
||||
* *
|
||||
* Args: w - the widget over which to make cursor normal *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
unsetBusyCursor(GtkWidget *w)
|
||||
{
|
||||
fprintf(stderr, "Unimplemented: unsetBusyCursor\n");
|
||||
|
||||
# if 0
|
||||
if( realized )
|
||||
{
|
||||
XUndefineCursor(XtDisplay(w),XtWindow(w));
|
||||
XmUpdateDisplay(w);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
**************** VERIFYBOX STUFF ***********************************
|
||||
\********************************************************************/
|
||||
|
||||
struct verify_callback_data {
|
||||
gboolean finished;
|
||||
gboolean value;
|
||||
};
|
||||
|
||||
static void
|
||||
verify_cb_yes(GtkWidget *w, gpointer data) {
|
||||
struct verify_callback_data *result = (struct verify_callback_data *) data;
|
||||
result->value = TRUE;
|
||||
result->finished = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
verify_cb_no(GtkWidget *w, gpointer data) {
|
||||
struct verify_callback_data *result = (struct verify_callback_data *) data;
|
||||
result->value = FALSE;
|
||||
result->finished = TRUE;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* verifyBox *
|
||||
* display a message, and asks the user to press "Ok" or "Cancel" *
|
||||
* *
|
||||
* NOTE: This function does not return until the dialog is closed *
|
||||
* *
|
||||
* Args: parent - the parent widget *
|
||||
* text - the message to display *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
gboolean
|
||||
verifyBox(GtkWidget *parent, const char *text)
|
||||
{
|
||||
|
||||
GtkWidget *verify_box = NULL;
|
||||
GtkWidget *verify_text = NULL;
|
||||
struct verify_callback_data result;
|
||||
|
||||
verify_box = gnome_dialog_new(text,
|
||||
GNOME_STOCK_BUTTON_YES,
|
||||
GNOME_STOCK_BUTTON_NO,
|
||||
NULL);
|
||||
gnome_dialog_set_modal(GNOME_DIALOG(verify_box));
|
||||
gnome_dialog_set_default(GNOME_DIALOG(verify_box), 1);
|
||||
gnome_dialog_set_close(GNOME_DIALOG(verify_box), TRUE);
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(verify_box), 0,
|
||||
GTK_SIGNAL_FUNC(verify_cb_yes),
|
||||
(gpointer) &result);
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(verify_box), 1,
|
||||
GTK_SIGNAL_FUNC(verify_cb_no),
|
||||
(gpointer) &result);
|
||||
|
||||
verify_text = gtk_label_new(text);
|
||||
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(verify_box)->vbox),
|
||||
verify_text, FALSE, FALSE, 0);
|
||||
gtk_widget_show(verify_text);
|
||||
|
||||
result.finished = FALSE;
|
||||
gtk_widget_show(verify_box);
|
||||
|
||||
setBusyCursor(parent);
|
||||
|
||||
while(!result.finished) {
|
||||
gtk_main_iteration();
|
||||
}
|
||||
|
||||
unsetBusyCursor(parent);
|
||||
|
||||
//gnome_dialog_close(GNOME_DIALOG(verify_box));
|
||||
|
||||
return result.value;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
*********************************************************************
|
||||
\********************************************************************/
|
||||
|
||||
static void
|
||||
error_cb_ok(GtkWidget *w, gpointer data) {
|
||||
*((gboolean *) data) = TRUE;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* errorBox *
|
||||
* displays an error dialog box *
|
||||
* *
|
||||
* Args: w - the parent widget *
|
||||
* message - the error message to display *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
errorBox(GtkWidget *parent, const char *message )
|
||||
{
|
||||
|
||||
GtkWidget *error_box = NULL;
|
||||
GtkWidget *error_text = NULL;
|
||||
gboolean finished = FALSE;
|
||||
|
||||
error_box = gnome_dialog_new("GnuCash: error",
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
NULL);
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(error_box), 0,
|
||||
GTK_SIGNAL_FUNC(error_cb_ok),
|
||||
(gpointer) &finished);
|
||||
gnome_dialog_set_modal(GNOME_DIALOG(error_box));
|
||||
gnome_dialog_set_default(GNOME_DIALOG(error_box), 0);
|
||||
gnome_dialog_set_close(GNOME_DIALOG(error_box), TRUE);
|
||||
|
||||
error_text = gtk_label_new(message);
|
||||
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(error_box)->vbox),
|
||||
error_text, FALSE, FALSE, 0);
|
||||
gtk_widget_show(error_text);
|
||||
|
||||
gtk_widget_show(error_box);
|
||||
|
||||
setBusyCursor(parent);
|
||||
|
||||
while(!finished) {
|
||||
gtk_main_iteration();
|
||||
}
|
||||
|
||||
unsetBusyCursor(parent);
|
||||
}
|
||||
|
||||
/************************* END OF FILE ******************************\
|
||||
\********************************************************************/
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
tab-width: 2
|
||||
indent-tabs-mode: nil
|
||||
eval: (c-set-style "gnu")
|
||||
End:
|
||||
*/
|
50
src/gnome/xtutil.h
Normal file
50
src/gnome/xtutil.h
Normal file
@ -0,0 +1,50 @@
|
||||
/********************************************************************\
|
||||
* xtutil.h -- utility functions that are used everywhere else for *
|
||||
* xacc (X-Accountant) *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* *
|
||||
* 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, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __XACC_XT_UTIL_H__
|
||||
#define __XACC_XT_UTIL_H__
|
||||
|
||||
#include <gnome.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/** PROTOTYPES ******************************************************/
|
||||
|
||||
#if 0
|
||||
|
||||
void dateCB( Widget mw, XtPointer cd, XtPointer cb );
|
||||
void amountCB( Widget mw, XtPointer cd, XtPointer cb );
|
||||
void noeditCB( Widget mw, XtPointer cd, XtPointer cb );
|
||||
void destroyShellCB( Widget w, XtPointer cd, XtPointer cb );
|
||||
void setBusyCursor( GtkWidget *w );
|
||||
void unsetBusyCursor( GtkWidget *w );
|
||||
void errorBox( GtkWidget *parent, const char *message );
|
||||
|
||||
#endif
|
||||
|
||||
gboolean verifyBox( GtkWidget *parent, const char *text );
|
||||
|
||||
#endif /* __XACC_XT_UTIL_H__ */
|
Loading…
Reference in New Issue
Block a user