mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
* src/gnc-ui-util.c (gnc_ui_account_get_balance): use current
stock quotes to get balances for stock/mutual/currency accounts * src/gnome/window-main.c: check for NULL toolbar parents * src/engine/sixtp-xml-write-utils.c: use new func below * src/engine/sixtp-dom-generators.c (timespec_sec_to_string): use new func below. * src/engine/sixtp-utils.c (timespec_secs_to_given_string): new func. format timezone string by hand (solaris fix) * src/engine/gnc-account-xml-v2.c (gnc_account_end_handler): only begin editing the account if parsing was successful * src/test/test-xml-account.c (test_add_account): don't delete the account, because it's referenced by the parser after the callback. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3990 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
e9e797da33
commit
c6ad9a51b9
22
ChangeLog
22
ChangeLog
@ -1,3 +1,25 @@
|
||||
2001-04-18 Dave Peticolas <dave@krondo.com>
|
||||
|
||||
* src/gnc-ui-util.c (gnc_ui_account_get_balance): use current
|
||||
stock quotes to get balances for stock/mutual/currency accounts
|
||||
|
||||
* src/gnome/window-main.c: check for NULL toolbar parents
|
||||
|
||||
* src/engine/sixtp-xml-write-utils.c: use new func below
|
||||
|
||||
* src/engine/sixtp-dom-generators.c (timespec_sec_to_string): use
|
||||
new func below.
|
||||
|
||||
* src/engine/sixtp-utils.c (timespec_secs_to_given_string): new
|
||||
func. format timezone string by hand (solaris fix)
|
||||
|
||||
* src/engine/gnc-account-xml-v2.c (gnc_account_end_handler): only
|
||||
begin editing the account if parsing was successful
|
||||
|
||||
* src/test/test-xml-account.c (test_add_account): don't delete
|
||||
the account, because it's referenced by the parser after the
|
||||
callback.
|
||||
|
||||
2001-04-17 Bill Gribble <grib@billgribble.com>
|
||||
|
||||
* src/gnome/window-main.c: More changes for MDI. I think we
|
||||
|
@ -1275,7 +1275,7 @@ xaccGroupForEachTransaction (AccountGroup *g,
|
||||
|
||||
GSList *
|
||||
xaccGroupMapAccounts (AccountGroup *grp,
|
||||
gpointer (*thunk)(Account *a, void *data),
|
||||
gpointer (*thunk)(Account *a, gpointer data),
|
||||
gpointer data)
|
||||
{
|
||||
GSList *result = NULL;
|
||||
@ -1298,7 +1298,7 @@ xaccGroupMapAccounts (AccountGroup *grp,
|
||||
|
||||
gpointer
|
||||
xaccGroupForEachAccountDeeply (AccountGroup *grp,
|
||||
gpointer (*thunk)(Account *a, void *data),
|
||||
gpointer (*thunk)(Account *a, gpointer data),
|
||||
gpointer data)
|
||||
{
|
||||
GList *node;
|
||||
|
@ -208,12 +208,12 @@ void xaccGroupDepthAutoCode (AccountGroup *grp);
|
||||
/* if the function returns null for a given item, it won't show up in
|
||||
the result list */
|
||||
GSList *xaccGroupMapAccounts(AccountGroup *grp,
|
||||
gpointer (*thunk)(Account *a, void *data),
|
||||
gpointer (*thunk)(Account *a, gpointer data),
|
||||
gpointer data);
|
||||
|
||||
gpointer xaccGroupForEachAccountDeeply(AccountGroup *grp,
|
||||
gpointer (*thunk)(Account *a,
|
||||
void *data),
|
||||
gpointer data),
|
||||
gpointer data);
|
||||
|
||||
gboolean xaccGroupEqual(AccountGroup *a, AccountGroup *b,
|
||||
|
@ -263,8 +263,9 @@ gnc_account_end_handler(gpointer data_for_children,
|
||||
* all the transactions, we will Commit. This replaces #splits
|
||||
* rebalances with #accounts rebalances at the end. A BIG win!
|
||||
*/
|
||||
xaccAccountBeginEdit(acc);
|
||||
|
||||
if (successful)
|
||||
xaccAccountBeginEdit(acc);
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
|
@ -94,38 +94,22 @@ gchar *
|
||||
timespec_sec_to_string(const Timespec *ts)
|
||||
{
|
||||
gchar *ret;
|
||||
struct tm parsed_time;
|
||||
time_t tmp_time;
|
||||
|
||||
ret = g_new(gchar, 512);
|
||||
|
||||
tmp_time = ts->tv_sec;
|
||||
|
||||
if(!localtime_r(&tmp_time, &parsed_time))
|
||||
ret = g_new(gchar, TIMESPEC_SEC_FORMAT_MAX);
|
||||
|
||||
if(!timespec_secs_to_given_string (ts, ret))
|
||||
{
|
||||
g_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(strftime(ret, 512, TIMESPEC_TIME_FORMAT, &parsed_time) == 0)
|
||||
{
|
||||
g_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar *
|
||||
timespec_nsec_to_string(const Timespec *ts)
|
||||
{
|
||||
gchar *ret;
|
||||
|
||||
ret = g_new(gchar, 22);
|
||||
|
||||
g_snprintf(ret, 22, "%ld", ts->tv_nsec);
|
||||
|
||||
return ret;
|
||||
return g_strdup_printf("%ld", ts->tv_nsec);
|
||||
}
|
||||
|
||||
xmlNodePtr
|
||||
|
@ -33,6 +33,8 @@
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
#define __EXTENSIONS__
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
@ -394,6 +396,8 @@ string_to_timespec_secs(const gchar *str, Timespec *ts) {
|
||||
time_t parsed_secs;
|
||||
long int gmtoff;
|
||||
|
||||
if (!str || !ts) return FALSE;
|
||||
|
||||
memset(&parsed_time, 0, sizeof(struct tm));
|
||||
|
||||
/* If you change this, make sure you also change the output code, if
|
||||
@ -448,7 +452,9 @@ string_to_timespec_nsecs(const gchar *str, Timespec *ts) {
|
||||
|
||||
long int nanosecs;
|
||||
int charcount;
|
||||
|
||||
|
||||
if (!str || !ts) return FALSE;
|
||||
|
||||
sscanf(str, " %ld %n", &nanosecs, &charcount);
|
||||
|
||||
if(charcount != strlen(str)) return(FALSE);
|
||||
@ -458,6 +464,55 @@ string_to_timespec_nsecs(const gchar *str, Timespec *ts) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
timespec_secs_to_given_string (const Timespec *ts, gchar *str)
|
||||
{
|
||||
struct tm parsed_time;
|
||||
size_t num_chars;
|
||||
time_t tmp_time;
|
||||
int minutes;
|
||||
int hours;
|
||||
int sign;
|
||||
|
||||
if (!ts || !str)
|
||||
return FALSE;
|
||||
|
||||
tmp_time = ts->tv_sec;
|
||||
|
||||
if (!localtime_r(&tmp_time, &parsed_time))
|
||||
return FALSE;
|
||||
|
||||
num_chars = strftime(str, TIMESPEC_SEC_FORMAT_MAX,
|
||||
TIMESPEC_TIME_FORMAT, &parsed_time);
|
||||
if (num_chars == 0)
|
||||
return FALSE;
|
||||
|
||||
str += num_chars;
|
||||
|
||||
/* timezone is reversed */
|
||||
sign = (timezone > 0) ? -1 : 1;
|
||||
|
||||
minutes = ABS (timezone) / 60;
|
||||
hours = minutes / 60;
|
||||
minutes -= hours * 60;
|
||||
|
||||
if (parsed_time.tm_isdst > 0)
|
||||
hours += sign;
|
||||
|
||||
/* check for rollover */
|
||||
if (hours == -1)
|
||||
{
|
||||
hours = 0;
|
||||
minutes = 60 - minutes;
|
||||
sign *= -1;
|
||||
}
|
||||
|
||||
g_snprintf (str, TIMESPEC_SEC_FORMAT_MAX - num_chars,
|
||||
" %c%02d%02d", (sign > 0) ? '+' : '-', hours, minutes);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Top level timespec node:
|
||||
|
||||
input: user end handler *
|
||||
|
@ -34,8 +34,9 @@ typedef struct {
|
||||
guint ns_block_count;
|
||||
} TimespecParseInfo;
|
||||
|
||||
#define TIMESPEC_TIME_FORMAT "%Y-%m-%d %H:%M:%S %z"
|
||||
#define TIMESPEC_TIME_FORMAT "%Y-%m-%d %H:%M:%S"
|
||||
#define TIMESPEC_PARSE_TIME_FORMAT "%Y-%m-%d %H:%M:%S"
|
||||
#define TIMESPEC_SEC_FORMAT_MAX 256
|
||||
|
||||
gboolean isspace_str(const gchar *str, int nomorethan);
|
||||
|
||||
@ -85,6 +86,9 @@ sixtp* simple_chars_only_parser_new(sixtp_end_handler end_handler);
|
||||
gboolean string_to_timespec_secs(const gchar *str, Timespec *ts);
|
||||
gboolean string_to_timespec_nsecs(const gchar *str, Timespec *ts);
|
||||
|
||||
/* str must have length of at least TIMESPEC_SEC_FORMAT_MAX */
|
||||
gboolean timespec_secs_to_given_string (const Timespec *ts, gchar *str);
|
||||
|
||||
|
||||
gboolean generic_timespec_start_handler(GSList* sibling_data,
|
||||
gpointer parent_data,
|
||||
|
@ -224,31 +224,23 @@ xml_add_editable_timespec(xmlNodePtr p,
|
||||
xmlNodePtr timespec_xml;
|
||||
xmlNodePtr secs_xml;
|
||||
size_t num_written;
|
||||
struct tm parsed_time;
|
||||
time_t tmp_timet;
|
||||
char secs_str[512]; /* This should be way bigger than we need.
|
||||
Still, it's bogus, we ought to have
|
||||
astrftime... */
|
||||
|
||||
char secs_str[TIMESPEC_SEC_FORMAT_MAX];
|
||||
|
||||
g_return_val_if_fail(p, FALSE);
|
||||
g_return_val_if_fail(tag, FALSE);
|
||||
g_return_val_if_fail(ts, FALSE);
|
||||
g_return_val_if_fail(ts, FALSE);
|
||||
|
||||
if(!include_if_zero && (ts->tv_sec == 0) && (ts->tv_nsec == 0)) return TRUE;
|
||||
|
||||
tmp_timet = ts->tv_sec;
|
||||
if(!localtime_r(&tmp_timet, &parsed_time)) return(FALSE);
|
||||
if (!timespec_secs_to_given_string (ts, secs_str))
|
||||
return FALSE;
|
||||
|
||||
num_written = strftime(secs_str, sizeof(secs_str),
|
||||
TIMESPEC_TIME_FORMAT,
|
||||
&parsed_time);
|
||||
if(num_written == 0) return(FALSE);
|
||||
|
||||
timespec_xml= xmlNewTextChild(p, NULL, tag, NULL);
|
||||
g_return_val_if_fail(timespec_xml, FALSE);
|
||||
|
||||
secs_xml = xmlNewTextChild(timespec_xml, NULL, "s", secs_str);
|
||||
g_return_val_if_fail(secs_xml, FALSE);
|
||||
|
||||
|
||||
if(ts->tv_nsec) {
|
||||
xmlNodePtr nsec_xml;
|
||||
char num_string[22];
|
||||
|
@ -191,28 +191,61 @@ gnc_account_get_balance_in_currency (Account *account,
|
||||
if (!price)
|
||||
return gnc_numeric_zero ();
|
||||
|
||||
return gnc_numeric_mul (balance, gnc_price_get_value (price),
|
||||
gnc_commodity_get_fraction (currency),
|
||||
GNC_RND_ROUND);
|
||||
balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
|
||||
gnc_commodity_get_fraction (currency),
|
||||
GNC_RND_ROUND);
|
||||
|
||||
gnc_price_unref (price);
|
||||
|
||||
return balance;
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gnc_commodity *currency;
|
||||
gnc_numeric balance;
|
||||
} CurrencyBalance;
|
||||
|
||||
|
||||
static gpointer
|
||||
balance_helper (Account *account, gpointer data)
|
||||
{
|
||||
CurrencyBalance *cb = data;
|
||||
gnc_numeric balance;
|
||||
|
||||
balance = gnc_account_get_balance_in_currency (account, cb->currency);
|
||||
|
||||
cb->balance = gnc_numeric_add (cb->balance, balance,
|
||||
gnc_commodity_get_fraction (cb->currency),
|
||||
GNC_RND_ROUND);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
gnc_ui_account_get_balance (Account *account, gboolean include_children)
|
||||
{
|
||||
gnc_numeric balance;
|
||||
gnc_commodity *currency;
|
||||
|
||||
if (account == NULL)
|
||||
return gnc_numeric_zero ();
|
||||
|
||||
balance = xaccAccountGetBalance (account);
|
||||
currency = xaccAccountGetCurrency (account);
|
||||
|
||||
balance = gnc_account_get_balance_in_currency (account, currency);
|
||||
|
||||
if (include_children)
|
||||
{
|
||||
AccountGroup *children;
|
||||
CurrencyBalance cb = { currency, balance };
|
||||
|
||||
children = xaccAccountGetChildren (account);
|
||||
balance = gnc_numeric_add_fixed (balance, xaccGroupGetBalance (children));
|
||||
|
||||
xaccGroupForEachAccountDeeply (children, balance_helper, &cb);
|
||||
|
||||
balance = cb.balance;
|
||||
}
|
||||
|
||||
/* reverse sign if needed */
|
||||
|
@ -95,9 +95,15 @@ gnc_main_window_remove_view_cb(GnomeMDI * mdi, GnomeMDIChild * child,
|
||||
static void
|
||||
gnc_main_window_app_destroyed_cb(GnomeApp * app, gpointer user_data) {
|
||||
GNCMainInfo * mainwin = user_data;
|
||||
GNCMainChildInfo * mc = NULL;
|
||||
GNCMainChildInfo * mc = NULL;
|
||||
GtkWidget *toolbar;
|
||||
GList * child;
|
||||
|
||||
toolbar = gtk_object_get_user_data (GTK_OBJECT (app));
|
||||
if (toolbar)
|
||||
gtk_widget_unref (toolbar);
|
||||
gtk_object_set_user_data (GTK_OBJECT (app), NULL);
|
||||
|
||||
for(child = mainwin->children; child; child = child->next) {
|
||||
mc = child->data;
|
||||
if(mc && mc->toolbar && mc->app && (mc->app == app)) {
|
||||
@ -107,7 +113,6 @@ gnc_main_window_app_destroyed_cb(GnomeApp * app, gpointer user_data) {
|
||||
gtk_container_remove(GTK_CONTAINER(mc->toolbar->parent), mc->toolbar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
@ -248,16 +253,17 @@ gnc_main_window_child_changed_cb(GnomeMDI * mdi, GnomeMDIChild * not_used,
|
||||
if(childwin->app && (childwin->app == new_app)) {
|
||||
oldbar = gtk_object_get_user_data(GTK_OBJECT(new_app));
|
||||
if(oldbar && (oldbar != childwin->toolbar)) {
|
||||
gtk_widget_hide(GTK_WIDGET(oldbar)->parent);
|
||||
if (oldbar->parent)
|
||||
gtk_widget_hide(GTK_WIDGET(oldbar)->parent);
|
||||
gtk_widget_show(GTK_WIDGET(childwin->toolbar)->parent);
|
||||
}
|
||||
}
|
||||
else if(childwin->app) {
|
||||
oldbar = gtk_object_get_user_data(GTK_OBJECT(new_app));
|
||||
if(oldbar && (oldbar != childwin->toolbar)) {
|
||||
if(oldbar && oldbar->parent && (oldbar != childwin->toolbar)) {
|
||||
gtk_widget_hide(GTK_WIDGET(oldbar)->parent);
|
||||
}
|
||||
|
||||
|
||||
/* we need to move the toolbar to a new App (mdi mode probably
|
||||
* changed) */
|
||||
if(GTK_WIDGET(childwin->toolbar)->parent) {
|
||||
@ -276,10 +282,10 @@ gnc_main_window_child_changed_cb(GnomeMDI * mdi, GnomeMDIChild * not_used,
|
||||
}
|
||||
else {
|
||||
oldbar = gtk_object_get_user_data(GTK_OBJECT(new_app));
|
||||
if(oldbar && (oldbar != childwin->toolbar)) {
|
||||
if(oldbar && oldbar->parent && (oldbar != childwin->toolbar)) {
|
||||
gtk_widget_hide(GTK_WIDGET(oldbar)->parent);
|
||||
}
|
||||
|
||||
|
||||
childwin->app = new_app;
|
||||
gnome_app_add_toolbar(GNOME_APP(childwin->app),
|
||||
GTK_TOOLBAR(childwin->toolbar),
|
||||
@ -288,12 +294,20 @@ gnc_main_window_child_changed_cb(GnomeMDI * mdi, GnomeMDIChild * not_used,
|
||||
gtk_toolbar_set_style(GTK_TOOLBAR(childwin->toolbar),
|
||||
gnc_get_toolbar_style());
|
||||
}
|
||||
|
||||
oldbar = gtk_object_get_user_data(GTK_OBJECT(new_app));
|
||||
if (oldbar)
|
||||
gtk_widget_unref (oldbar);
|
||||
|
||||
if (childwin->toolbar)
|
||||
gtk_widget_ref (childwin->toolbar);
|
||||
|
||||
gtk_object_set_user_data(GTK_OBJECT(new_app), childwin->toolbar);
|
||||
}
|
||||
|
||||
|
||||
/* set the window title */
|
||||
gnc_childwin_set_title (childwin);
|
||||
|
||||
|
||||
/* install menu hints if relevant */
|
||||
if(mdi->active_child) {
|
||||
/* the arg to this callback is SUPPOSED to be the last active child,
|
||||
|
Loading…
Reference in New Issue
Block a user