updates from rob browning

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@832 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1998-04-22 03:12:19 +00:00
parent f69c987698
commit 7f204f4a70
9 changed files with 1545 additions and 273 deletions

View File

@ -1,4 +1,4 @@
/********************************************************************\
/********************************************************************\
* MainWindow.c -- the main window, and associated helper functions *
* and callback functions for xacc (X-Accountant) *
* Copyright (C) 1998 Jeremy Collins *
@ -23,6 +23,7 @@
#include "MainWindow.h"
#include "MenuBar.h"
#include "messages.h"
#include "RegWindow.h"
#include "main.h"
@ -37,14 +38,25 @@ struct main_window {
};
/* This should most likely be rewritting to use a Tree, not a Clist so
we can represent the heirarchical account structure */
static void
acct_tree_open_selected(GtkWidget *child) {
Account *acct = gtk_object_get_user_data(GTK_OBJECT(child));
fprintf(stderr, "calling regWindowSimple(%p)\n", acct);
regWindowSimple(acct);
}
static void
acct_tree_select(GtkTree *tree, GtkWidget *child) {
//if(bevent && bevent->type == GDK_2BUTTON_PRESS) {
acct_tree_open_selected(child);
//}
}
static void
cram_accts_into_tree(GtkTree *maintree, AccountGroup *accts) {
int count = xaccGetNumAccounts(accts);
int i;
for(i=0; i<count; i++)
{
Account *acc = xaccGroupGetAccount(accts, i);
@ -58,10 +70,18 @@ cram_accts_into_tree(GtkTree *maintree, AccountGroup *accts) {
rowstrs[2] = xaccAccountGetNotes (acc);
tree_item = gtk_tree_item_new_with_label( rowstrs[0] );
/* Set the tree item to point to the actual account so we can reach it
trivially when the user selects the row. (Should we use
gtk_*_data_full and have a destroy notify?) */
gtk_object_set_user_data(GTK_OBJECT(tree_item), acc);
gtk_tree_append(GTK_TREE(maintree), tree_item );
gtk_widget_show ( tree_item );
}
gtk_signal_connect (GTK_OBJECT (maintree),
"select_child",
(GtkSignalFunc) acct_tree_select,
NULL);
}
/* Function: add_account
@ -239,10 +259,15 @@ main_window_init(AccountGroup *accts)
/* create a bunch of buttons */
button_bar = gtk_hbox_new(FALSE, 1);
toolBar[0] = gtk_button_new_with_label ( OPEN_STR );
toolBar[1] = gtk_button_new_with_label ( NEW_STR );
toolBar[2] = gtk_button_new_with_label ( EDIT_STR );
toolBar[3] = gtk_button_new_with_label ( DELETE_STR );
toolBar[open] = gtk_button_new_with_label ( OPEN_STR );
toolBar[close] = gtk_button_new_with_label ( NEW_STR );
toolBar[button3] = gtk_button_new_with_label ( EDIT_STR );
toolBar[button4] = gtk_button_new_with_label ( DELETE_STR );
toolBar[exit] = gtk_button_new_with_label (" Exit ");
/* Initialize callbacks */
gtk_signal_connect(GTK_OBJECT(toolBar[exit]), "clicked",
GTK_SIGNAL_FUNC (file_cmd_quit), NULL);
/* Initilize ToolTips */
@ -251,18 +276,21 @@ main_window_init(AccountGroup *accts)
gtk_tooltips_set_tip (tooltip, toolBar[close], TOOLTIP_NEW , NULL);
gtk_tooltips_set_tip (tooltip, toolBar[button3], TOOLTIP_EDIT, NULL);
gtk_tooltips_set_tip (tooltip, toolBar[button4], TOOLTIP_DELETE, NULL);
gtk_tooltips_set_tip (tooltip, toolBar[exit], TOOLTIP_EDIT, NULL);
/* Pack the buttons into the toolbar */
gtk_box_pack_start(GTK_BOX(button_bar), toolBar[0], FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(button_bar), toolBar[1], FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(button_bar), toolBar[2], FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(button_bar), toolBar[3], FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(button_bar), toolBar[4], FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(main_vbox), button_bar, FALSE, TRUE, 1);
gtk_widget_show(toolBar[open]);
gtk_widget_show(toolBar[close]);
gtk_widget_show(toolBar[button3]);
gtk_widget_show(toolBar[button4]);
gtk_widget_show(toolBar[exit]);
gtk_widget_show(button_bar);
gtk_widget_show(maintree);
@ -271,6 +299,11 @@ main_window_init(AccountGroup *accts)
gtk_signal_connect (GTK_OBJECT (toolBar[1]), "clicked",
GTK_SIGNAL_FUNC (add_account), accts);
//gtk_signal_connect (GTK_OBJECT(window), "destroy",
// GTK_SIGNAL_FUNC (gnucash_shutdown), NULL);
//gtk_signal_connect (GTK_OBJECT (window), "delete_event",
// GTK_SIGNAL_FUNC (gnucash_shutdown), NULL);
gtk_widget_set_usize ( app, 400, 400 );
/* Show everything now that it is created */

View File

@ -1,101 +1,66 @@
# Generated automatically from Makefile.in by configure.
#
######################################################################
#********************************************************************
#* Makefile -- makefile for xacc/src/gtk *
#* Copyright (C) 1997 Robin Clark *
#* Copyright (C) 1998 Linas Vepstas *
#* Copyright (C) 1998 Rob Browning *
#* *
#* 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: Robin Clark *
#* Internet: rclark@rush.aero.org *
#* Address: 609 8th Street *
#* Huntington Beach, CA 92648-4632 *
#********************************************************************
# Makefile -- makefile for xacc/src/engine
# Copyright (C) 1997 Robin Clark
# Copyright (C) 1998 Linas Vepstas
# Copyright (C) 1998 Rob Browning <rlb@cs.utexas.edu>
#
# 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: Robin Clark
# Internet: rclark@rush.aero.org
# Address: 609 8th Street
# Huntington Beach, CA 92648-4632
# These three lines are suggested defs for autoconf (see the info pages).
srcdir = .
CC = gcc
INCLPATH = -I/usr/include \
-I.. \
-I../.. \
-I../engine \
-I../register \
-I/usr/local/include \
-I/usr/X11R6/include/. \
-I./../../include \
-I/usr/lib/gnome-libs/include
INCLPATH = -I.. -I../.. -I../engine -I../register -I./../../include
# libhtmlw eliminated due to license restrictions
# and general brokenness
# -I./../../lib/libhtmlw
CFLAGS = -O2 -Wall -g -Wall -I/usr/X11R6/include ${INCLPATH}
LDFLAGS = -g -Wall
LIBS = -lpng -ljpeg -lz -lm -lSM -lICE -lXpm -L/usr/X11R6/lib $(shell gtk-config --libs) \
-lgnomeui -lgnome -lgnomesupport
#
# CFLAGS and LIBS are built automatically with gtk-config.
# gtk-config is now "guaranteed" to be installed on any host
# where gtk's installed and is supposed to report the compiler
# options needed for the build.
CFLAGS := $(shell gtk-config --cflags) -g -Wall
LFLAGS := -g -Wall
# LIBS = -lXpm -lXm -lXmu -lXt -lXext -lSM -lICE -lX11 -lpng -ljpeg -lz -lm
GNOMELIBS= -lgnomeui -lgnome -lgnomesupport -ldl -lgdk_imlib -ltiff -lgif -ljpeg -lpng -lz -lSM -lICE -L/usr/local/lib -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm
LIBS := $(shell gtk-config --libs) $(GNOMELIBS)
LIBPATH = -L/lib -L/usr/lib -L/usr/local/lib -L/usr/X11R6/lib/.
TARGET = ../../xacc.gtk.bin
STATIC = ../../xacc-static.gtk.bin
OTHER_OBJS := ../obj/gnome/*.o ../engine/obj/*.o ../register/obj/gnome/*.o
LIBREG = ../libregister.a
LIBENG = ../libengine.a
######################################################################
SRCS = main.c MainWindow.c MenuBar.c
# SRCS = AccWindow.c AccountMenu.c AdjBWindow.c \
# See Makefile.common for information about these variables.
GNOME_SRCS := main.c MainWindow.c MenuBar.c RegWindow.c
# AccWindow.c AccountMenu.c AdjBWindow.c \
# BuildMenu.c Destroy.c FileBox.c HelpWindow.c \
# RecnWindow.c RegWindow.c Reports.c TextBox.c \
# XferWindow.c date.c xtutil.c
# OBJS = ${SRCS:.c=.o} $(LIBENG) $(LIBREG) ../Ledger.o
OBJS = ${SRCS:.c=.o} $(LIBENG)
######################################################################
default: $(TARGET)
gnome: default
# This inclusion must come after the first target, and after the
# definitions of *_SRCS, etc., but before the usage of *_OBJS.
include ../../Makefile.common
$(TARGET): $(OBJS)
@echo "++++++"
$(CC) $(LFLAGS) $(OBJS) $(LIBPATH) $(LIBS) -o $@
gnome: default
static: $(STATIC)
$(STATIC): $(OBJS)
@echo "++++++"
$(CC) $(LFLAGS) $(OBJS) $(LIBPATH) $(LIBS) -o $@ -static
$(TARGET): ${GNOME_OBJS} ${OTHER_OBJS}
$(CC) $(LDFLAGS) $(LIBS) -o $@ $^
.c.o:
@echo "+++"
$(CC) -c $(CFLAGS) $(INCLPATH) $<
depend:
makedepend -- $(INCLPATH) $(DEFN) -- $(SRCS)
clean:
rm -f *.o *~ *.bak
distclean: clean
rm -f $(TARGET) $(STATIC) Makefile Makefile.bak config.h
# DO NOT DELETE THIS LINE -- make depend depends on it.
$(STATIC): ${GNOME_OBJS} ${OTHER_OBJS}
$(CC) -static $(LDFLAGS) $(LIBS) -o $@ $^

View File

@ -1,101 +1,66 @@
#
######################################################################
#********************************************************************
#* Makefile -- makefile for xacc/src/gtk *
#* Copyright (C) 1997 Robin Clark *
#* Copyright (C) 1998 Linas Vepstas *
#* Copyright (C) 1998 Rob Browning *
#* *
#* 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: Robin Clark *
#* Internet: rclark@rush.aero.org *
#* Address: 609 8th Street *
#* Huntington Beach, CA 92648-4632 *
#********************************************************************
# Makefile -- makefile for xacc/src/engine
# Copyright (C) 1997 Robin Clark
# Copyright (C) 1998 Linas Vepstas
# Copyright (C) 1998 Rob Browning <rlb@cs.utexas.edu>
#
# 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: Robin Clark
# Internet: rclark@rush.aero.org
# Address: 609 8th Street
# Huntington Beach, CA 92648-4632
# These three lines are suggested defs for autoconf (see the info pages).
@SET_MAKE@
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
INCLPATH = -I/usr/include \
-I.. \
-I../.. \
-I../engine \
-I../register \
-I/usr/local/include \
-I@x_includes@/. \
-I@srcdir@/../../include \
-I/usr/lib/gnome-libs/include
INCLPATH = -I.. -I../.. -I../engine -I../register -I@srcdir@/../../include
# libhtmlw eliminated due to license restrictions
# and general brokenness
# -I@srcdir@/../../lib/libhtmlw
CFLAGS = @CFLAGS@ @X_CFLAGS@ ${INCLPATH}
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@ @X_PRE_LIBS@ @X_LIBS@ $(shell gtk-config --libs) \
@X_EXTRA_LIBS@ -lgnomeui -lgnome -lgnomesupport
#
# CFLAGS and LIBS are built automatically with gtk-config.
# gtk-config is now "guaranteed" to be installed on any host
# where gtk's installed and is supposed to report the compiler
# options needed for the build.
CFLAGS := $(shell gtk-config --cflags) @cflags@
LFLAGS := @lflags@
# LIBS = @LIBS@
GNOMELIBS= -lgnomeui -lgnome -lgnomesupport -ldl -lgdk_imlib -ltiff -lgif -ljpeg -lpng -lz -lSM -lICE -L/usr/local/lib -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm
LIBS := $(shell gtk-config --libs) $(GNOMELIBS)
LIBPATH = -L/lib -L/usr/lib -L/usr/local/lib -L@x_libraries@/.
TARGET = ../../xacc.gtk.bin
STATIC = ../../xacc-static.gtk.bin
OTHER_OBJS := ../obj/gnome/*.o ../engine/obj/*.o ../register/obj/gnome/*.o
LIBREG = ../libregister.a
LIBENG = ../libengine.a
######################################################################
SRCS = main.c MainWindow.c MenuBar.c
# SRCS = AccWindow.c AccountMenu.c AdjBWindow.c \
# See Makefile.common for information about these variables.
GNOME_SRCS := main.c MainWindow.c MenuBar.c RegWindow.c
# AccWindow.c AccountMenu.c AdjBWindow.c \
# BuildMenu.c Destroy.c FileBox.c HelpWindow.c \
# RecnWindow.c RegWindow.c Reports.c TextBox.c \
# XferWindow.c date.c xtutil.c
# OBJS = ${SRCS:.c=.o} $(LIBENG) $(LIBREG) ../Ledger.o
OBJS = ${SRCS:.c=.o} $(LIBENG)
######################################################################
default: $(TARGET)
gnome: default
# This inclusion must come after the first target, and after the
# definitions of *_SRCS, etc., but before the usage of *_OBJS.
include ../../Makefile.common
$(TARGET): $(OBJS)
@echo "++++++"
$(CC) $(LFLAGS) $(OBJS) $(LIBPATH) $(LIBS) -o $@
gnome: default
static: $(STATIC)
$(STATIC): $(OBJS)
@echo "++++++"
$(CC) $(LFLAGS) $(OBJS) $(LIBPATH) $(LIBS) -o $@ -static
$(TARGET): ${GNOME_OBJS} ${OTHER_OBJS}
$(CC) $(LDFLAGS) $(LIBS) -o $@ $^
.c.o:
@echo "+++"
$(CC) -c $(CFLAGS) $(INCLPATH) $<
depend:
makedepend -- $(INCLPATH) $(DEFN) -- $(SRCS)
clean:
rm -f *.o *~ *.bak
distclean: clean
rm -f $(TARGET) $(STATIC) Makefile Makefile.bak config.h
# DO NOT DELETE THIS LINE -- make depend depends on it.
$(STATIC): ${GNOME_OBJS} ${OTHER_OBJS}
$(CC) -static $(LDFLAGS) $(LIBS) -o $@ $^

1058
src/gnome/RegWindow.c Normal file

File diff suppressed because it is too large Load Diff

52
src/gnome/RegWindow.h Normal file
View File

@ -0,0 +1,52 @@
/********************************************************************\
* RegWindow.h -- the register window 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 __REGWINDOW_H__
#define __REGWINDOW_H__
#include <gtk/gtk.h>
#include "config.h"
#include "Account.h"
/** GLOBALS *********************************************************/
/** STRUCTS *********************************************************/
typedef struct _RegWindow RegWindow;
/** PROTOTYPES ******************************************************/
void accRefresh (Account *);
RegWindow *regWindowSimple( Account *account );
RegWindow *regWindowAccGroup( Account *account_group );
RegWindow *regWindowLedger( Account *lead, Account **account, int type);
/*
* The xaccDestroyRegWindow() subroutine can be called from
* anywhere to shut down the Register window. Used primarily when
* destroying the underlying account.
*/
void xaccDestroyRegWindow (Account *);
#endif

View File

@ -1,6 +1,5 @@
* From: Rob Browning <rlb@cs.utexas.edu>
For those of you interested, below is an extremely simple example of a
tiny standalone program that can read an .xac file (specified as the
first argument and then let you select accounts to plot from a Gtk
@ -14,8 +13,8 @@ ftp://ftp.gnu.org/pub/gnu/plotutils-2.0.tar.gz
Issues:
This program is trivial, and it only works via a Gtk GUI, but I think
that in the end we should support both interactive and non-interactive
This program is trivial, and it only works via a Gtk GUI. In the end
I think we should support both interactive and non-interactive
operation of our graphing and reporting tools. Whether this happens
via special arguments to xacc, or by providing separate standalone
programs that link to a common library (libxaccplot?) I don't know,
@ -27,25 +26,17 @@ axis labels or anything. This could obviously be improved, but there
are limits to how flexible the graph program is. It can't, for
example, do pie or bar charts at the moment.
However, the lower level library (libplot) that it's based on will
allow us to do whatever we want. In that case, though, we have to do
the scaling, drawing, etc, ourselves, so I think we're better off to
use "graph" for now, and go back and re-implement things in libplot,
adding bells and whistles and other types of graphs later. I did
create libplot code for simple bars in a bargraph just to make sure I
though it would be feasible.
The other disadvantage to calling graph (as opposed to using libplot
directly) is that it brings up it's own independent X window on each
invocation. This can also be overcome by switching to the more
primitive libplot, where you can specify your own X drawable as the
output device.
I've actually contacted the plotutils author about providing the more
sophisticated "graph" level plotting behaviors (autoscaling, etc.) as
part of a library (libplotutils) rather than only as a standalone
program. My guess is that this will happen, but I haven't heard back
yet.
The lower level library (libplot) that graph is based on will allow us
to do whatever we want, although we'll have to do all the scaling,
drawing, etc, that graph normally handles. Right now, graph's
functionality is only availble in the executable, but after talking to
the upstream author, he's decided to turn most of graph into a
library. As a result it doesn't make sense to spend a lot of time
right now re-implementing graph's functionality in libplot. We should
just wait, executing graph as a separate process to handle normal XY
plots for now. Our current efforts should be directed at implementing
graph types plotutils doesn't handle (like pie and bar), and into work
on the general graphing infrastructure.
--
Rob Browning <rlb@cs.utexas.edu>

View File

@ -1,95 +1,299 @@
/* File: plot-test.c */
/* Eventually the graphs should draw to a pixmap and refresh from
there. This is *easy* to do in GTK. */
#include <stdio.h>
#include <assert.h>
#include <getopt.h>
#include <gtk/gtk.h>
#include <gdk/gdkprivate.h>
#include <plot.h>
#include <Account.h>
#include <LedgerUtils.h>
#include <FileIO.h>
static int
graph_balance(Split **splits) {
FILE *child = popen("graph -T X", "w");
int i = 0;
#include <plot.h>
assert(child != NULL);
while(*splits) {
const double split_balance = xaccGetBalance(*splits);
fprintf(child, "%d %f\n", i, split_balance);
i++;
splits++;
}
pclose(child);
return 0;
}
static char *filename = NULL;
void
destroy() {
gtk_main_quit ();
}
typedef struct {
char *label;
double value;
} PieChartItem;
static const PieChartItem item1 = {"horses", 121.32};
static const PieChartItem item2 = {"throbbing expanse", 350.19};
static const PieChartItem item3 = {"tangibles", 23.32};
static const PieChartItem item4 = {"intangibles", 45.44};
static const PieChartItem item5 = {"giant fungi", 241.87};
static const PieChartItem *pie_data[] = {
&item1,
&item2,
&item3,
&item4,
&item5,
0
};
static double
pie_chart_slice(GtkWidget *w,
GdkColor *color,
const int width,
const int height,
const int center_x,
const int center_y,
const double total,
const double start_angle,
const PieChartItem *item) {
GdkGC *gc = NULL;
const int pie_width = (2 * width) / 3;
const int pie_height = (2 * width) / 3;
const double full_circle = 360 * 64;
const double arc_sweep = (item->value / total) * full_circle;
gc = gdk_gc_new(GTK_WIDGET(w)->window);
gdk_gc_copy(gc, GTK_WIDGET(w)->style->black_gc);
gdk_gc_set_foreground(gc, color);
gdk_draw_arc(w->window, gc, TRUE,
center_x - pie_width / 2,
center_y - pie_width / 2,
pie_width, pie_height,
rint(start_angle), rint(arc_sweep));
gdk_gc_unref(gc);
return arc_sweep;
}
static void
graph_account_balance_per_transaction(gpointer item, gpointer user_data) {
Account *acct = (Account *)
gtk_object_get_data(GTK_OBJECT(item), "acct_ptr");
fprintf(stderr, "%s\n", acct->accountName);
xaccRecomputeBalance(acct);
{
Account *list[] = { acct, NULL };
Split **splits = accListGetSortedSplits(list);
graph_balance(splits);
pie_chart(GtkWidget *w, const PieChartItem *pie_chart_items[]) {
if(pie_chart_items) {
const PieChartItem **item = pie_chart_items;
double total = 0;
double current_angle = 0;
int current_color = 0;
/* this is going to be handled through guile eventually */
const char *pie_color_strings[] = {
"DarkGreen",
"FireBrick",
"DarkBlue",
"DarkOliveGreen",
"DarkOrange",
"MediumSeaGreen",
"peru",
"DarkOrchid",
"LimeGreen"
};
GdkColorContext *color_context =
gdk_color_context_new(gtk_widget_get_visual(w),
gtk_widget_get_colormap(w));
assert(color_context);
/* get total */
while(*item) {
fprintf(stderr, "%s\n", (*item)->label);
total += (*item)->value;
item++;
}
item = pie_chart_items;
while(*item) {
/* This is a *really* inefficient way to handle the colors, but
it's guaranteed safe. We can do something smarter later, but
it may not be worth worrying about. */
GdkColor color;
int n;
const int width = 400;
const int height = 400;
const int center_x = 200;
const int center_y = 200;
assert(gdk_color_parse(pie_color_strings[current_color], &color) != 0);
color.pixel = 0; /* this is important! */
n = 0; /* this is important! */
gdk_color_context_get_pixels (color_context,
&color.red,
&color.green,
&color.blue,
1, &color.pixel, &n);
assert(n == 1);
current_angle +=
pie_chart_slice(w, &color, width, height, center_x, center_y,
total, current_angle, *item);
current_color++;
if(current_color == sizeof(pie_color_strings) / sizeof(char *))
current_color = 0;
item++;
}
gdk_color_context_free(color_context);
}
}
static double
pie_chart_slice_plotutils(const char color[],
const int width,
const int height,
const int center_x,
const int center_y,
const double total,
const double start_angle,
const PieChartItem *item) {
const int pie_radius = width / 3;
const double full_circle = 2 * M_PI;
const double arc_sweep = (item->value / total) * full_circle;
savestate();
filltype(1);
colorname(color);
move(0,0);
savestate();
frotate(start_angle * 180 / M_PI);
cont(pie_radius, 0);
arc(0, 0,
pie_radius, 0,
pie_radius * cos(arc_sweep),
pie_radius * sin(arc_sweep));
cont(0,0);
endpath();
restorestate();
move(0.90 * width / 2 * cos(start_angle + arc_sweep / 2),
0.90 * width / 2 * sin(start_angle + arc_sweep / 2));
alabel('c', 'c', item->label);
restorestate();
fprintf(stderr, "start: %f sweep: %f\n", start_angle, arc_sweep);
return arc_sweep;
}
static void
plot(GtkButton *button, gpointer data) {
GtkWidget *list = GTK_WIDGET(data);
GList *selection = GTK_LIST(list)->selection;
g_list_foreach(selection, graph_account_balance_per_transaction, NULL);
pie_plotutils(const PieChartItem *pie_chart_items[]) {
if(pie_chart_items) {
const PieChartItem **item = pie_chart_items;
double total = 0;
double current_angle = 0;
int current_color = 0;
/* this is going to be handled through guile eventually */
const char *pie_color_strings[] = {
"DarkGreen",
"FireBrick",
"DarkBlue",
"DarkOliveGreen",
"DarkOrange",
"MediumSeaGreen",
"peru",
"DarkOrchid",
"LimeGreen",
0
};
/* get total */
while(*item) {
fprintf(stderr, "%s\n", (*item)->label);
total += (*item)->value;
item++;
}
item = pie_chart_items;
while(*item) {
/* This is a *really* inefficient way to handle the colors, but
it's guaranteed safe. We can do something smarter later, but
it may not be worth worrying about. */
const int width = 400;
const int height = 400;
const int center_x = 200;
const int center_y = 200;
current_angle +=
pie_chart_slice_plotutils(pie_color_strings[current_color],
width, height, center_x, center_y,
total, current_angle, *item);
current_color++;
if(!pie_color_strings[current_color]) current_color = 0;
item++;
}
}
}
static void
pie_window_expose(GtkDrawingArea *da, GdkEventExpose *event, gpointer data) {
//fprintf(stderr, "%p\n", data);
//pie_chart(GTK_WIDGET(da), data);
{
int handle;
GdkWindowPrivate *priv = (GdkWindowPrivate *)(GTK_WIDGET(da)->window);
assert(parampl("XDRAWABLE_DISPLAY", priv->xdisplay) == 0);
assert(parampl("XDRAWABLE_DRAWABLE1", &(priv->xwindow)) == 0);
//assert(parampl("XDRAWABLE_DRAWABLE2", &(priv->xwindow)) == 0);
assert(parampl("XDRAWABLE_DRAWABLE2", NULL) == 0);
handle = newpl("Xdrawable", stdin, stdout, stderr);
assert(handle);
selectpl(handle);
assert(openpl() == 0);
space(-200, -200, 200, 200);
colorname("grey83");
box(-200, -200, 200, 200);
pie_plotutils(pie_data);
assert(closepl() == 0);
selectpl(0);
deletepl(handle);
}
}
static GtkWidget *
make_main_window(GtkWidget **list) {
pie_window() {
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *quit_button;
GtkWidget *plot_button;
GtkWidget *da;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
*list = gtk_list_new();
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (destroy), NULL);
gtk_container_border_width (GTK_CONTAINER (window), 3);
quit_button = gtk_button_new_with_label ("Quit");
gtk_signal_connect_object (GTK_OBJECT (quit_button), "clicked",
GTK_SIGNAL_FUNC (gtk_widget_destroy),
GTK_OBJECT (window));
plot_button = gtk_button_new_with_label ("Plot");
gtk_signal_connect (GTK_OBJECT (plot_button), "clicked",
GTK_SIGNAL_FUNC (plot), *list);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add (GTK_CONTAINER(window), vbox);
gtk_box_pack_start(GTK_BOX(vbox), *list, FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(vbox), quit_button, FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(vbox), plot_button, FALSE, FALSE, 0);
gtk_widget_show (*list);
gtk_widget_show (plot_button);
da = gtk_drawing_area_new();
gtk_drawing_area_size(GTK_DRAWING_AREA(da), 400,400);
gtk_box_pack_start(GTK_BOX(vbox), da, FALSE, FALSE, 0);
gtk_widget_show(da);
gtk_signal_connect(GTK_OBJECT (da),
"expose_event",
GTK_SIGNAL_FUNC (pie_window_expose),
pie_data);
gtk_widget_set_events (da, GDK_EXPOSURE_MASK);
gtk_container_add (GTK_CONTAINER(window), vbox);
gtk_box_pack_end(GTK_BOX(vbox), quit_button, FALSE, FALSE, 0);
gtk_widget_show (quit_button);
gtk_widget_show(vbox);
gtk_widget_show (window);
@ -98,50 +302,54 @@ make_main_window(GtkWidget **list) {
}
static void
add_accounts_to_list(GtkWidget *list, const char *filename) {
AccountGroup *db = xaccReadAccountGroup(filename);
if(!db) {
fprintf(stderr, "db: %p error: %d\n", db, xaccGetFileIOError());
exit(1);
}
usage() {
static char usage_string[] =
"usage: plot-test [ --pie ] filename\n"
"--pie generate pie chart.\n";
{
int count = xaccGetNumAccounts(db);
int i;
GtkWidget *item;
for(i=0; i<count; i++) {
Account *acc = getAccount(db, i);
item = gtk_list_item_new_with_label(acc->accountName);
gtk_object_set_data(GTK_OBJECT(item), "acct_ptr", acc);
gtk_container_add(GTK_CONTAINER(list), item);
gtk_widget_show(item);
}
}
fputs(usage_string, stderr);
}
int
main(int argc, char *argv[]) {
int opt_pie = 0;
struct option cmd_line_opts[] = {
{"pie", 0, &opt_pie, 1},
{0, 0, 0, 0},
};
int result = 0;
int handle;
char *filename;
GtkWidget *main_win;
GtkWidget *display_area;
GtkWidget *list = NULL;
char c;
while((c = getopt_long(argc, argv, "", cmd_line_opts, NULL)) != EOF) {
if(c == ':') {
usage();
exit(1);
}
if(c == '?') {
usage();
exit(1);
}
}
if(optind != (argc - 1)) {
usage();
exit(1);
}
filename = argv[optind];
gtk_init(&argc, &argv);
if(argc != 2) {
fprintf(stderr, "usage: plot-test filename\n");
exit(1);
}
filename = argv[1];
//main_win = make_main_window(&list);
//add_accounts_to_list(list, filename);
main_win = make_main_window(&list);
add_accounts_to_list(list, filename);
gtk_main();
if(opt_pie) pie_window();
return(0);
gtk_main();
return result;
}

View File

@ -82,7 +82,7 @@ void file_ok_sel (GtkWidget *w, GtkFileSelection *fs)
main_window_init(topgroup);
}
void destroy (GtkWidget *widget, gpointer *data)
void gnucash_shutdown (GtkWidget *widget, gpointer *data)
{
gtk_main_quit ();
}
@ -116,7 +116,7 @@ main( int argc, char *argv[] )
gnome_init ("GnuCash", NULL, argc, argv,
0, NULL);
prepare_app();
{

View File

@ -50,7 +50,7 @@
/** STRUCTS *********************************************************/
/** PROTOTYPES ******************************************************/
void destroy (GtkWidget *widget, gpointer *data);
void gnucash_shutdown (GtkWidget *widget, gpointer *data);
void file_cmd_open (GtkWidget *widget, gpointer data);
void file_cmd_quit (GtkWidget *widget, gpointer data);
void prepare_app ( void );