[Gnucash-changes] Darin Willits' initial budget code.

Derek Atkins warlord at cvs.gnucash.org
Thu Aug 5 17:03:31 EDT 2004


Log Message:
-----------
Darin Willits' initial budget code.

	* src/engine/gnc-budget*:
	* src/gnome/*budget*:
	* src/gnome/glade/budget.glade:
	* src/gnome-utils/gnc-budget*:
	  Darin Willits' initial budget code.  Still not fully functional
	  but the basic UI is there.  See the GNOME2_STATUS for additional
	  information.

Tags:
----
gnucash-gnome2-dev

Modified Files:
--------------
    gnucash:
        ChangeLog
        GNOME2_STATUS
    gnucash/src/engine:
        Makefile.am
        gnc-engine.c
        gnc-engine.h
        gnc-trace.c
    gnucash/src/gnome:
        Makefile.am
        gnc-main-window.c
    gnucash/src/gnome/ui:
        gnc-main-window-ui.xml
    gnucash/src/gnome-utils:
        Makefile.am

Added Files:
-----------
    gnucash/src/engine:
        gnc-budget-book-p.h
        gnc-budget-book.c
        gnc-budget-book.h
        gnc-budget-cat-p.h
        gnc-budget-cat.c
        gnc-budget-cat.h
        gnc-budget-p.h
        gnc-budget-period-p.h
        gnc-budget-period-value-p.h
        gnc-budget-period-value.c
        gnc-budget-period-value.h
        gnc-budget-period.c
        gnc-budget-period.h
        gnc-budget.c
        gnc-budget.h
    gnucash/src/gnome:
        dialog-budget-category.c
        dialog-budget-category.h
        dialog-budget-list.c
        dialog-budget-list.h
        dialog-budget-workbench.c
        dialog-budget-workbench.h
        druid-budget-create.c
        druid-budget-create.h
        gnc-budget-gui.h
    gnucash/src/gnome/glade:
        budget.glade
    gnucash/src/gnome-utils:
        gnc-budget-list-tree-model.c
        gnc-budget-list-tree-model.h
        gnc-budget-tree-model.c
        gnc-budget-tree-model.h

Revision Data
-------------
Index: ChangeLog
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/ChangeLog,v
retrieving revision 1.1487.2.135
retrieving revision 1.1487.2.136
diff -LChangeLog -LChangeLog -u -r1.1487.2.135 -r1.1487.2.136
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,13 @@
+2004-08-05  Derek Atkins  <derek at ihtfp.com>
+
+	* src/engine/gnc-budget*:
+	* src/gnome/*budget*:
+	* src/gnome/glade/budget.glade:
+	* src/gnome-utils/gnc-budget*:
+	  Darin Willits' initial budget code.  Still not fully functional
+	  but the basic UI is there.  See the GNOME2_STATUS for additional
+	  information.
+
 2004-07-20  Derek Atkins <derek at ihtfp.com>
 
 	* lib/egg/eggtoolbar.c
Index: GNOME2_STATUS
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/Attic/GNOME2_STATUS,v
retrieving revision 1.1.2.25
retrieving revision 1.1.2.26
diff -LGNOME2_STATUS -LGNOME2_STATUS -u -r1.1.2.25 -r1.1.2.26
--- GNOME2_STATUS
+++ GNOME2_STATUS
@@ -121,6 +121,20 @@
 
   HBCI - Needs new http support. [gnet]
 
+Budgeting
+    - Can create/modify budgets via the Budgeting workbench.
+      (Actions->Budgeting Workbench)
+    - Track budget tab still needs to be competed.  Should allow you to look
+      at predicted vs actual information.
+    - No save to file functionality.  Therefore budgets must currently be
+      created fresh each time gnucash is started.  First thing that I want
+      to fix.
+    - Should the budgeting workbench fit into the new windowing scheme
+      better?  Currently it is its own window but maybe each workbench
+      should be a tab in the new layout.  How would this work with the
+      sub-tabs?  Have to think about this some more.
+    - Probably more TODO but these are the main points.
+
 ========================================
               ENHANCEMENTS
 ========================================
@@ -145,3 +159,4 @@
 	long term?)
 
 4/      Print-preview support.
+
--- /dev/null
+++ src/gnome/glade/budget.glade
@@ -0,0 +1,2202 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+<requires lib="gnome"/>
+
+<widget class="GtkDialog" id="Budget List">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Budget List</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="close_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-close</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-7</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox1">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="scrolledwindow1">
+	      <property name="border_width">5</property>
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTreeView" id="Budget List View">
+		  <property name="border_width">10</property>
+		  <property name="width_request">250</property>
+		  <property name="height_request">200</property>
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="headers_visible">True</property>
+		  <property name="rules_hint">False</property>
+		  <property name="reorderable">False</property>
+		  <property name="enable_search">True</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVButtonBox" id="vbuttonbox1">
+	      <property name="border_width">5</property>
+	      <property name="visible">True</property>
+	      <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkButton" id="new_button">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-new</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="edit_button">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-open</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="button3">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-delete</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkWindow" id="New Budget Druid">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">New Budget</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">True</property>
+
+  <child>
+    <widget class="GnomeDruid" id="Budget Druid">
+      <property name="border_width">4</property>
+      <property name="visible">True</property>
+      <property name="show_help">False</property>
+
+      <child>
+	<widget class="GnomeDruidPageEdge" id="">
+	  <property name="visible">True</property>
+	  <property name="position">GNOME_EDGE_START</property>
+	  <property name="title" translatable="yes">Create new Budget</property>
+	  <property name="text" translatable="yes">This druid will help you create a new 
+Budget.
+
+Note:  This is still a *very* experimental
+feature.  It will most probably crash and
+very likely spill your coffee in your lap 
+causing serious burns.
+
+You have been warned.</property>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageStandard" id="Budget Name">
+	  <property name="visible">True</property>
+	  <property name="title" translatable="yes">Budget Name</property>
+
+	  <child internal-child="vbox">
+	    <widget class="GtkVBox" id="druid-vbox1">
+	      <property name="border_width">16</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment2">
+		  <property name="visible">True</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xscale">1</property>
+		  <property name="yscale">0.5</property>
+
+		  <child>
+		    <widget class="GtkTable" id="table2">
+		      <property name="visible">True</property>
+		      <property name="n_rows">3</property>
+		      <property name="n_columns">3</property>
+		      <property name="homogeneous">False</property>
+		      <property name="row_spacing">5</property>
+		      <property name="column_spacing">5</property>
+
+		      <child>
+			<widget class="GtkLabel" id="label32">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Name:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label33">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Description: </property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label36">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes"></property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">2</property>
+			  <property name="right_attach">3</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label37">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes"></property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">2</property>
+			  <property name="right_attach">3</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label39">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes"></property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">46</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label41">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes"></property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">2</property>
+			  <property name="right_attach">3</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="name_entry">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char" translatable="yes">*</property>
+			  <property name="activates_default">False</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">3</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkScrolledWindow" id="scrolledwindow10">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+			  <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+			  <property name="shadow_type">GTK_SHADOW_IN</property>
+			  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+			  <child>
+			    <widget class="GtkTextView" id="description_view">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="justification">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap_mode">GTK_WRAP_NONE</property>
+			      <property name="cursor_visible">True</property>
+			      <property name="pixels_above_lines">0</property>
+			      <property name="pixels_below_lines">0</property>
+			      <property name="pixels_inside_wrap">0</property>
+			      <property name="left_margin">0</property>
+			      <property name="right_margin">0</property>
+			      <property name="indent">0</property>
+			      <property name="text" translatable="yes"></property>
+			    </widget>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">3</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options">fill</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageStandard" id="druidpagestandard1">
+	  <property name="visible">True</property>
+	  <property name="title" translatable="yes">Budget Setup</property>
+
+	  <child internal-child="vbox">
+	    <widget class="GtkVBox" id="druid-vbox2">
+	      <property name="border_width">16</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment3">
+		  <property name="visible">True</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xscale">1</property>
+		  <property name="yscale">0.5</property>
+
+		  <child>
+		    <widget class="GtkVBox" id="vbox10">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox13">
+			  <property name="border_width">5</property>
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">5</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label77">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Budget Duration:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkSpinButton" id="length_button">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="climb_rate">1</property>
+			      <property name="digits">0</property>
+			      <property name="numeric">False</property>
+			      <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+			      <property name="snap_to_ticks">False</property>
+			      <property name="wrap">False</property>
+			      <property name="adjustment">1 0 100 1 10 10</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkOptionMenu" id="length_menu">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="history">0</property>
+
+			      <child>
+				<widget class="GtkMenu" id="menu7">
+
+				  <child>
+				    <widget class="GtkMenuItem" id="months1">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">months</property>
+				      <property name="use_underline">True</property>
+				      <signal name="activate" handler="on_months1_activate" last_modification_time="Mon, 15 Sep 2003 09:45:19 GMT"/>
+				    </widget>
+				  </child>
+
+				  <child>
+				    <widget class="GtkMenuItem" id="years1">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">years</property>
+				      <property name="use_underline">True</property>
+				      <signal name="activate" handler="on_years1_activate" last_modification_time="Mon, 15 Sep 2003 09:45:19 GMT"/>
+				    </widget>
+				  </child>
+				</widget>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkHBox" id="budget_freq_box">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <placeholder/>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageStandard" id="Category Setup">
+	  <property name="visible">True</property>
+	  <property name="title" translatable="yes">Category Setup</property>
+
+	  <child internal-child="vbox">
+	    <widget class="GtkVBox" id="druid-vbox3">
+	      <property name="border_width">16</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox6">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkScrolledWindow" id="scrolledwindow11">
+		      <property name="width_request">500</property>
+		      <property name="height_request">400</property>
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		      <property name="shadow_type">GTK_SHADOW_NONE</property>
+		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		      <child>
+			<widget class="GtkTreeView" id="budget_tree_view">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="headers_visible">True</property>
+			  <property name="rules_hint">False</property>
+			  <property name="reorderable">False</property>
+			  <property name="enable_search">True</property>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkVButtonBox" id="vbuttonbox2">
+		      <property name="border_width">5</property>
+		      <property name="visible">True</property>
+		      <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkButton" id="new_category_button">
+			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-new</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="edit_category_button">
+			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-open</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="delete_category_button">
+			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-delete</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageEdge" id="finish_page">
+	  <property name="visible">True</property>
+	  <property name="position">GNOME_EDGE_FINISH</property>
+	  <property name="title" translatable="yes">Finish Budget</property>
+	  <property name="text" translatable="yes">Welcome to the first step on the road
+to financial happiness!</property>
+	</widget>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkDialog" id="Budget Workbench">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Budget Workbench</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox3">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area3">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="helpbutton2">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-help</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-11</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="cancel_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="apply_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-apply</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-10</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="ok_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-5</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkNotebook" id="notebook1">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="show_tabs">True</property>
+	  <property name="show_border">True</property>
+	  <property name="tab_pos">GTK_POS_TOP</property>
+	  <property name="scrollable">False</property>
+	  <property name="enable_popup">False</property>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox9">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkFrame" id="frame5">
+		  <property name="border_width">5</property>
+		  <property name="visible">True</property>
+		  <property name="label_xalign">0</property>
+		  <property name="label_yalign">0.5</property>
+		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox16">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkTable" id="table4">
+			  <property name="border_width">5</property>
+			  <property name="visible">True</property>
+			  <property name="n_rows">3</property>
+			  <property name="n_columns">3</property>
+			  <property name="homogeneous">False</property>
+			  <property name="row_spacing">5</property>
+			  <property name="column_spacing">10</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label65">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Name:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">1</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label66">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Description:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">1</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">2</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="name_entry">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char" translatable="yes">*</property>
+			      <property name="activates_default">False</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label70">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes"></property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">2</property>
+			      <property name="bottom_attach">3</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label71">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">     </property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">2</property>
+			      <property name="right_attach">3</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label72">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes"></property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">2</property>
+			      <property name="right_attach">3</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">2</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label73">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes"></property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">2</property>
+			      <property name="right_attach">3</property>
+			      <property name="top_attach">2</property>
+			      <property name="bottom_attach">3</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkScrolledWindow" id="scrolledwindow12">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+			      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+			      <property name="shadow_type">GTK_SHADOW_IN</property>
+			      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+			      <child>
+				<widget class="GtkTextView" id="description_view">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="editable">True</property>
+				  <property name="justification">GTK_JUSTIFY_LEFT</property>
+				  <property name="wrap_mode">GTK_WRAP_NONE</property>
+				  <property name="cursor_visible">True</property>
+				  <property name="pixels_above_lines">0</property>
+				  <property name="pixels_below_lines">0</property>
+				  <property name="pixels_inside_wrap">0</property>
+				  <property name="left_margin">0</property>
+				  <property name="right_margin">0</property>
+				  <property name="indent">0</property>
+				  <property name="text" translatable="yes"></property>
+				</widget>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">3</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkVBox" id="vbox11">
+			  <property name="border_width">5</property>
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <widget class="GtkHBox" id="hbox17">
+			      <property name="border_width">5</property>
+			      <property name="visible">True</property>
+			      <property name="homogeneous">False</property>
+			      <property name="spacing">5</property>
+
+			      <child>
+				<widget class="GtkLabel" id="label78">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes">Budget Duration:</property>
+				  <property name="use_underline">False</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_LEFT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">0.5</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkSpinButton" id="length_button">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="climb_rate">1</property>
+				  <property name="digits">0</property>
+				  <property name="numeric">False</property>
+				  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+				  <property name="snap_to_ticks">False</property>
+				  <property name="wrap">False</property>
+				  <property name="adjustment">1 0 100 1 10 10</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkOptionMenu" id="length_menu">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="history">0</property>
+
+				  <child>
+				    <widget class="GtkMenu" id="menu8">
+
+				      <child>
+					<widget class="GtkMenuItem" id="menuitem6">
+					  <property name="visible">True</property>
+					  <property name="label" translatable="yes">months</property>
+					  <property name="use_underline">True</property>
+					  <signal name="activate" handler="on_months1_activate" last_modification_time="Mon, 15 Sep 2003 09:45:19 GMT"/>
+					</widget>
+				      </child>
+
+				      <child>
+					<widget class="GtkMenuItem" id="menuitem7">
+					  <property name="visible">True</property>
+					  <property name="label" translatable="yes">years</property>
+					  <property name="use_underline">True</property>
+					  <signal name="activate" handler="on_years1_activate" last_modification_time="Mon, 15 Sep 2003 09:45:19 GMT"/>
+					</widget>
+				      </child>
+				    </widget>
+				  </child>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkHBox" id="budget_freq_box">
+			      <property name="visible">True</property>
+			      <property name="homogeneous">False</property>
+			      <property name="spacing">0</property>
+
+			      <child>
+				<placeholder/>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label63">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">General Information</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		    <packing>
+		      <property name="type">label_item</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkFrame" id="frame6">
+		  <property name="border_width">5</property>
+		  <property name="visible">True</property>
+		  <property name="label_xalign">0</property>
+		  <property name="label_yalign">0.5</property>
+		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox20">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkScrolledWindow" id="scrolledwindow13">
+			  <property name="border_width">5</property>
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+			  <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+			  <property name="shadow_type">GTK_SHADOW_IN</property>
+			  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+			  <child>
+			    <widget class="GtkTreeView" id="category_view">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="headers_visible">True</property>
+			      <property name="rules_hint">False</property>
+			      <property name="reorderable">False</property>
+			      <property name="enable_search">True</property>
+			    </widget>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkVButtonBox" id="vbuttonbox3">
+			  <property name="border_width">10</property>
+			  <property name="visible">True</property>
+			  <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <widget class="GtkButton" id="new_category_button">
+			      <property name="visible">True</property>
+			      <property name="can_default">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label">gtk-new</property>
+			      <property name="use_stock">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			    </widget>
+			  </child>
+
+			  <child>
+			    <widget class="GtkButton" id="edit_category_button">
+			      <property name="visible">True</property>
+			      <property name="can_default">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label">gtk-open</property>
+			      <property name="use_stock">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			    </widget>
+			  </child>
+
+			  <child>
+			    <widget class="GtkButton" id="delete_category_button">
+			      <property name="visible">True</property>
+			      <property name="can_default">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label">gtk-delete</property>
+			      <property name="use_stock">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			    </widget>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label81">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Category Setup</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		    <packing>
+		      <property name="type">label_item</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox11">
+	      <property name="border_width">3</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkImage" id="image3">
+		  <property name="visible">True</property>
+		  <property name="stock">gtk-properties</property>
+		  <property name="icon_size">4</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label74">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Budget Setup</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox13">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkHButtonBox" id="hbuttonbox1">
+		  <property name="border_width">5</property>
+		  <property name="visible">True</property>
+		  <property name="layout_style">GTK_BUTTONBOX_END</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkButton" id="regenerate_button">
+		      <property name="visible">True</property>
+		      <property name="can_default">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+
+		      <child>
+			<widget class="GtkAlignment" id="alignment4">
+			  <property name="visible">True</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xscale">0</property>
+			  <property name="yscale">0</property>
+
+			  <child>
+			    <widget class="GtkHBox" id="hbox21">
+			      <property name="visible">True</property>
+			      <property name="homogeneous">False</property>
+			      <property name="spacing">2</property>
+
+			      <child>
+				<widget class="GtkImage" id="image6">
+				  <property name="visible">True</property>
+				  <property name="stock">gtk-refresh</property>
+				  <property name="icon_size">4</property>
+				  <property name="xalign">0.5</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkLabel" id="label82">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes">Regenerate From Defaults</property>
+				  <property name="use_underline">True</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_LEFT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">0.5</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+			    </widget>
+			  </child>
+			</widget>
+		      </child>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="scrolledwindow14">
+		  <property name="border_width">5</property>
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		  <property name="shadow_type">GTK_SHADOW_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <widget class="GtkTreeView" id="balance_budget_view">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="headers_visible">True</property>
+		      <property name="rules_hint">False</property>
+		      <property name="reorderable">False</property>
+		      <property name="enable_search">True</property>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox12">
+	      <property name="border_width">3</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkImage" id="image4">
+		  <property name="visible">True</property>
+		  <property name="stock">gtk-refresh</property>
+		  <property name="icon_size">4</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label75">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Balance Budget</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox14">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox22">
+		  <property name="border_width">10</property>
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkHButtonBox" id="hbuttonbox3">
+		      <property name="visible">True</property>
+		      <property name="layout_style">GTK_BUTTONBOX_START</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkButton" id="first_period_button">
+			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-goto-first</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="back_period_button">
+			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-go-back</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="period_label">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">January 1, 2004</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkHButtonBox" id="hbuttonbox2">
+		      <property name="visible">True</property>
+		      <property name="layout_style">GTK_BUTTONBOX_END</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkButton" id="next_period_button">
+			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-go-forward</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="last_period_button">
+			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-goto-last</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="scrolledwindow15">
+		  <property name="border_width">5</property>
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		  <property name="shadow_type">GTK_SHADOW_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <widget class="GtkTreeView" id="track_view">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="headers_visible">True</property>
+		      <property name="rules_hint">False</property>
+		      <property name="reorderable">False</property>
+		      <property name="enable_search">True</property>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="track_budget_view">
+	      <property name="border_width">3</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkImage" id="image5">
+		  <property name="visible">True</property>
+		  <property name="stock">gtk-zoom-100</property>
+		  <property name="icon_size">4</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label76">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Track Budget</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkDialog" id="Modify Category Dialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Modify Category</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox4">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area4">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="helpbutton3">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-help</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-11</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="cancel_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="ok_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="response_id">-5</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox4">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox7">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox8">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkFrame" id="frame1">
+		      <property name="border_width">5</property>
+		      <property name="visible">True</property>
+		      <property name="label_xalign">0</property>
+		      <property name="label_yalign">0.5</property>
+		      <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox8">
+			  <property name="border_width">5</property>
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <widget class="GtkVBox" id="vbox5">
+			      <property name="border_width">3</property>
+			      <property name="visible">True</property>
+			      <property name="homogeneous">True</property>
+			      <property name="spacing">0</property>
+
+			      <child>
+				<widget class="GtkLabel" id="label51">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes">Name:</property>
+				  <property name="use_underline">False</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">1</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkLabel" id="label52">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes">Description:</property>
+				  <property name="use_underline">False</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">1</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkLabel" id="label59">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes">Value:</property>
+				  <property name="use_underline">False</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">1</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkLabel" id="label53">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes">Commodity:</property>
+				  <property name="use_underline">False</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">1</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkVBox" id="vbox6">
+			      <property name="border_width">3</property>
+			      <property name="visible">True</property>
+			      <property name="homogeneous">True</property>
+			      <property name="spacing">0</property>
+
+			      <child>
+				<widget class="GtkEntry" id="name_entry">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="editable">True</property>
+				  <property name="visibility">True</property>
+				  <property name="max_length">0</property>
+				  <property name="text" translatable="yes"></property>
+				  <property name="has_frame">True</property>
+				  <property name="invisible_char" translatable="yes">*</property>
+				  <property name="activates_default">False</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkEntry" id="description_entry">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="editable">True</property>
+				  <property name="visibility">True</property>
+				  <property name="max_length">0</property>
+				  <property name="text" translatable="yes"></property>
+				  <property name="has_frame">True</property>
+				  <property name="invisible_char" translatable="yes">*</property>
+				  <property name="activates_default">False</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkSpinButton" id="value_button">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="climb_rate">1</property>
+				  <property name="digits">2</property>
+				  <property name="numeric">False</property>
+				  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+				  <property name="snap_to_ticks">False</property>
+				  <property name="wrap">False</property>
+				  <property name="adjustment">1 0 1e+37 1 10 10</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkHBox" id="commodity_box">
+				  <property name="visible">True</property>
+				  <property name="homogeneous">False</property>
+				  <property name="spacing">0</property>
+
+				  <child>
+				    <placeholder/>
+				  </child>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label50">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Category Information</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="type">label_item</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkFrame" id="frame3">
+		      <property name="border_width">5</property>
+		      <property name="visible">True</property>
+		      <property name="label_xalign">0</property>
+		      <property name="label_yalign">0.5</property>
+		      <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox9">
+			  <property name="border_width">5</property>
+			  <property name="visible">True</property>
+			  <property name="homogeneous">True</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <widget class="GtkRadioButton" id="inflow_button">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label" translatable="yes">In Flow</property>
+			      <property name="use_underline">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="active">False</property>
+			      <property name="inconsistent">False</property>
+			      <property name="draw_indicator">True</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkRadioButton" id="outflow_button">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label" translatable="yes">Outflow</property>
+			      <property name="use_underline">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="active">False</property>
+			      <property name="inconsistent">False</property>
+			      <property name="draw_indicator">True</property>
+			      <property name="group">inflow_button</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label55">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Category Type</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="type">label_item</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="frequency_box">
+		  <property name="border_width">5</property>
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox7">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkFrame" id="frame4">
+		  <property name="border_width">5</property>
+		  <property name="visible">True</property>
+		  <property name="label_xalign">0</property>
+		  <property name="label_yalign">0.5</property>
+		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+		  <child>
+		    <widget class="GtkScrolledWindow" id="related_accounts_scroll">
+		      <property name="border_width">5</property>
+		      <property name="width_request">509</property>
+		      <property name="height_request">390</property>
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		      <property name="shadow_type">GTK_SHADOW_IN</property>
+		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		      <child>
+			<placeholder/>
+		      </child>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label56">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Related Accounts:</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		    <packing>
+		      <property name="type">label_item</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
Index: gnc-main-window-ui.xml
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/ui/Attic/gnc-main-window-ui.xml,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -Lsrc/gnome/ui/gnc-main-window-ui.xml -Lsrc/gnome/ui/gnc-main-window-ui.xml -u -r1.1.2.8 -r1.1.2.9
--- src/gnome/ui/gnc-main-window-ui.xml
+++ src/gnome/ui/gnc-main-window-ui.xml
@@ -58,6 +58,7 @@
         <menuitem name="ActionsSinceLastRun" action="ActionsSinceLastRunAction"/>
         <menuitem name="ActionsMortgageLoan" action="ActionsMortgageLoanAction"/>
       </menu>
+      <menuitem name="ActionsBudgetWorkbenchAction" action="ActionsBudgetWorkbenchAction"/>
       <placeholder name="ActionsPlaceholder"/>
       <menuitem name="ActionsCloseBooks" action="ActionsCloseBooksAction"/>
     </menu>
Index: gnc-trace.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-trace.c,v
retrieving revision 1.2.20.7
retrieving revision 1.2.20.8
diff -Lsrc/engine/gnc-trace.c -Lsrc/engine/gnc-trace.c -u -r1.2.20.7 -r1.2.20.8
--- src/engine/gnc-trace.c
+++ src/engine/gnc-trace.c
@@ -43,7 +43,7 @@
   GNC_LOG_WARNING,      /* REGISTER */
   GNC_LOG_WARNING,      /* LEDGER */
   GNC_LOG_WARNING,      /* HTML */
-  GNC_LOG_WARNING,      /* GUI */
+  GNC_LOG_DEBUG,      /* GUI */
   GNC_LOG_WARNING,      /* SCRUB */
   GNC_LOG_WARNING,      /* GTK_REG */
   GNC_LOG_WARNING,      /* GUILE */
--- /dev/null
+++ src/engine/gnc-budget-period-p.h
@@ -0,0 +1,49 @@
+/********************************************************************\
+ * gnc-budget-period-p.h --  Private structure definition of the        *
+ *                          budget period structure.                *
+ * Copyright (C) 16 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup engine
+ *     @{ */
+/** @file gnc-budget-period-p.h
+ *  @breif Private structure definition of the budget period structure.
+ *  @author Created by Darin Willits 16 sep 2003 
+ *  @author Copyright (c) 16 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ * A budget period is simply a begin and end date right now although
+ * it may eventually have to encapsulate more information.  Each budget
+ * category maintains a list of values each of which refers to a given 
+ * budget period object.
+ */
+
+#ifndef __GNC_BUDGET_PERIOD_P_H__
+#define __GNC_BUDGET_PERIOD_P_H__
+
+#include "gnc-budget-period.h"
+
+struct gncp_budget_period{
+    GDate start_date;
+    GDate end_date;
+};
+
+
+#endif // __GNC_BUDGET_PERIOD_P_H__
--- /dev/null
+++ src/engine/gnc-budget-cat.c
@@ -0,0 +1,568 @@
+/********************************************************************\
+ * gnc-budget-cat.c --  Implementation of the budget category methods.  *
+ * Copyright (C) 05 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup Engine
+ *     @{ */
+/** @file gnc-budget-cat.c
+ *  @breif Implementation of the budget category methods.
+ *  @author Created by Darin Willits 05 sep 2003 
+ *  @author Copyright (c) 05 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ *
+ */
+
+
+// Includes
+#include "config.h"
+#include <stdio.h>
+#include <time.h>
+
+#include "gnc-budget-cat-p.h"
+#include "qofid-p.h"
+#include "gnc-trace.h"
+#include "gnc-budget-period-value.h"
+#include "gnc-budget-period.h"
+
+static short module = MOD_GUI;
+
+GncBudgetCategory *gnc_budget_category_new(QofBook* book, GncBudget* budget)
+{
+    GncBudgetCategory* category;
+    GDate date;
+    GString* freqStr;
+
+    ENTER("book %p, budget %p", book, budget);
+    g_return_val_if_fail(book, NULL);
+
+    category = g_new0(GncBudgetCategory, 1);
+   
+    qof_instance_init (&category->inst, GNC_ID_BUDGET_CATEGORY, book);
+
+    // The interface for this has been changed to the above line.
+    //category->entity_table = qof_book_get_entity_table (book);
+    //qof_entity_guid_new (category->entity_table, &category->guid);
+
+    //qof_entity_store( category->entity_table, category,
+    //                &category->guid, GNC_ID_BUDGET_CATEGORY );
+ 
+    category->budget = budget;
+    category->value = gnc_numeric_zero();
+    
+    category->freq = xaccFreqSpecMalloc(book);
+    g_date_clear(&date, 1);
+    g_date_set_time(&date, time(NULL));
+    if(g_date_valid(&date) == FALSE){
+        //printf("Invalid Date!\n");
+    }
+    xaccFreqSpecSetMonthly(category->freq, &date, 1);
+    xaccFreqSpecSetUIType(category->freq, UIFREQ_MONTHLY);
+    
+    freqStr = g_string_sized_new(16);
+    xaccFreqSpecGetFreqStr(category->freq, freqStr);
+    //printf("Category Freq: %s\n", freqStr->str);
+
+
+    LEAVE("category: %p", category);
+    return category;
+}
+
+static void delete_child(gpointer data, gpointer user_data)
+{
+    GncBudgetCategory* category = (GncBudgetCategory*)data;
+    gnc_budget_category_delete(category);
+}
+
+
+void gnc_budget_category_delete(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return;
+    }
+    
+    if(category->name){
+        g_free(category->name);
+    }
+    if(category->description){
+        g_free(category->description);
+    }
+
+    // Now use qof_instance_release.
+    //qof_entity_remove(category->entity_table, &category->guid);
+    g_list_free(category->accountList);
+
+    xaccFreqSpecFree(category->freq);
+
+    g_list_foreach(category->children, delete_child, NULL);
+    
+
+    /* Remove us from our parents list. */
+    if(category->parent != NULL){
+        gnc_budget_category_remove_child(category->parent, category);
+    }
+    
+    qof_instance_release(&category->inst);
+    g_free(category);
+}
+
+void gnc_budget_category_set_name(GncBudgetCategory* category, const gchar* name)
+{
+    g_return_if_fail( name != NULL );
+    if ( category->name != NULL ) {
+        g_free( category->name );
+        category->name = NULL;
+    }
+    category->name = g_strdup( name );
+}
+
+gchar* gnc_budget_category_get_name(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return NULL;
+    }
+    return category->name;
+}
+
+void gnc_budget_category_set_description(GncBudgetCategory* category, const gchar* description)
+{
+    g_return_if_fail(description != NULL);
+    if(category->description != NULL){
+        g_free(category->description);
+        category->description = NULL;
+    }
+    category->description = g_strdup(description);
+}
+
+gchar* gnc_budget_category_get_description(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return NULL;
+    }
+    return category->description;
+}
+
+void gnc_budget_category_set_value(GncBudgetCategory* category, gnc_numeric value)
+{
+    if(category == NULL){
+        return;
+    }
+    category->value = value;
+}
+
+gnc_numeric gnc_budget_category_get_value(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return gnc_numeric_zero();
+    }
+    return category->value;
+}
+
+void gnc_budget_category_add_account(GncBudgetCategory* category, Account* account)
+{
+    if(category == NULL){
+        return;
+    }
+    category->accountList = g_list_append(category->accountList, account);
+
+    /* If our commodity hasn't been set yet we might as well take it
+     * from the account we have just been given. */
+    if(category->commodity == NULL){
+        category->commodity = xaccAccountGetCommodity(account);
+    }
+}
+
+void gnc_budget_category_remove_account(GncBudgetCategory* category, Account* account)
+{
+    if(category == NULL){
+        return;
+    }
+    category->accountList = g_list_remove(category->accountList, account);
+}
+
+AccountList* gnc_budget_category_get_related_accounts(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return NULL;
+    }
+    return category->accountList;
+}
+
+void gnc_budget_category_set_related_accounts(GncBudgetCategory* category, AccountList* accounts)
+{
+    if(category == NULL){
+        return;
+    }
+
+    if(category->accountList != NULL){
+        g_list_free(category->accountList);   
+        category->accountList = NULL;
+    }
+
+    category->accountList = accounts;
+}
+
+void gnc_budget_category_set_frequency(GncBudgetCategory* category, FreqSpec* freq)
+{
+    if(category == NULL){
+        return;
+    }
+    category->freq = freq;
+}
+
+FreqSpec* gnc_budget_category_get_frequency(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return NULL;
+    }
+    return category->freq;
+}
+
+void gnc_budget_category_set_type(GncBudgetCategory* category, GncBudgetCategoryType type)
+{
+    if(category == NULL){
+        return;
+    }
+    category->type = type;
+}
+
+GncBudgetCategoryType gnc_budget_category_get_type(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return -1;
+    }
+    return category->type;
+}
+
+void gnc_budget_category_set_commodity(GncBudgetCategory* category, gnc_commodity* commodity)
+{
+    if(category == NULL){
+        return;
+    }
+    category->commodity = commodity;
+}
+
+gnc_commodity* gnc_budget_category_get_commodity(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return NULL;
+    }
+    return category->commodity;
+}
+
+void gnc_budget_category_add_child(GncBudgetCategory* parent, GncBudgetCategory* child)
+{
+    if((parent == NULL) || (child == NULL)){
+        return;
+    }
+    if(child->parent != NULL){
+        /* Remove the child account from its previous parents list. */
+        child->parent->children = g_list_remove(child->parent->children, child);
+    }
+    parent->children = g_list_append(parent->children, child);
+    child->parent = parent;
+}
+
+void gnc_budget_category_remove_child(GncBudgetCategory* parent, GncBudgetCategory* child)
+{
+    if((parent == NULL) || (child == NULL)){
+        return;
+    }
+    parent->children = g_list_remove(parent->children, child);
+}
+
+GncBudgetCategory* gnc_budget_category_get_child(GncBudgetCategory* parent, gint index)
+{
+    if(parent == NULL){
+        return NULL;
+    }
+    return g_list_nth_data(parent->children, index);
+}
+
+GncBudgetCategoryList* gnc_budget_category_get_children(GncBudgetCategory* parent)
+{
+    if(parent == NULL){
+        return NULL;
+    }
+    return parent->children;
+}
+
+gint gnc_budget_category_get_num_children(GncBudgetCategory* parent)
+{
+    if(parent == NULL){
+        return -1;
+    }
+    return g_list_length(parent->children);
+}
+
+GncBudgetCategory* gnc_budget_category_get_parent(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return NULL;
+    }
+    return category->parent;
+}
+
+gint gnc_budget_category_get_index_in_parent_list(GncBudgetCategory* category)
+{
+    if(category == NULL){
+        return -1;
+    }
+    if(category->parent == NULL){
+        return 0;
+    }
+    return g_list_index(category->parent->children, category);
+}
+
+/*
+ * Nice idea but not necessary.
+static gint calculate_mulitplier(FreqSpec* freq, GDate* start_date, GDate* end_date)
+{
+    gint multiplier = 0;
+    gboolean done = FALSE;
+    GDate* outDate, *inDate;
+    inDate = g_date_new_dmy(   g_date_get_day(start_date),
+                                g_date_get_month(start_date),
+                                g_date_get_year(start_date));
+    outDate = g_date_new();
+    g_date_clear(outDate, 1);
+
+
+    while(!done){
+        xaccFreqSpecGetNextInstance(freq, inDate, outDate);
+        if(!g_date_valid(outDate)){
+            break;
+        }
+        
+        if(g_date_compare(outDate, end_date) < 0){
+            multiplier++;
+            g_date_set_dmy(inDate, g_date_get_day(outDate),
+                                    g_date_get_month(outDate),
+                                    g_date_get_year(outDate));
+        }
+        else{
+            done = TRUE;
+        }
+    }
+    
+    g_date_free(inDate);
+    g_date_free(outDate);
+    
+    return multiplier;
+}
+
+
+GncBudgetValue* budget_value_new()
+{
+    GncBudgetValue* value;
+
+    value = g_new0(GncBudgetValue, 1);
+    value->value = gnc_numeric_zero();
+    value->adjustment = gnc_numeric_zero();
+
+    return value;
+}
+*/
+
+/* Find out how many occurences of the given frequency spec fall within the 
+ * given dates.  
+ * TODO: This should probably be moved to the FreqSpec public interface.
+ */
+static gint find_num_occurences(FreqSpec* a, const GDate* startDate, const GDate* endDate)
+{
+    GDate outDate;
+    GDate curDate;
+    
+    g_date_set_dmy(&curDate, g_date_day(startDate),
+                             g_date_month(startDate),
+                             g_date_year(startDate));
+
+    gint counter = 0;
+
+    do{
+        xaccFreqSpecGetNextInstance(a, &curDate, &outDate);
+        if(g_date_valid(&outDate) == FALSE){
+            break;
+        }
+
+        if(g_date_compare(&outDate, endDate) <= 0){
+            counter++;
+            g_date_set_dmy(&curDate, g_date_day(&outDate),
+                                    g_date_month(&outDate),
+                                    g_date_year(&outDate));
+        }
+        else{
+            break;
+        }
+    }while(1);
+
+    return counter;
+}
+
+/* Generate the budget value for the given period.
+ */
+static void generate_budget_value_for_period(gpointer data, gpointer user_data)
+{
+    GncBudgetCategory* category = user_data;
+    GncBudgetPeriod* period = data;
+    GDate* periodStartDate, *periodEndDate;
+    FreqSpec* periodFreq, *catFreq;
+    int compare;
+    GncBudgetPeriodValue* periodValue;
+    gint multiplier;
+    double value;
+    
+    periodFreq = gnc_budget_get_period_frequency(category->budget);
+    catFreq = gnc_budget_category_get_frequency(category);
+    
+    periodStartDate = gnc_budget_period_get_start_date(period);
+    periodEndDate = gnc_budget_period_get_end_date(period);
+   
+    compare = gnc_freq_spec_compare(periodFreq, catFreq);
+    
+    /* If the frequencies are the same we can just fill in the value 
+     * from the categories value.  Otherwise we have to find out how many
+     * of the categories frequencies fall within the given period and and 
+     * multiply by the categories value.
+     */
+    if(compare == 0){
+        value = gnc_numeric_to_double(category->value);
+        //printf("Frequencies equal: %0.2f\n", value);
+        periodValue = gnc_budget_period_value_new();
+        gnc_budget_period_value_set_value_double(periodValue, value);
+        category->period_values = g_list_append(category->period_values, periodValue);
+    }
+    else{
+        multiplier = find_num_occurences(catFreq, periodStartDate, periodEndDate);
+        value = gnc_numeric_to_double(category->value) * multiplier;
+        //printf("Period Freq larger: %0.2f\n", value);
+        periodValue = gnc_budget_period_value_new();
+        gnc_budget_period_value_set_value_double(periodValue, value);
+        category->period_values = g_list_append(category->period_values, periodValue);
+    }
+    
+}
+
+static void category_generate_values(gpointer data, gpointer user_data)
+{
+    GncBudgetCategory* category = data;
+    
+    gnc_budget_category_generate_values(category);
+}
+
+static void free_budget_value(gpointer data, gpointer user_data)
+{
+    GncBudgetPeriodValue* periodValue = data;
+    gnc_budget_period_value_delete(periodValue);
+}
+
+void gnc_budget_category_generate_values(GncBudgetCategory* category)
+{
+    GList* period_list;
+    double value;
+
+    if(category == NULL){
+        return;
+    }
+
+    /* Delete all the old values if there are any cause we are going to 
+     * re-evaluate them all.
+     */
+    if(category->period_values != NULL){
+        g_list_foreach(category->period_values, free_budget_value, NULL);
+        g_list_free(category->period_values);
+        category->period_values = NULL;
+    }
+    
+    value = gnc_numeric_to_double(category->value);
+    //printf("Category Value: %0.2f\n", value);
+
+    period_list = gnc_budget_get_period_list(category->budget);
+    
+    g_list_foreach(period_list, generate_budget_value_for_period, category);
+
+    /* Now generate the value lists for our kids.
+     * Should this really do this?? Maybe categories with children
+     * should have the sum of their kids values as their own ala the
+     * accounts.  Have to think on this some more... for now the quick and 
+     * dirty.
+     */
+    //printf("Doing children for category: %s\n", category->name);
+    g_list_foreach(category->children, category_generate_values, NULL);
+}
+
+gnc_numeric gnc_budget_category_get_value_by_index(GncBudgetCategory* category, gint index)
+{
+    GncBudgetPeriodValue* periodValue;
+
+    if(category == NULL){
+        return gnc_numeric_zero();
+    }
+    
+    periodValue = g_list_nth_data(category->period_values, index);
+
+    if(periodValue == NULL){
+        return gnc_numeric_zero();
+    }
+    
+    return gnc_budget_period_value_get_value(periodValue); 
+}
+
+void gnc_budget_category_set_period_value_by_index(GncBudgetCategory* category, gint index, 
+                                                    gnc_numeric value)
+{
+    GncBudgetPeriodValue* periodValue;
+
+    if(category == NULL){
+        return;
+    }
+
+    periodValue = g_list_nth_data(category->period_values, index);
+
+    if(periodValue == NULL){
+        return;
+    }
+
+    gnc_budget_period_value_set_value(periodValue, value);
+}
+
+/* This is a cheat method right now to give meaningfull values for the
+ * display.  We should probably NEVER return doubles as we could then
+ * potentially encounter rounding errors.  All calculations should be done
+ * in terms of the gnc_numeric value.
+ */
+double gnc_budget_category_sum_child_values_by_index(GncBudgetCategory* category, gint index)
+{
+    double sum = 0.0;
+    GList* childList;
+
+    if(category == NULL){
+        return 0.00;
+    }
+
+    childList = category->children;
+    
+    for(;childList; childList = childList->next){
+        sum += gnc_numeric_to_double(gnc_budget_category_get_value_by_index(childList->data, index));
+    }
+    
+    return sum;
+}
--- /dev/null
+++ src/engine/gnc-budget-period.c
@@ -0,0 +1,87 @@
+/********************************************************************\
+ * gnc-budget-period.c --  Implementation of the budget period      *
+ *                      interface.                                  *
+ * Copyright (C) 16 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup engine
+ *     @{ */
+/** @file gnc-budget-period.c
+ *  @breif Implementation of the budget period interface.
+ *  @author Created by Darin Willits 16 sep 2003 
+ *  @author Copyright (c) 16 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+
+// Includes
+#include <glib.h>
+
+#include "gnc-budget-period.h"
+#include "gnc-budget-period-p.h"
+
+GncBudgetPeriod* gnc_budget_period_new(void)
+{
+    GncBudgetPeriod* period;
+
+    period = g_new0(GncBudgetPeriod, 1);
+
+    g_date_clear(&period->start_date, 1);
+    g_date_clear(&period->end_date, 1);
+
+    return period;
+}
+
+void gnc_budget_period_set_start_date(GncBudgetPeriod* period, GDate* startDate)
+{
+    if(period == NULL){
+        return;
+    }
+    period->start_date = *startDate;
+}
+
+GDate* gnc_budget_period_get_start_date(GncBudgetPeriod* period)
+{
+    if(period == NULL){
+        return NULL;
+    }
+    return &period->start_date;
+}
+
+
+
+void gnc_budget_period_set_end_date(GncBudgetPeriod* period, GDate* endDate)
+{
+    if(period == NULL){
+        return;
+    }
+    period->end_date = *endDate;
+}
+
+GDate* gnc_budget_period_get_end_date(GncBudgetPeriod* period)
+{
+    if(period == NULL){
+        return NULL;
+    }
+    return &period->end_date;
+}
+
+
--- /dev/null
+++ src/engine/gnc-budget-book-p.h
@@ -0,0 +1,53 @@
+/********************************************************************\
+ * gnc-budget-book-p.h --  Private functions for budget/book linkage*
+ * Copyright (C) 04 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup Engine
+ *     @{ */
+/** @file gnc-budget-book-p.h
+ *  @breif Private functions for budget/book linkage.
+ *  @author Created by Darin Willits 04 sep 2003 
+ *  @author Copyright (c) 04 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ * 
+ */
+
+#ifndef __GNC_BUDGETBOOK_P_H__
+#define __GNC_BUDGETBOOK_P_H__
+
+#include "qofbook.h"
+#include "gnc-budget-book.h"
+
+struct xaccBudgetsDef{
+
+    QofBook *book;
+    GList   *budget_list;
+    gboolean budget_notsaved;
+    
+};
+
+/** Associate the given budget list to the book.*/
+void gnc_book_set_budgets( QofBook *book, GList *newList );
+
+gboolean gnc_budget_register (void);
+
+#endif // __BUDGETBOOK_P_H__
Index: gnc-engine.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-engine.h,v
retrieving revision 1.16.4.5
retrieving revision 1.16.4.6
diff -Lsrc/engine/gnc-engine.h -Lsrc/engine/gnc-engine.h -u -r1.16.4.5 -r1.16.4.6
--- src/engine/gnc-engine.h
+++ src/engine/gnc-engine.h
@@ -73,6 +73,8 @@
 #define GNC_ID_PRICEDB        "PriceDB"
 #define GNC_ID_SPLIT          "Split"
 #define GNC_ID_SCHEDXACTION   "SchedXaction"
+#define GNC_ID_BUDGET         "Budget"
+#define GNC_ID_BUDGET_CATEGORY "BudgetCategory"
 #define GNC_ID_SXTG           "SXTGroup"
 #define GNC_ID_SXTT           "SXTTrans"
 #define GNC_ID_TRANS          "Trans"
--- /dev/null
+++ src/engine/gnc-budget-cat.h
@@ -0,0 +1,187 @@
+/********************************************************************\
+ * gnc-budget-cat.h -- Public interface for the budget category.    *
+ * Copyright (C) 05 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                 *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup Engine
+ *     @{ */
+/** @file gnc-budget-cat.h
+ *  @breif Public interface of the budget category structure.
+ *  @author Created by Darin Willits 05 sep 2003 
+ *  @author Copyright (c) 05 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ *  A budget category encapsulates the concept of a single budgetable
+ *  item.  By default a category is linked to a single account from
+ *  account tree.  However a category can be linked to any number of 
+ *  regular accounts including none at all.  Hopefully this flexibility
+ *  will allow different users to utilize the budgeting engine to capture
+ *  their own concept of budgeting.
+ *
+ *  This is pre-alpha software.  Beware.
+ */
+
+#ifndef __GNC_BUDGET_CAT_H__
+#define __GNC_BUDGET_CAT_H__
+
+#include <glib.h>
+
+/** The budget data.*/
+typedef struct gncp_budget_category GncBudgetCategory;
+typedef GList GncBudgetCategoryList;
+
+#include "Account.h"
+#include "gnc-numeric.h"
+#include "qofbook.h"
+#include "gnc-budget.h"
+#include "FreqSpec.h"
+
+
+typedef enum{
+    BUDGET_CATEGORY_INFLOW,
+    BUDGET_CATEGORY_OUTFLOW,
+} GncBudgetCategoryType;
+
+
+/**
+ * Creates and initializes a Budget Category.
+ **/
+GncBudgetCategory *gnc_budget_category_new(QofBook* book, GncBudget* budget);
+
+/** Deletes the given budget category object.*/
+void gnc_budget_category_delete(GncBudgetCategory* category);
+
+/**  Set the Name of the Budget Category.
+ */
+void gnc_budget_category_set_name(GncBudgetCategory* category, const gchar* name);
+
+/**  Retieve the Name of the Budget.
+ */
+gchar* gnc_budget_category_get_name(GncBudgetCategory* category);
+
+/**  Set the Description of the Budget Category.
+ */
+void gnc_budget_category_set_description(GncBudgetCategory* category, const gchar* description); 
+
+/**  Retieve the Description of the Budget.
+ */
+gchar* gnc_budget_category_get_description(GncBudgetCategory* category);
+
+
+/** Set the value for this budget category.
+ */
+void gnc_budget_category_set_value(GncBudgetCategory* category, gnc_numeric value);
+
+/** Retrieve the value for this budget category.
+ */
+gnc_numeric gnc_budget_category_get_value(GncBudgetCategory* category);
+
+/* Add the account to the list of accounts.
+ */
+void gnc_budget_category_add_account(GncBudgetCategory* category, Account* account);
+
+/* Remove the account from the list of accounts.
+ */
+void gnc_budget_category_remove_account(GncBudgetCategory* category, Account* account);
+
+/* Return the list of related accounts.
+ */
+AccountList* gnc_budget_category_get_related_accounts(GncBudgetCategory* category);
+
+/* Set the list of related accounts to the one given.
+ * Delete the current list if it exists.
+ */
+void gnc_budget_category_set_related_accounts(GncBudgetCategory* category, AccountList* accounts);
+
+
+/* Set the frequency.
+ */
+void gnc_budget_category_set_frequency(GncBudgetCategory* category, FreqSpec* freq);
+
+/** Retrieve the frequency. 
+ */
+FreqSpec* gnc_budget_category_get_frequency(GncBudgetCategory* category);
+
+
+/** Set the budget category type
+ */
+void gnc_budget_category_set_type(GncBudgetCategory* category, GncBudgetCategoryType type);
+
+/** Retrieve the category type.
+ */
+GncBudgetCategoryType gnc_budget_category_get_type(GncBudgetCategory* category);
+
+/** Set the commodity.
+ */
+void gnc_budget_category_set_commodity(GncBudgetCategory* category, gnc_commodity* commodity);
+
+/* Retrieve the commodity.
+ */
+gnc_commodity* gnc_budget_category_get_commodity(GncBudgetCategory* category);
+
+
+/* Add a category to our list of children.
+ */
+void gnc_budget_category_add_child(GncBudgetCategory* parent, GncBudgetCategory* child);
+
+/* Remove a category to our list of children.
+ */
+void gnc_budget_category_remove_child(GncBudgetCategory* parent, GncBudgetCategory* child);
+
+/* Retrieve a child category from the given index.
+ */
+GncBudgetCategory* gnc_budget_category_get_child(GncBudgetCategory* parent, gint index);
+
+/** Retrieve the entire list of our children.
+ */
+GncBudgetCategoryList* gnc_budget_category_get_children(GncBudgetCategory* parent);
+
+/** Get the number of child account we have.
+ */
+gint gnc_budget_category_get_num_children(GncBudgetCategory* parent);
+
+/* Return the parent of this category.
+ */
+GncBudgetCategory* gnc_budget_category_get_parent(GncBudgetCategory* category);
+
+/** Return the position of this category in its parents list. */
+gint gnc_budget_category_get_index_in_parent_list(GncBudgetCategory* category);
+
+
+/* Generate the budget values.
+ * This function will generate the list of budget values based on the 
+ * list of periods in the associated budget object.
+ */
+void gnc_budget_category_generate_values(GncBudgetCategory* category);
+
+/* Retrieve the budget value based on an index.
+ */
+gnc_numeric gnc_budget_category_get_value_by_index(GncBudgetCategory* category, gint index);
+
+/* Set the period value at the given index.
+ */
+void gnc_budget_category_set_period_value_by_index(GncBudgetCategory* category, gint index, 
+                                                    gnc_numeric value);
+
+/** Get the sum of values for child accounts at the given period index.
+ */
+double gnc_budget_category_sum_child_values_by_index(GncBudgetCategory* category, gint index);
+
+#endif // __BUDGET_CAT_H__
--- /dev/null
+++ src/engine/gnc-budget.h
@@ -0,0 +1,187 @@
+/********************************************************************\
+ * gnc-budget.h -- Budget public handling routines.                     *
+ * Copyright (C) 04 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+
+/** @addtogroup Engine
+ *     @{ */
+/** @file gnc-budget.h
+ *  @breif Public interface for budget objects.
+ *  @author Created by Darin Willits 04 sep 2003 
+ *  @author Copyright (c) 04 Darin Willits <darin at willits.ca>
+ *
+ * This file contains the public methods to interact with a budgeting
+ * object. A budget object contains a list of budget_categories each of 
+ * which define an individual budgetable item.  When a budget is first
+ * created these catagories will be initialized based on the existing 
+ * account hierarchy.
+ *
+ * This is pre-alpha code right now.  User beware.
+ */
+
+
+#ifndef __GNC_BUDGET_H__
+#define __GNC_BUDGET_H__
+
+#include <glib.h>
+
+/** The budget data.*/
+typedef struct gncp_budget GncBudget;
+
+#include "guid.h"
+#include "qofbook.h"
+#include "gnc-budget-cat.h"
+#include "FreqSpec.h"
+
+
+/**
+ * Creates and initializes a Budget.
+ **/
+GncBudget *gnc_budget_new(QofBook *book);
+
+/** Deletes the given budget object.*/
+void gnc_budget_delete(GncBudget* budget);
+
+
+
+/**  Set the Name of the Budget.
+ */
+void gnc_budget_set_name(GncBudget* budget, const gchar* name);
+
+/**  Retieve the Name of the Budget.
+ */
+gchar* gnc_budget_get_name(GncBudget* budget);
+
+
+
+/**  Set the Description of the Budget.
+ */
+void gnc_budget_set_description(GncBudget* budget, const gchar* description);
+
+/**  Retieve the Description of the Budget.
+ */
+gchar* gnc_budget_get_description(GncBudget* budget);
+
+
+
+/** Set the period frequency.
+ */
+void gnc_budget_set_period_frequency(GncBudget* budget, FreqSpec* period);
+
+/** Get the period frequency.
+ */
+FreqSpec* gnc_budget_get_period_frequency(GncBudget* budget);
+
+
+
+/** Set the start date*/
+void gnc_budget_set_start_date(GncBudget* budget, GDate* date);
+
+/** Return the start date */
+GDate* gnc_budget_get_start_date(GncBudget* budget);
+
+
+/** Set the Length for this budget in terms of a number of months.
+ */
+void gnc_budget_set_length_months(GncBudget* budget, gint months);
+
+/** Set the Length for this budget in terms of a number of months.
+ */
+void gnc_budget_set_length_years(GncBudget* budget, gint years);
+
+/** Retrieve the Length for this budget in number of months.
+ */
+gint gnc_budget_get_length_months(GncBudget* budget);
+
+/** Retrieve the Length for this budget in number of years.
+ */
+gint gnc_budget_get_length_years(GncBudget* budget);
+
+
+
+/* Add the inflow category for this budget.  
+ * This is a wrapper function to make it easier to add a category
+ * as a child of the inflow category.  It's here cause I'm a lazy ass.
+ */
+void gnc_budget_add_inflow_category(GncBudget* budget, GncBudgetCategory* inflow);
+
+/* Remove the inflow category for this budget.  
+ */
+void gnc_budget_remove_inflow_category(GncBudget* budget, GncBudgetCategory* category);
+
+/* Set the inflow category for this budget.  
+ */
+void gnc_budget_set_inflow_category(GncBudget* budget, GncBudgetCategory* inflow);
+
+/** Retrieve the inflow category for this budget. 
+ */
+GncBudgetCategory* gnc_budget_get_inflow_category(GncBudget* budget);
+
+
+
+
+/* Add the outflow category for this budget.  
+ */
+void gnc_budget_add_outflow_category(GncBudget* budget, GncBudgetCategory* outflow);
+
+/* Remove the outflow category for this budget.  
+ */
+void gnc_budget_remove_outflow_category(GncBudget* budget, GncBudgetCategory* inflow);
+
+/* Set the outflow category for this budget.  
+ */
+void gnc_budget_set_outflow_category(GncBudget* budget, GncBudgetCategory* category);
+
+/** Retrieve the outflow category for this budget. 
+ */
+GncBudgetCategory* gnc_budget_get_outflow_category(GncBudget* budget);
+
+
+
+/** Retrieve the book that this budget is associated with.*/
+QofBook* gnc_budget_get_book(GncBudget* budget);
+
+
+/** Generate the list of periods.
+ * This function will use the start date and budget length to generate a 
+ * list of budget periods.  The periods are represented by a list of start
+ * dates for each period.
+ * As well this function regenerates the list of values for each
+ * category.
+ * */
+void gnc_budget_generate_periods(GncBudget* budget);
+
+/** Get the number of periods.
+ */
+gint gnc_budget_get_num_periods(GncBudget* budget);
+
+/* Return the list of periods.
+ */
+GList* gnc_budget_get_period_list(GncBudget* budget);
+
+
+/** Retrieve the budget object associated with the given GUID from 
+ * the given book.
+ */
+GncBudget* gnc_budget_lookup (const GUID *guid, QofBook *book);
+
+#endif // __BUDGET_H__
--- /dev/null
+++ src/engine/gnc-budget-period-value-p.h
@@ -0,0 +1,52 @@
+/********************************************************************\
+ * gnc-budget-period-value-p.h -- Private structure definition of the   *
+ *                              budget period value objects.        *
+ * Copyright (C) 16 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup engine
+ *     @{ */
+/** @file gnc-budget-period-value-p.h
+ *  @breif Private structure definition of the budget period value 
+ *          structure.
+ *  @author Created by Darin Willits 16 sep 2003 
+ *  @author Copyright (c) 16 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ * A budget period value is the value associated with each budget period.
+ * Each category maintains a list of these values.  If the budget period
+ * is changed this list needs to be regenerated.
+ * Note: We should probably add a reference here to the actual budget
+ * period we are referring to.  Right now we just depend on their order
+ * in their respective lists.
+ */
+
+#ifndef __GNC_BUDGET_PERIOD_VALUE_P_H__
+#define __GNC_BUDGET_PERIOD_VALUE_P_H__
+
+#include "gnc-budget-period-value.h"
+
+struct gncp_budget_period_value{
+    gnc_numeric value;
+    gnc_numeric adjustment;
+};
+
+
+#endif // __GNC_BUDGET_PERIOD_VALUE_P_H__
--- /dev/null
+++ src/engine/gnc-budget-period-value.c
@@ -0,0 +1,85 @@
+/********************************************************************\
+ * gnc-budget-period-value.c --  Implmentation of the budget period     *
+ *                              value structure.                    *
+ * Copyright (C) 16 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup engine
+ *     @{ */
+/** @file gnc-budget-period-value.c
+ *  @breif Implementation of the budget-period-value structure.
+ *  @author Created by Darin Willits 16 sep 2003 
+ *  @author Copyright (c) 16 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+// Includes
+#include "gnc-budget-period-value.h"
+#include "gnc-budget-period-value-p.h"
+#include "gnc-numeric.h"
+
+GncBudgetPeriodValue* gnc_budget_period_value_new(void)
+{
+    GncBudgetPeriodValue* periodValue;
+
+    periodValue = g_new0(GncBudgetPeriodValue, 1);
+
+    periodValue->value = gnc_numeric_zero();
+    periodValue->adjustment = gnc_numeric_zero();
+
+    return periodValue;
+}
+
+void gnc_budget_period_value_delete(GncBudgetPeriodValue* periodValue)
+{
+    g_free(periodValue);
+}
+
+
+
+void gnc_budget_period_value_set_value(GncBudgetPeriodValue* periodValue, gnc_numeric value)
+{
+    if(periodValue == NULL){
+        return;
+    }
+    periodValue->value = value;
+}
+
+void gnc_budget_period_value_set_value_double(GncBudgetPeriodValue* periodValue, double value)
+{
+    if(periodValue == NULL){
+        return;
+    }
+    periodValue->value = double_to_gnc_numeric(value, 1, GNC_RND_NEVER);
+}
+
+gnc_numeric gnc_budget_period_value_get_value(GncBudgetPeriodValue* periodValue)
+{
+    if(periodValue == NULL){
+        return gnc_numeric_zero();
+    }
+    return periodValue->value;
+}
+
+
+
+
+
--- /dev/null
+++ src/engine/gnc-budget-book.h
@@ -0,0 +1,60 @@
+/********************************************************************\
+ * gnc-budget-book.h -- Linkage between budgets and books.          *
+ * Copyright (C) 04 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup Engine
+ *     @{ */
+/** @file gnc-budget-book.h
+ *  @breif Linkage between budgets and books.
+ *  @author Created by Darin Willits 04 sep 2003 
+ *  @author Copyright (c) 04 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ * 
+ */
+
+#ifndef __GNC_BUDGETBOOK_H__
+#define __GNC_BUDGETBOOK_H__
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "qofbook.h"
+#include "gnc-budget.h"
+#include "gnc-engine.h"
+
+
+typedef struct xaccBudgetsDef GncBudgets;
+
+/** Retrieve the budget list structure for the given book. */
+GncBudgets* gnc_book_get_budget_list( QofBook *book );
+
+/** Retrieve the list of budgets for the given book.*/
+GList* gnc_book_get_budgets( QofBook *book );
+
+/** Add the given budget to the list of budgets for the given book. */
+void gnc_book_add_budget(QofBook* book, GncBudget* budget);
+
+/** Delete the given budget from the list of budgets for the given book. */
+void gnc_book_delete_budget(QofBook* book, GncBudget* budget);
+
+#endif // __BUDGETBOOK_H__
--- /dev/null
+++ src/engine/gnc-budget-p.h
@@ -0,0 +1,67 @@
+/********************************************************************\
+ * gnc-budget-p.h -- Private structure defintion for the budget object. *
+ * Copyright (C) 04 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup Engine
+ *     @{ */
+/** @file gnc-budget-p.h
+ *  @breif Private structure definition for the budget object.
+ *  @author Created by Darin Willits 04 sep 2003 
+ *  @author Copyright (c) 04 Darin Willits <darin at willits.ca>
+ *
+ *  
+ */
+
+#ifndef __GNC_BUDGET_P_H__
+#define __GNC_BUDGET_P_H__
+
+#include <glib.h>
+#include "qofbook.h"
+#include "guid.h"
+#include "gnc-budget.h"
+#include "FreqSpec.h"
+#include "qofinstance-p.h"
+
+struct gncp_budget{
+
+    QofInstance     inst;
+    
+    char* name;
+    char* description;
+    
+    FreqSpec* period_freq;
+    GDate start_date;
+    gint  length;
+
+    GList* period_list;
+
+    GncBudgetCategory* inflow_category;
+    GncBudgetCategory* outflow_category;
+
+    /** FIXME: I think we actually have access to this value
+     * through the OofInstance member.  We should probably 
+     * use that one to reduce confusion and duplication. */
+    QofBook*        book;
+};
+
+
+#endif // __GNC_BUDGET_P_H__
--- /dev/null
+++ src/engine/gnc-budget-period.h
@@ -0,0 +1,67 @@
+/********************************************************************\
+ * gnc-budget-period.h -- Public interface for the budget period        *
+ *                      structure.                                  *
+ * Copyright (C) 16 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup engine
+ *     @{ */
+/** @file gnc-budget-period.h
+ *  @breif Public interface for the budget period structure.
+ *  @author Created by Darin Willits 16 sep 2003 
+ *  @author Copyright (c) 16 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ * A budget period is simply a begin and end date right now although
+ * it may eventually have to encapsulate more information.  Each budget
+ * category maintains a list of values each of which refers to a given 
+ * budget period object.
+ */
+
+#ifndef __GNC_BUDGET_PERIOD_H__
+#define __GNC_BUDGET_PERIOD_H__
+
+#include <glib.h>
+
+typedef struct gncp_budget_period GncBudgetPeriod;
+
+/* Create a new budget period object.
+ */
+GncBudgetPeriod* gnc_budget_period_new(void);
+
+/** Set the start date for the period.
+ */
+void gnc_budget_period_set_start_date(GncBudgetPeriod* period, GDate* startDate);
+
+/* Get the start date for the period.
+ */
+GDate* gnc_budget_period_get_start_date(GncBudgetPeriod* period);
+
+
+/** Set the end date for the period.
+ */
+void gnc_budget_period_set_end_date(GncBudgetPeriod* period, GDate* endDate);
+
+/* Get the end date for the period.
+ */
+GDate* gnc_budget_period_get_end_date(GncBudgetPeriod* period);
+
+
+#endif // __BUDGET_PERIOD_H__
--- /dev/null
+++ src/engine/gnc-budget-cat-p.h
@@ -0,0 +1,67 @@
+/********************************************************************\
+ * gnc-budget-cat-p.h -- Definition of the budget category structure.   *
+ * Copyright (C) 05 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup Engine
+ *     @{ */
+/** @file gnc-budget-cat-p.h
+ *  @breif Definition of the private budget category structure.
+ *  @author Created by Darin Willits 05 sep 2003 
+ *  @author Copyright (c) 05 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+#ifndef __GNC_BUDGET_CAT_P_H__
+#define __GNC_BUDGET_CAT_P_H__
+
+#include "gnc-numeric.h"
+#include "gnc-budget-cat.h"
+#include "gnc-budget.h"
+#include "Account.h"
+#include "FreqSpec.h"
+#include "qofbook.h"
+#include "gnc-engine.h"
+#include "qofinstance-p.h"
+
+struct gncp_budget_category{
+
+    QofInstance     inst;
+    
+    char*       name;
+    char*       description;
+    GncBudget*  budget;
+
+    gnc_numeric value;
+    GncBudgetCategoryType type;
+    gnc_commodity* commodity;
+    GList* period_values;
+
+    GncBudgetCategory* parent;
+    GncBudgetCategoryList* children;
+    
+    GList* accountList;    
+
+    FreqSpec*   freq;
+};
+
+
+#endif // __BUDGET_CAT_P_H__
--- /dev/null
+++ src/engine/gnc-budget-book.c
@@ -0,0 +1,200 @@
+/********************************************************************\
+ * gnc-budget-book.c --  Implementation of the budget/book linkage.      *
+ * Copyright (C) 04 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @file gnc-budget-book.c
+ *  @breif Implementation of the book/budget linkage.
+ *  @author Created by Darin Willits 04 sep 2003 
+ *  @author Copyright (c) 2003 Darin Willits <darin at willits.ca>
+ *
+ *
+ */
+
+// Includes
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "gnc-engine.h"
+#include "gnc-trace.h"
+#include "gnc-engine-util.h"
+#include "gnc-event-p.h"
+
+#include "gnc-budget-book-p.h"
+#include "gnc-budget-p.h"
+
+#include "qofbook.h"
+#include "qofbook-p.h"
+#include "qofobject.h"
+
+#define GNC_BUDGETS "gnc_budgets"
+
+/* =========================================================== */
+
+/** Retrieve the budget list structure for the given book. */
+GncBudgets* gnc_book_get_budget_list( QofBook *book )
+{
+  if ( book == NULL ){
+    return NULL;
+  }
+  return qof_book_get_data (book, GNC_BUDGETS);
+} 
+
+/** Retrieve the list of budgets for the given book.*/
+GList* gnc_book_get_budgets( QofBook *book )
+{
+  GncBudgets *list;
+  if ( book == NULL ){
+    return NULL;
+  }
+  
+  list = qof_book_get_data (book, GNC_BUDGETS);
+  if (list){
+    return list->budget_list;
+  }
+  return NULL;
+}
+
+/** Associate the given budget list to the book.*/
+void gnc_book_set_budgets( QofBook *book, GList *newList )
+{
+  GncBudgets *old_list, *new_list;
+  if ( book == NULL ){
+    return;
+  }
+
+  old_list = qof_book_get_data (book,GNC_BUDGETS);
+  if (old_list && old_list->budget_list == newList){
+     /* Assume the worst, that any 'set' means the data has 
+      * changed, and needs to be saved. */
+     old_list->budget_notsaved = TRUE;
+     return;
+  }
+  
+  new_list = g_new (GncBudgets, 1);
+  new_list->book = book;
+  new_list->budget_list = newList;
+  new_list->budget_notsaved = TRUE;
+  
+  if (NULL == newList){
+      new_list->budget_notsaved = FALSE;
+  }
+  
+  qof_book_set_data (book, GNC_BUDGETS, new_list);
+
+  g_free (old_list);
+}
+
+/** Add the given budget to the list of budgets for the given book. */
+void gnc_book_add_budget(QofBook* book, GncBudget* budget)
+{
+    GList* budgetList;
+
+    if((budget == NULL) || (book == NULL)){
+        return;
+    }
+
+    budgetList = gnc_book_get_budgets( book );
+    budgetList = g_list_append( budgetList, budget);
+    gnc_book_set_budgets( book, budgetList );
+    
+    gnc_engine_gen_event( &budget->inst.entity, GNC_EVENT_ADD);
+}
+
+/** Delete the given budget from the list of budgets for the given book. */
+void gnc_book_delete_budget(QofBook* book, GncBudget* budget)
+{
+    GList* budgetList;
+
+    if((budget == NULL) || (book == NULL)){
+        return;
+    }
+
+    budgetList = gnc_book_get_budgets( book );
+    budgetList = g_list_remove( budgetList, budget);
+    gnc_book_set_budgets( book, budgetList );
+    
+    gnc_engine_gen_event( &budget->inst.entity, GNC_EVENT_REMOVE );
+}
+
+/* ============================================================ */
+
+
+
+/** ===========================================================
+ * gncObject registration functions.
+ */
+
+/* This function is called when the book is first initialized.
+ * Therefore we se the list of budgets to be NULL.
+ */
+static void budget_book_begin (QofBook *book)
+{
+    gnc_book_set_budgets (book, NULL);
+}
+
+/* This function is called when the book is being cleaned up.
+ * Therefore we se the list of budgets to be NULL.
+ */
+static void budget_book_end (QofBook *book)
+{
+    gnc_book_set_budgets(book, NULL);
+}
+
+/* ============================================================ */
+/* dirty flag stuff */
+
+static gboolean book_budget_notsaved(QofCollection *col)
+{
+    /** TODO: what is this for again??*/
+    return FALSE;
+}
+  
+static void budget_mark_clean(QofCollection *col)
+{
+    /** TODO: and this one... hummm. */
+}
+
+/* Define the QofObject. */
+static QofObject budget_object_def = 
+{
+    interface_version: QOF_OBJECT_VERSION,
+    e_type:              GNC_ID_BUDGET,
+    type_label:        "BUDGET",
+    book_begin:        budget_book_begin,
+    book_end:          budget_book_end,
+    is_dirty:          book_budget_notsaved,
+    mark_clean:        budget_mark_clean,
+    foreach:           NULL,
+    printable:         NULL,
+};
+
+/* Register ourselves with the engine. */
+gboolean gnc_budget_register (void)
+{
+    return qof_object_register (&budget_object_def);
+}
+
+/* ============================================================== */
Index: gnc-engine.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-engine.c,v
retrieving revision 1.17.4.2
retrieving revision 1.17.4.3
diff -Lsrc/engine/gnc-engine.c -Lsrc/engine/gnc-engine.c -u -r1.17.4.2 -r1.17.4.3
--- src/engine/gnc-engine.c
+++ src/engine/gnc-engine.c
@@ -31,6 +31,7 @@
 #include "AccountP.h"
 #include "GroupP.h"
 #include "SX-book-p.h"
+#include "gnc-budget-book-p.h"
 #include "TransactionP.h"
 #include "gnc-commodity.h"
 #include "gnc-lot-p.h"
@@ -95,6 +96,7 @@
   xaccAccountRegister ();
   xaccGroupRegister ();
   gnc_sxtt_register ();
+  gnc_budget_register();
   gnc_pricedb_register ();
   gnc_commodity_table_register();
   gnc_lot_register ();
--- /dev/null
+++ src/engine/gnc-budget.c
@@ -0,0 +1,513 @@
+/********************************************************************\
+ * gnc-budget.c -- Implementation of the top level Budgeting API's.     *
+ * Copyright (C) 04 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @file gnc-budget.c
+ *  @breif Implementation of the top level budgeting API's.
+ *  @author Created by Darin Willits 04 sep 2003 
+ *  @author Copyright (c) 2003 Darin Willits <darin at willits.ca>
+ *
+ *
+ */
+
+// Includes
+#include "config.h"
+#include <stdio.h>
+
+#include "gnc-budget-p.h"
+#include "qofbook.h"
+#include "qofbook-p.h"
+#include "qofid-p.h"
+#include "gnc-engine.h"
+#include "gnc-engine-util.h"
+#include "gnc-event-p.h"
+#include "Group.h"
+#include "Account.h"
+#include "gnc-budget-period.h"
+
+
+static void budget_fill_categories(GncBudget* budget);
+
+GncBudget* gnc_budget_new(QofBook *book)
+{
+    GncBudget* budget;
+    GDate date;
+    GString* freqStr;
+
+    g_return_val_if_fail(book, NULL);
+
+    budget = g_new0(GncBudget, 1);
+    
+    
+    qof_instance_init (&budget->inst, GNC_ID_BUDGET, book);
+    //budget->entity_table = qof_book_get_entity_table (book);
+    //qof_entity_guid_new (budget->entity_table, &budget->guid);
+    //qof_entity_store( budget->entity_table, budget,
+    //                &budget->guid, GNC_ID_BUDGET );
+    
+    budget->book = book;
+
+    /* Create the default period frequency.*/
+    budget->period_freq = xaccFreqSpecMalloc(book);
+    
+    g_date_clear(&date, 1);
+    g_date_set_time(&date, time(NULL));
+    xaccFreqSpecSetMonthly(budget->period_freq, &date, 1);
+    xaccFreqSpecSetUIType(budget->period_freq, UIFREQ_MONTHLY);
+
+    freqStr = g_string_sized_new(16);
+    xaccFreqSpecGetFreqStr(budget->period_freq, freqStr);
+    //printf("Category Freq: %s\n", freqStr->str);
+
+    
+    
+    /* fill the categories based on the current account hierarchy. 
+     * FIXME: This should probably not be here but rather be a separate 
+     * operation with a public interface.  For now it is convienent.*/
+    budget_fill_categories(budget);
+
+
+    gnc_engine_gen_event( &budget->inst.entity, GNC_EVENT_CREATE );
+
+    return budget;
+}
+
+void gnc_budget_delete(GncBudget* budget)
+{
+    if(budget == NULL){
+        return;
+    }
+    
+    /* We first send the message that this object is about to be
+     * destroyed so that any GUI elements can remove it before it is
+     * actually gone.
+     */
+    gnc_engine_gen_event( &budget->inst.entity, GNC_EVENT_DESTROY);
+    
+    //qof_entity_remove(budget->entity_table, &budget->guid);
+
+    if(budget->name){
+        g_free(budget->name);
+    }
+    
+    if(budget->description){
+        g_free(budget->description);
+    }
+
+    qof_instance_release (&budget->inst);
+    g_free(budget);
+}
+
+void gnc_budget_set_name(GncBudget* budget, const gchar* name)
+{
+    g_return_if_fail( name != NULL );
+    if ( budget->name != NULL ) {
+        g_free( budget->name );
+        budget->name = NULL;
+    }
+    budget->name = g_strdup( name );
+}
+
+gchar* gnc_budget_get_name(GncBudget* budget)
+{
+    if(budget == NULL){
+        return NULL;
+    }
+    return budget->name;
+}
+
+void gnc_budget_set_description(GncBudget* budget, const gchar* description)
+{
+    g_return_if_fail( description != NULL );
+    if ( budget->description != NULL ) {
+        g_free( budget->description);
+        budget->description = NULL;
+    }
+    budget->description = g_strdup(description);
+}
+
+gchar* gnc_budget_get_description(GncBudget* budget)
+{
+    if(budget == NULL){
+        return NULL;
+    }
+    return budget->description;
+}
+
+
+
+
+void gnc_budget_set_period_frequency(GncBudget* budget, FreqSpec* period)
+{
+    if(budget == NULL){
+        return;
+    }
+    
+    if((budget->period_freq == period) || (period == NULL)){
+        return;
+    }
+
+    if(budget->period_freq != NULL){
+        /* Delete the existing object before setting the new one. */
+        xaccFreqSpecFree(budget->period_freq);
+    }
+
+    budget->period_freq = period;
+}
+
+FreqSpec* gnc_budget_get_period_frequency(GncBudget* budget)
+{
+    if(budget == NULL){
+        return NULL;
+    }
+
+    return budget->period_freq;
+}
+
+
+
+
+void gnc_budget_set_start_date(GncBudget* budget, GDate* date)
+{
+    if(budget == NULL){
+        return;
+    }
+    budget->start_date = *date;
+}
+
+GDate* gnc_budget_get_start_date(GncBudget* budget)
+{
+    if(budget == NULL){
+        return NULL;
+    }
+    return &budget->start_date;
+}
+
+
+
+
+
+
+void gnc_budget_set_length_months(GncBudget* budget, gint months)
+{
+    if(budget == NULL){
+        return;
+    }
+
+    budget->length = months;
+}
+
+void gnc_budget_set_length_years(GncBudget* budget, gint years)
+{
+    if(budget == NULL){
+        return;
+    }
+
+    budget->length = years * 12;
+}
+
+gint gnc_budget_get_length_months(GncBudget* budget)
+{
+    if(budget == NULL){
+        return 0;
+    }
+
+    return budget->length;
+}
+
+gint gnc_budget_get_length_years(GncBudget* budget)
+{
+    if(budget == NULL){
+        return 0;
+    }
+
+    return budget->length / 12;
+}
+
+
+
+
+
+
+void gnc_budget_add_inflow_category(GncBudget* budget, GncBudgetCategory* category)
+{
+    if(budget == NULL){
+        return;
+    }
+    gnc_budget_category_add_child(budget->inflow_category, category);
+}
+
+void gnc_budget_remove_inflow_category(GncBudget* budget, GncBudgetCategory* category)
+{
+    if(budget == NULL){
+        return;
+    }
+    gnc_budget_category_remove_child(budget->inflow_category, category);
+}
+
+void gnc_budget_set_inflow_category(GncBudget* budget, GncBudgetCategory* inflow)
+{
+    if(budget == NULL){
+        return;
+    }
+    budget->inflow_category = inflow;
+}
+
+GncBudgetCategory* gnc_budget_get_inflow_category(GncBudget* budget)
+{
+    if(budget == NULL){
+        return NULL;
+    }
+    return budget->inflow_category;
+}
+
+void gnc_budget_set_outflow_category(GncBudget* budget, GncBudgetCategory* outflow)
+{
+    if(budget == NULL){
+        return;
+    }
+    budget->outflow_category = outflow;
+}
+
+GncBudgetCategory* gnc_budget_get_outflow_category(GncBudget* budget)
+{
+    if(budget == NULL){
+        return NULL;
+    }
+    return budget->outflow_category;
+}
+
+void gnc_budget_add_outflow_category(GncBudget* budget, GncBudgetCategory* category)
+{
+    if(budget == NULL){
+        return;
+    }
+    gnc_budget_category_add_child(budget->outflow_category, category);
+}
+
+void gnc_budget_remove_outflow_category(GncBudget* budget, GncBudgetCategory* category)
+{
+    if(budget == NULL){
+        return;
+    }
+    gnc_budget_category_remove_child(budget->inflow_category, category);
+}
+
+QofBook* gnc_budget_get_book(GncBudget* budget)
+{
+    if(budget == NULL){
+        return NULL;
+    }
+    return budget->book;
+}
+
+static void free_budget_period(gpointer data, gpointer user_data)
+{
+    GncBudgetPeriod* period = data;
+    g_free(period);
+}
+
+void gnc_budget_generate_periods(GncBudget* budget)
+{
+    GDate currentPeriod, outDate;
+    GDate endDate;
+    GDate periodStartDate;
+    GncBudgetPeriod* budgetPeriod;
+
+    if(budget == NULL){
+        return;
+    }
+
+    /* TODO: Add in some error checking such that we don't regenerate
+     * the periods if they are the same as before.  We may still need
+     * to recalculate the values however.
+     */
+    if(budget->period_list != NULL){
+        g_list_foreach(budget->period_list, free_budget_period, NULL);
+        g_list_free(budget->period_list);
+        budget->period_list = NULL;
+    }
+    
+    /* Add the starting period.  Every budget should have at least
+     * one period. */
+    g_date_set_dmy(&periodStartDate, g_date_get_day(&budget->start_date),
+                                     g_date_get_month(&budget->start_date),
+                                     g_date_get_year(&budget->start_date));
+    budgetPeriod = gnc_budget_period_new();
+    gnc_budget_period_set_start_date(budgetPeriod, &periodStartDate);
+    budget->period_list = g_list_append(budget->period_list, budgetPeriod);
+ 
+    
+    /* Setup the end Date */
+    g_date_set_dmy(&endDate, g_date_get_day(&budget->start_date),
+                             g_date_get_month(&budget->start_date),
+                             g_date_get_year(&budget->start_date));
+    g_date_add_months(&endDate, budget->length);
+    
+
+    g_date_set_dmy(&currentPeriod, g_date_get_day(&budget->start_date),
+                                  g_date_get_month(&budget->start_date),
+                                  g_date_get_year(&budget->start_date));
+    do{
+        xaccFreqSpecGetNextInstance(budget->period_freq, &currentPeriod, &outDate);
+        if(g_date_valid(&outDate) == FALSE){
+            break;
+        }
+        
+        if(g_date_compare(&outDate, &endDate) >= 0){
+            break;
+        }
+        else{
+            /* Set the end date of the previous period. */
+            gnc_budget_period_set_end_date(budgetPeriod, &outDate);
+
+            /* Create the new period. */
+            budgetPeriod = gnc_budget_period_new();
+            gnc_budget_period_set_start_date(budgetPeriod, &outDate);
+            
+            budget->period_list = g_list_append(budget->period_list, budgetPeriod);
+            g_date_set_dmy(&currentPeriod, g_date_get_day(&outDate),
+                            g_date_get_month(&outDate),
+                            g_date_get_year(&outDate));
+        }
+    }while(1);
+
+    gnc_budget_period_set_end_date(budgetPeriod, &endDate);
+    
+    /* Now we should generate the list of values for each category.*/
+    gnc_budget_category_generate_values(budget->inflow_category);
+    gnc_budget_category_generate_values(budget->outflow_category);
+}
+
+
+gint gnc_budget_get_num_periods(GncBudget* budget)
+{
+    if(budget == NULL){
+        return 0;
+    }
+    return g_list_length(budget->period_list);
+}
+
+GList* gnc_budget_get_period_list(GncBudget* budget)
+{
+    if(budget == NULL){
+        return NULL;
+    }
+    return budget->period_list;
+}
+
+
+
+/* ==================================================================== */
+/* Private member functions.
+ *
+ * ==================================================================== */
+
+static void add_category_from_account(gpointer data, gpointer userdata)
+{
+    GncBudget* budget;
+    Account* account;
+    AccountList* children;
+    GncBudgetCategory* category = NULL;
+    gchar* name;
+    AccountGroup* group;
+    int numChildren;
+    GNCAccountType accountType;
+
+    account = data;
+    budget = userdata;
+    
+    if(account == NULL){
+        return;
+    }
+
+    //printf("Adding Category from account\n");
+    //printf("Account: %s\n", xaccAccountGetName(account));
+    group  = xaccAccountGetChildren(account);
+    children = xaccGroupGetAccountList(group);
+    numChildren = xaccGroupGetNumAccounts(group);
+    //printf("NumChildren: %d\n", numChildren);
+
+    if(numChildren == 0){
+        name = xaccAccountGetFullName(account, ':');
+        accountType = xaccAccountGetType(account);
+        
+        category = gnc_budget_category_new(budget->book, budget);
+        gnc_budget_category_set_name(category, name);
+        gnc_budget_category_add_account(category, account);
+                
+        if(accountType == INCOME){
+            //printf("Inflow Category: %s\n", gnc_budget_category_get_name(category));
+            gnc_budget_category_set_type(category, BUDGET_CATEGORY_INFLOW);
+            gnc_budget_category_add_child(budget->inflow_category, category);
+        }
+        else{
+            //printf("Outflow Category: %s\n", gnc_budget_category_get_name(category));
+            gnc_budget_category_set_type(category, BUDGET_CATEGORY_OUTFLOW);
+            gnc_budget_category_add_child(budget->outflow_category, category);
+        }
+        
+        g_free(name);
+    }
+
+}
+
+static void budget_fill_categories(GncBudget* budget)
+{
+    AccountList* children;
+    if(budget == NULL){
+        return;
+    }
+    
+    //printf("Creating top level budget categories.\n");
+
+    budget->inflow_category = gnc_budget_category_new(budget->book, budget);
+    gnc_budget_category_set_name(budget->inflow_category, "Inflow");
+
+    
+    budget->outflow_category = gnc_budget_category_new(budget->book, budget);
+    gnc_budget_category_set_name(budget->outflow_category, "Outflow");
+
+    
+    //printf("Filing budget Categories.\n");
+    //children = xaccGroupGetAccountList(gnc_book_get_group(budget->book));
+    children = xaccGroupGetSubAccounts(gnc_book_get_group(budget->book));
+    g_list_foreach(children, add_category_from_account, budget);
+
+    //printf("Number of inflow categories: %d\n", 
+            //gnc_budget_category_get_num_children(budget->inflow_category));
+    //printf("Number of outflow categories: %d\n", 
+            //gnc_budget_category_get_num_children(budget->outflow_category));
+}
+
+GncBudget* gnc_budget_lookup (const GUID *guid, QofBook *book)
+{
+    QofCollection *col;
+    
+    if (!guid || !book){
+        return NULL;
+    }
+        
+    col = qof_book_get_collection (book, GNC_ID_BUDGET);
+    return (GncBudget*)qof_collection_lookup_entity (col, guid);
+}
+
Index: Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Makefile.am,v
retrieving revision 1.94.2.6
retrieving revision 1.94.2.7
diff -Lsrc/engine/Makefile.am -Lsrc/engine/Makefile.am -u -r1.94.2.6 -r1.94.2.7
--- src/engine/Makefile.am
+++ src/engine/Makefile.am
@@ -25,6 +25,11 @@
   Transaction.c \
   cap-gains.c \
   gnc-associate-account.c \
+  gnc-budget-book.c \
+  gnc-budget-cat.c \
+  gnc-budget-period-value.c \
+  gnc-budget-period.c \
+  gnc-budget.c \
   gnc-commodity.c \
   gnc-date.c \
   gnc-engine-util.c \
@@ -79,6 +84,11 @@
   glib-helpers.h \
   gnc-associate-account.h \
   gnc-book.h \
+  gnc-budget-book.h \
+  gnc-budget-cat.h \
+  gnc-budget-period-value.h \
+  gnc-budget-period.h \
+  gnc-budget.h \
   gnc-commodity.h \
   gnc-date.h \
   gnc-engine-util.h \
@@ -121,6 +131,11 @@
   SX-book.h \
   SX-ttinfo.h \
   TransactionP.h \
+  gnc-budget-book-p.h \
+  gnc-budget-cat-p.h \
+  gnc-budget-period-value-p.h \
+  gnc-budget-period-p.h \
+  gnc-budget-p.h \
   gnc-event-p.h \
   gnc-lot.h \
   gnc-lot-p.h \
--- /dev/null
+++ src/engine/gnc-budget-period-value.h
@@ -0,0 +1,65 @@
+/********************************************************************\
+ * gnc-budget-period-value.h --  Public interface for the budget period *
+ *                              value structure.                    *
+ * Copyright (C) 16 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup engine
+ *     @{ */
+/** @file gnc-budget-period-value.h
+ *  @breif Public interface for the budget period value structure.
+ *  @author Created by Darin Willits 16 sep 2003 
+ *  @author Copyright (c) 16 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ * A budget period value is the value associated with each budget period.
+ * Each category maintains a list of these values.  If the budget period
+ * is changed this list needs to be regenerated.
+ * Note: We should probably add a reference here to the actual budget
+ * period we are referring to.  Right now we just depend on their order
+ * in their respective lists.
+ */
+
+#ifndef __GNC_BUDGET_PERIOD_VALUE_H__
+#define __GNC_BUDGET_PERIOD_VALUE_H__
+
+#include "gnc-numeric.h"
+
+typedef struct gncp_budget_period_value GncBudgetPeriodValue;
+
+/* Create a new GncBudgetPeriodValue object.
+ */
+GncBudgetPeriodValue* gnc_budget_period_value_new(void);
+
+/** Delete a GncBudgetPeriodValue object.
+ */
+void gnc_budget_period_value_delete(GncBudgetPeriodValue* periodValue);
+
+/** Set the value
+ */
+void gnc_budget_period_value_set_value(GncBudgetPeriodValue* periodValue, gnc_numeric value);
+void gnc_budget_period_value_set_value_double(GncBudgetPeriodValue* periodValue, double value);
+
+/* Get the value
+ */
+gnc_numeric gnc_budget_period_value_get_value(GncBudgetPeriodValue* periodValue);
+
+
+#endif // __BUDGET_PERIOD_VALUE_H__
--- /dev/null
+++ src/gnome/dialog-budget-list.h
@@ -0,0 +1,43 @@
+/********************************************************************\
+ * dialog-budget-list.h --  Dialog to show the list of available    *
+ *                          budgets to the user.                    *
+ * Copyright (C) 08 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gui
+ *     @{ */
+/** @file dialog-budget-list.h
+ *  @breif Dialog to show the list of available budgets to the user.
+ *  @author Created by Darin Willits 08 sep 2003 
+ *  @author Copyright (c) 08 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+#ifndef __DIALOG_BUDGET_LIST_H__
+#define __DIALOG_BUDGET_LIST_H__
+
+#include <glib.h>
+
+/** Launch the budget list dialog.*/
+void gnc_budget_list_dialog_create(void);
+
+void add_budget_to_model( gpointer data, gpointer user_data );
+#endif // __DIALOG_BUDGET_LIST_H__
--- /dev/null
+++ src/gnome/gnc-budget-gui.h
@@ -0,0 +1,38 @@
+/********************************************************************\
+ * gnc-budget-gui.h -- budget gui defines.                              *
+ * Copyright (C) 08 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gui
+ *     @{ */
+/** @file gnc-budget-gui.h
+ *  @breif Common defines used by the budgeting gui components.
+ *  @author Created by Darin Willits 08 sep 2003 
+ *  @author Copyright (c) 08 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+#ifndef __GNC_BUDGET_GUI_H__
+#define __GNC_BUDGET_GUI_H__
+
+#define GNC_BUDGET_GUI_FILE    "budget.glade"
+
+#endif // __GNC_BUDGET_H__
--- /dev/null
+++ src/gnome/dialog-budget-category.h
@@ -0,0 +1,47 @@
+/********************************************************************\
+ * dialog-budget-category.h --  Defintion of the public interface   *
+ *                              for the budget category dialog.     *
+ * Copyright (C) 10 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gnome
+ *     @{ */
+/** @file dialog-budget-category.h
+ *  @breif Definition of the public interface of the budget category dialog.
+ *  @author Created by Darin Willits 10 sep 2003 
+ *  @author Copyright (c) 10 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+#ifndef __DIALOG_BUDGET_CATEGORY_H__
+#define __DIALOG_BUDGET_CATEGORY_H__
+
+#include "gnc-budget-cat.h"
+
+/* Launch the modify category dialog.
+ */
+void gnc_budget_category_dialog_create(GncBudget* budget, GncBudgetCategory* category);
+
+/* Launch the modify category dialog without an existing category.
+ * A new one will be created and inserted into the buget on success.
+ */
+void gnc_budget_category_new_dialog_create(GncBudget* budget);
+#endif // __DIALOG_BUDGET_CATEGORY_H__
--- /dev/null
+++ src/gnome/dialog-budget-category.c
@@ -0,0 +1,324 @@
+/********************************************************************\
+ * dialog-budget-category.c --  Implementation of the budget        *
+ *                              category dialog.                    *
+ * Copyright (C) 10 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gnome
+ *     @{ */
+/** @file dialog-budget-category.c
+ *  @breif Implementation of the budget category dialog.
+ *  @author Created by Darin Willits 10 sep 2003 
+ *  @author Copyright (c) 10 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+// Includes
+#include "config.h"
+
+#include <gnome.h>
+#include "dialog-utils.h"
+#include "gnc-ui-util.h"
+#include "dialog-budget-category.h"
+#include "FreqSpec.h"
+#include "gnc-tree-model-account.h"
+#include "gnc-tree-view-account.h"
+#include "gnc-general-select.h"
+#include "gnc-frequency.h"
+#include "gnc-budget-gui.h"
+#include "gnc-commodity-edit.h"
+#include "dialog-commodity.h"
+#include "gnc-ui-util.h"
+#include "Group.h"
+
+
+/* Budget Category Dialog structure definition. */
+typedef struct{
+    GtkWidget* wnd;
+    GladeXML* xml;
+
+    GtkWidget* commodityEdit;
+    dialog_commodity_mode commodityMode;
+    GtkTreeView* relatedView;
+    GNCFrequency* freqWnd;
+    GtkEntry* name_entry;
+    GtkEntry* description_entry;
+    GtkSpinButton* value_button;
+    GtkRadioButton* inflow_button;
+    GtkRadioButton* outflow_button;
+
+    gboolean new_category;
+
+    GncBudgetCategory* category;
+    GncBudget* budget;
+
+} BudgetCategoryDlg;
+
+/* Fill in the Budget Category from the values displayed in the UI. */
+static void category_from_ui(BudgetCategoryDlg* dlg)
+{
+    FreqSpec* freqSpec;
+    GDate startDate;
+    const gchar* name, *description;
+    gnc_numeric value; 
+    gnc_commodity* commodity;
+    gint type;
+    AccountList* selectedAccounts;
+
+    /* Set the name and description. */
+    name = gtk_entry_get_text(dlg->name_entry);
+    description = gtk_entry_get_text(dlg->description_entry);
+
+    gnc_budget_category_set_name(dlg->category, name);
+    gnc_budget_category_set_description(dlg->category, description);
+    
+    /* Set the category's value. */
+    value = double_to_gnc_numeric(
+                gtk_spin_button_get_value_as_float(dlg->value_button), 
+                1, GNC_RND_NEVER );
+    gnc_budget_category_set_value(dlg->category, value);
+    
+    /* Set the frequency. */
+    freqSpec = gnc_budget_category_get_frequency(dlg->category);
+    if(freqSpec == NULL){
+        freqSpec = xaccFreqSpecMalloc(gnc_budget_get_book(dlg->budget));
+    }
+    gnc_frequency_save_state( dlg->freqWnd, freqSpec, &startDate);
+    gnc_budget_category_set_frequency(dlg->category, freqSpec);
+    
+
+    /* Set the commodity. */
+    commodity = (gnc_commodity *)
+        gnc_general_select_get_selected (GNC_GENERAL_SELECT (dlg->commodityEdit));
+    gnc_budget_category_set_commodity(dlg->category, commodity);
+
+    /* Set the category's type. */
+    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlg->inflow_button))){
+        type = BUDGET_CATEGORY_INFLOW;
+    }
+    else{
+        type = BUDGET_CATEGORY_OUTFLOW;
+    }
+   
+    /* If this category has just been created we have to add it to either
+     * the inflow or outflow categories.  We also have to check if the type 
+     * has been changed and move it. */
+    if(dlg->new_category == TRUE){
+        if(type == BUDGET_CATEGORY_INFLOW){
+            gnc_budget_add_inflow_category(dlg->budget, dlg->category);
+        }
+        else{
+            gnc_budget_add_outflow_category(dlg->budget, dlg->category);
+        }
+        gnc_budget_category_set_type(dlg->category, type);
+    }
+    else if(type != gnc_budget_category_get_type(dlg->category)){
+        if(type == BUDGET_CATEGORY_INFLOW){
+            gnc_budget_remove_outflow_category(dlg->budget, dlg->category);
+            gnc_budget_add_inflow_category(dlg->budget, dlg->category);
+        }
+        else{
+            gnc_budget_remove_inflow_category(dlg->budget, dlg->category);
+            gnc_budget_add_outflow_category(dlg->budget, dlg->category);
+        }
+        gnc_budget_category_set_type(dlg->category, type);
+    }
+    
+    /* Set the related accounts. */
+    selectedAccounts = 
+        (AccountList*)gnc_tree_view_account_get_selected_accounts(
+                                           GNC_TREE_VIEW_ACCOUNT(dlg->relatedView));
+    gnc_budget_category_set_related_accounts(dlg->category, selectedAccounts);
+}
+
+/* Fill in the User Interface from the category object. */
+static void category_to_ui(BudgetCategoryDlg* dlg)
+{
+    double value;
+    gnc_commodity* commodity;
+    GncBudgetCategoryType type;
+    GList* relatedAccounts;
+    
+    /* Set the name and description. */
+    gtk_entry_set_text(dlg->name_entry, 
+            gnc_budget_category_get_name(dlg->category));
+    gtk_entry_set_text(dlg->description_entry, 
+            gnc_budget_category_get_description(dlg->category));
+
+    /* Set the value. */
+    value = gnc_numeric_to_double(
+                gnc_budget_category_get_value(dlg->category));
+    gtk_spin_button_set_value(dlg->value_button, value);
+    
+    /* Set the commodity. */
+    commodity = gnc_budget_category_get_commodity(dlg->category);
+    gnc_general_select_set_selected (GNC_GENERAL_SELECT (dlg->commodityEdit),
+                                    commodity);
+
+    /* Set the categories type. */
+    type = gnc_budget_category_get_type(dlg->category);
+    if(type == BUDGET_CATEGORY_INFLOW){
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dlg->inflow_button), TRUE);
+    }
+    else{
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dlg->outflow_button), TRUE);
+    }
+
+    /* Set the tree view to show the related accounts. */
+    relatedAccounts = (GList*)gnc_budget_category_get_related_accounts(dlg->category);
+    printf("Related Accouts: %d\n", g_list_length(relatedAccounts));
+    gnc_tree_view_account_set_selected_accounts(
+            GNC_TREE_VIEW_ACCOUNT(dlg->relatedView), relatedAccounts, TRUE);
+}
+
+
+/* Destroy the dialog and cleanup. */
+static void category_dialog_destroy(BudgetCategoryDlg* dlg)
+{
+    gtk_widget_destroy(dlg->wnd);
+    g_free(dlg);
+}
+
+/* Ok Button event handler. */
+static void ok_clicked(GtkWidget* object, gpointer* data)
+{
+    BudgetCategoryDlg* dlg = (BudgetCategoryDlg*)data;
+    category_from_ui(dlg);
+    category_dialog_destroy(dlg);
+}
+
+/* Cancel button event handler. */
+static void cancel_clicked(GtkWidget* object, gpointer data)
+{
+    category_dialog_destroy((BudgetCategoryDlg*)data);
+}
+
+/* Create the Budget Category Dialog. */
+static void category_dialog_create(BudgetCategoryDlg* dlg)
+{
+    GladeXML *xml;
+    GtkWidget *box;
+    GtkWidget* ok_button;
+    GtkWidget* cancel_button;
+    GtkTreeModel *model;
+    GtkTreeSelection* selection;
+    
+    /* Load the glade xml file and create the widget. */
+    xml = gnc_glade_xml_new (GNC_BUDGET_GUI_FILE, "Modify Category Dialog");
+    dlg->wnd = glade_xml_get_widget(xml, "Modify Category Dialog");
+    dlg->xml = xml;
+   
+    /* Create the various component widgets. */
+    dlg->name_entry = 
+        GTK_ENTRY(glade_xml_get_widget(dlg->xml, "name_entry"));
+    dlg->description_entry = 
+        GTK_ENTRY(glade_xml_get_widget(dlg->xml, "description_entry"));
+    dlg->value_button = 
+        GTK_SPIN_BUTTON(glade_xml_get_widget(dlg->xml, "value_button"));
+    dlg->inflow_button = 
+        GTK_RADIO_BUTTON(glade_xml_get_widget(dlg->xml, "inflow_button"));
+    dlg->outflow_button = 
+        GTK_RADIO_BUTTON(glade_xml_get_widget(dlg->xml, "outflow_button"));
+
+    
+    /* Set up the commodity widget. */
+    dlg->commodityMode = DIAG_COMM_CURRENCY;
+    box = glade_xml_get_widget (dlg->xml, "commodity_box");
+    dlg->commodityEdit = gnc_general_select_new (GNC_GENERAL_SELECT_TYPE_SELECT,
+					       gnc_commodity_edit_get_string,
+					       gnc_commodity_edit_new_select,
+					       &dlg->commodityMode);
+    gtk_box_pack_start(GTK_BOX(box), dlg->commodityEdit, TRUE, TRUE, 0);
+
+
+    /* Set up the related accounts view. */
+    model = gnc_tree_model_account_new (gnc_book_get_group (gnc_get_current_book ()));
+    
+    box = glade_xml_get_widget (xml, "related_accounts_scroll");
+    dlg->relatedView = gnc_tree_view_account_new(FALSE);
+    gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(dlg->relatedView));
+    gtk_tree_view_set_model (dlg->relatedView, model);
+    
+    gnc_tree_view_account_configure_columns(GNC_TREE_VIEW_ACCOUNT(dlg->relatedView), NULL);
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dlg->relatedView));
+    gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+ 
+
+    /* Set up the frequency view. */
+    dlg->freqWnd = GNC_FREQUENCY(
+            gnc_frequency_new(gnc_budget_category_get_frequency(dlg->category), NULL));
+    
+    /* Reparent to the correct location */
+    box = glade_xml_get_widget (xml, "frequency_box");
+    gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (dlg->freqWnd),TRUE, TRUE, 0);
+    
+    /* Connect signals. */
+    ok_button = glade_xml_get_widget( dlg->xml, "ok_button" );
+    g_signal_connect( ok_button, "clicked",
+                        G_CALLBACK(ok_clicked), dlg);
+    cancel_button = glade_xml_get_widget( dlg->xml, "cancel_button" );
+    g_signal_connect( cancel_button, "clicked",
+                        G_CALLBACK(cancel_clicked), dlg);
+
+
+    /* Fill in the ui from the category. */
+    category_to_ui(dlg);
+}
+
+/* Public interface method to create the budget category dialog.
+ * This method is used to create a dialog to edit an existing category. */
+void gnc_budget_category_dialog_create(GncBudget* budget, GncBudgetCategory* category)
+{
+    BudgetCategoryDlg* dlg;
+
+    dlg = g_new0(BudgetCategoryDlg, 1);
+
+    dlg->category = category;
+    dlg->budget = budget;
+    category_dialog_create(dlg);
+
+    gtk_widget_show_all(dlg->wnd);
+}
+
+/* Public interface method to create the budget category dialog.
+ * This method is used to create a dialog to edit a newly created category. 
+ * If the user clicks ok then the new category will be added to the budget,
+ * otherwise the new category will be destroyed.
+ * */
+void gnc_budget_category_new_dialog_create(GncBudget* budget)
+{
+    BudgetCategoryDlg* dlg;
+    GncBudgetCategory* category;
+
+    dlg = g_new0(BudgetCategoryDlg, 1);
+
+    category = gnc_budget_category_new(gnc_budget_get_book(budget),  budget);
+    
+    
+    dlg->category = category;
+    dlg->budget = budget;
+    
+    dlg->new_category = TRUE;
+    
+    category_dialog_create(dlg);
+
+    gtk_widget_show_all(dlg->wnd);
+}
Index: gnc-main-window.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/Attic/gnc-main-window.c,v
retrieving revision 1.1.2.32
retrieving revision 1.1.2.33
diff -Lsrc/gnome/gnc-main-window.c -Lsrc/gnome/gnc-main-window.c -u -r1.1.2.32 -r1.1.2.33
--- src/gnome/gnc-main-window.c
+++ src/gnome/gnc-main-window.c
@@ -35,6 +35,7 @@
 
 #include "gnc-main-window.h"
 
+#include "dialog-budget-list.h"
 #include "gnc-menu-extensions.h"
 
 #include "dialog-fincalc.h"
@@ -111,6 +112,7 @@
 static void gnc_main_window_cmd_view_summary (EggAction *action, GncMainWindow *window);
 static void gnc_main_window_cmd_view_statusbar (EggAction *action, GncMainWindow *window);
 static void gnc_main_window_cmd_actions_scheduled_transaction_editor (EggAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_actions_budget_workbench(EggAction *action, GncMainWindow *window);
 static void gnc_main_window_cmd_actions_since_last_run (EggAction *action, GncMainWindow *window);
 static void gnc_main_window_cmd_actions_mortgage_loan (EggAction *action, GncMainWindow *window);
 static void gnc_main_window_cmd_actions_close_books (EggAction *action, GncMainWindow *window);
@@ -227,6 +229,9 @@
 	{ "ActionsMortgageLoanAction", N_("_Mortgage & Loan Repayment..."), NULL, "NULL",
 	  N_("Setup scheduled transactions for repayment of a loan"),
 	  G_CALLBACK (gnc_main_window_cmd_actions_mortgage_loan) },
+	{ "ActionsBudgetWorkbenchAction", N_("_Budget Workbench (Experimental)"), NULL, NULL, 
+      N_("Create, Manage, and Monitor Budgets." ),
+      G_CALLBACK(gnc_main_window_cmd_actions_budget_workbench) },
 	{ "ActionsCloseBooksAction", N_("Close Books"), NULL, "NULL",
 	  N_("Archive old data using accounting periods"),
 	  G_CALLBACK (gnc_main_window_cmd_actions_close_books) },
@@ -1142,6 +1147,12 @@
 	gnc_ui_sx_loan_druid_create ();
 }
 
+static void 
+gnc_main_window_cmd_actions_budget_workbench(EggAction *action, GncMainWindow *window)
+{
+    gnc_budget_list_dialog_create();
+}
+
 static void
 gnc_main_window_cmd_actions_close_books (EggAction *action, GncMainWindow *window)
 {
--- /dev/null
+++ src/gnome/dialog-budget-workbench.c
@@ -0,0 +1,592 @@
+/********************************************************************\
+ * dialog-budget-workbench.c -- Implementation of the budget        *
+ *                              workbench dialog.                   *
+ * Copyright (C) 14 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gnome
+ *     @{ */
+/** @file dialog-budget-workbench.c
+ *  @breif Implmentation of the budget workbench dialog.
+ *  @author Created by Darin Willits 14 sep 2003 
+ *  @author Copyright (c) 14 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ * The Budget Workbench is the main budgeting window.  This window
+ * allows the user to configure and track their budget.
+ */
+
+// Includes
+#include <gnome.h>
+#include "dialog-utils.h"
+#include "gnc-ui-util.h"
+#include "dialog-budget-category.h"
+#include "gnc-general-select.h"
+#include "gnc-budget-gui.h"
+#include "gnc-ui-util.h"
+#include "gnc-date-edit.h"
+#include "misc-gnome-utils.h"
+#include "gnc-frequency.h"
+
+#include "dialog-budget-workbench.h"
+#include "dialog-budget-category.h"
+#include "gnc-budget-tree-model.h"
+#include "gnc-budget-period.h"
+
+
+/* The Budget Workbench dialog structure. */
+typedef struct{
+    GtkWidget* wnd;
+    GladeXML* xml;
+
+    GtkEntry* name_entry;
+    GtkTextView* description_view;
+    GNCDateEdit* start_date;
+    GNCFrequency* freqWnd;
+    GtkSpinButton*  length_button;
+    GtkOptionMenu*  length_menu;
+    GtkOptionMenu*  period_menu;
+    GtkTreeView*    category_view;
+    GtkTreeView*    balance_view;
+    GtkTreeView*    track_view;
+    GtkTreeModel*   category_model;
+    GtkLabel*       period_label;
+
+    int colNum;
+    int active_period;
+    
+    GncBudget* budget;
+
+} BudgetWorkbench;
+
+/* Event handler for a cell having been edited. */
+static void cell_edited (GtkCellRendererText *cell,
+                	        const gchar         *path_string,
+	                        const gchar         *new_text,
+	                        gpointer             data)
+{
+    BudgetWorkbench* bench = data;
+    GtkTreeModel *model = bench->category_model;
+    GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+    GtkTreeIter iter;
+    GncBudgetCategory* category;
+
+    gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));
+
+    gtk_tree_model_get_iter (model, &iter, path);
+    category = gnc_budget_tree_model_get_category(GNC_BUDGET_TREE_MODEL(model), &iter);
+
+    if(category == NULL){
+        printf("Cell_Edited: Category is NULL!\n");
+        return;
+    }
+
+    gint index = column - GNC_BUDGET_TREE_MODEL_NUM_STATIC_COLUMNS;
+    gnc_numeric value = double_to_gnc_numeric(atof(new_text), 1, GNC_RND_NEVER);
+
+    gnc_budget_category_set_period_value_by_index(category, index, value);
+
+}
+
+/* Add a single period column to the balance view tab. */
+static void add_period_column(gpointer data, gpointer user_data)
+{
+    GncBudgetPeriod* period = data;
+    GDate* startDate, *endDate;
+    BudgetWorkbench* bench = user_data;
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+    char buffer[256];
+    gint colnum;
+
+    startDate = gnc_budget_period_get_start_date(period);
+    endDate = gnc_budget_period_get_end_date(period);
+
+    /* Format the period column title. */
+    sprintf(buffer, "%d/%d/%d", g_date_get_day(startDate),
+                                           g_date_get_month(startDate),
+                                           g_date_get_year(startDate));
+
+    /* column for severities */
+    colnum = GNC_BUDGET_TREE_MODEL_NUM_STATIC_COLUMNS + bench->colNum;
+    renderer = gtk_cell_renderer_text_new ();
+    g_signal_connect (renderer, "edited",
+		    G_CALLBACK (cell_edited), bench);
+    g_object_set_data (G_OBJECT (renderer), "column", (gint *)colnum);
+    column = gtk_tree_view_column_new_with_attributes (buffer,
+						     renderer,
+						     "text", colnum,
+                             "editable", GNC_BUDGET_TREE_MODEL_COL_EDITABLE,
+						     NULL);
+    gtk_tree_view_append_column (bench->balance_view, column);
+
+    bench->colNum++;
+}
+
+/* Iterates across the list of periods and adds a column for each
+ * one to the balance budget view. */
+static void add_balance_budget_columns(BudgetWorkbench* bench)
+{
+    GList* period_list;
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+    
+    /* column for category name */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Name",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_NAME,
+                             NULL);
+    gtk_tree_view_append_column (bench->balance_view, column);
+ 
+    
+    bench->colNum = 0;
+    period_list = gnc_budget_get_period_list(bench->budget);
+
+    g_list_foreach(period_list, add_period_column, bench);
+}
+
+/* Remove a single column from the given TreeView. */
+static void remove_column(gpointer data, gpointer user_data)
+{
+    GtkTreeView* treeView = user_data;
+    GtkTreeViewColumn* column = data;
+
+    gtk_tree_view_remove_column(treeView, column);
+}
+
+/* Removes all the columns from the balance view.  This is used to 
+ * re-build the budget from category data. */
+static void remove_balance_view_columns(BudgetWorkbench* bench)
+{
+    GList* columns;
+    columns = gtk_tree_view_get_columns(bench->balance_view);
+
+    g_list_foreach(columns, remove_column, bench->balance_view);
+
+    g_list_free(columns);
+}
+
+/* Add the category columns to the given tree view. */
+static void add_category_columns(GtkTreeView* treeView)
+{
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+
+    /* column for category name */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Name",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_NAME,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+
+    /* column for value */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Value",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_VALUE,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+    
+    /* column for freq */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Frequency",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_FREQ,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+}
+
+/* Add the columns for the track budget view. */
+static void add_track_columns(GtkTreeView* treeView)
+{
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+
+    /* column for category name */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Name",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_NAME,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+
+    /* column for previous overflow value */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Previous Overflow",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_LAST_OVERFLOW,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+    
+    /* column for actual period value */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Actual",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_ACTUAL,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);    
+    
+    /* column for planned period value */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Planned",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_PLANNED,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);    
+    
+    /* column for period balance value */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Period Balance",
+						     renderer,
+						     "text", GNC_BUDGET_TREE_MODEL_COL_CUR_OVERFLOW,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);    
+}
+
+/* Fill in the user interface from the budget object. */
+static void workbench_from_budget(BudgetWorkbench* bench)
+{
+    /* Set the name and description.*/
+    gtk_entry_set_text(bench->name_entry, gnc_budget_get_name(bench->budget));
+    xxxgtk_textview_set_text(bench->description_view, 
+            gnc_budget_get_description(bench->budget));
+    
+    /* Set the length value.  
+     * FIXME: Default to showing length in months
+     * cause we have no way of knowing which they choose before.
+     * Maybe have to change this.
+     */
+    gtk_spin_button_set_value(bench->length_button, 
+            gnc_budget_get_length_months(bench->budget));
+    gtk_option_menu_set_history(bench->length_menu, 0);
+}
+
+/* Fill in the budget object from the user interface. */
+static void workbench_to_budget(BudgetWorkbench* bench)
+{
+    const gchar *name, *description;
+    FreqSpec* freqSpec;
+    GDate* startDate;
+    gint length;
+
+    /* Set the name and description of the budget. */
+    name = gtk_entry_get_text(bench->name_entry);
+    description = xxxgtk_textview_get_text(bench->description_view);
+
+    gnc_budget_set_name(bench->budget, name);
+    gnc_budget_set_description(bench->budget, description);
+    
+    /* Set the length of the budget. */
+    length = gtk_spin_button_get_value_as_int(bench->length_button);
+    if(gtk_option_menu_get_history(bench->length_menu) == 1){
+        gnc_budget_set_length_years(bench->budget, length);
+    }
+    else{
+        gnc_budget_set_length_months(bench->budget, length);
+    }
+    
+    /* Set the budget period. */
+    freqSpec = gnc_budget_get_period_frequency(bench->budget);
+    startDate = gnc_budget_get_start_date(bench->budget);
+    if(freqSpec == NULL){
+        freqSpec = xaccFreqSpecMalloc(gnc_budget_get_book(bench->budget));
+    }
+    gnc_frequency_save_state( bench->freqWnd, freqSpec, startDate);
+    gnc_budget_set_period_frequency(bench->budget, freqSpec);
+
+}
+
+/* Destroy and cleanup the budget workbench dialog. */
+static void budget_workbench_destroy(BudgetWorkbench* bench)
+{
+    if(bench == NULL){
+        return;
+    }
+    gtk_widget_destroy(bench->wnd);
+    g_free(bench);
+}
+
+/* Event handler for the ok button. */
+static void ok_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    workbench_to_budget(bench);
+
+    budget_workbench_destroy(bench);
+}
+
+/* Event handler for the apply button. */
+static void apply_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    workbench_to_budget(bench);
+}
+
+/* Event handler for the cancel button. */
+static void cancel_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    budget_workbench_destroy(bench);
+}
+
+/* Event handler for the new category button. */
+static void new_category_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+
+    printf("Creating new Category... Budget: %p\n", bench->budget);
+    gnc_budget_category_new_dialog_create(bench->budget);
+}
+
+/* Event handler for the edit category button. */
+static void edit_category_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    GtkTreeSelection *selection;
+    GtkTreeIter iter;
+    GncBudgetCategory *category = NULL;
+
+    printf("Editing Category... Druid: %p Budget: %p\n",bench, bench->budget);
+    selection = gtk_tree_view_get_selection (bench->category_view);
+    if (!gtk_tree_selection_get_selected (selection, &bench->category_model, &iter)){
+        printf("Nothing selected...\n");
+        return;
+    }
+
+    category = gnc_budget_tree_model_get_category(GNC_BUDGET_TREE_MODEL(bench->category_model), &iter);
+
+    gnc_budget_category_dialog_create(bench->budget, category);
+}
+
+/* Event handler for the delete category button. */
+static void delete_category_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    GtkTreeSelection *selection;
+    GtkTreeIter iter;
+    GncBudgetCategory *category, *inflowCat, *outflowCat;
+
+    printf("Deleting Category...\n");
+    selection = gtk_tree_view_get_selection (bench->category_view);
+    if (!gtk_tree_selection_get_selected (selection, &bench->category_model, &iter)){
+        printf("Nothing selected...\n");
+        return;
+    }
+
+    category = gnc_budget_tree_model_get_category(GNC_BUDGET_TREE_MODEL(bench->category_model), &iter);
+    inflowCat = gnc_budget_get_inflow_category(bench->budget);
+    outflowCat = gnc_budget_get_outflow_category(bench->budget);
+
+    if((category != inflowCat) && (category != outflowCat)){
+        gnc_budget_category_delete(category);
+    }
+    else{
+        printf("Cannot delete this category...\n");
+    }
+}
+
+/* Event handler for the regenerate button.  This will regenerate the 
+ * values for each budget period from the category values. */
+static void regenerate_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+
+    remove_balance_view_columns(bench);
+    gnc_budget_generate_periods(bench->budget);
+    add_balance_budget_columns(bench);
+}
+
+/* Update the period label for the new active period on the track
+ * budget tab. */
+static void update_period_label(BudgetWorkbench* bench)
+{
+    GList* periodList;
+    periodList = gnc_budget_get_period_list(bench->budget);
+    GncBudgetPeriod* period;
+    GDate* startDate, *endDate;
+    char buffer[256];
+    gchar startBuffer[126];
+    gchar endBuffer[126];
+
+    if(bench->active_period >= g_list_length(periodList)){
+        bench->active_period = g_list_length(periodList) - 1;
+    }
+    else if(bench->active_period < 0){
+        bench->active_period = 0;
+    }
+
+    period = g_list_nth_data(periodList, bench->active_period);
+    startDate = gnc_budget_period_get_start_date(period);
+    endDate = gnc_budget_period_get_end_date(period);
+
+    g_date_strftime(startBuffer, 126, "%x", startDate);
+    g_date_strftime(endBuffer, 126, "%x", endDate);
+    
+    sprintf(buffer, "%s - %s", startBuffer, endBuffer);
+    gtk_label_set_text(bench->period_label, buffer);
+}
+
+/* Roll back the active period to the first one. */
+static void first_period_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    bench->active_period = 0;
+    update_period_label(bench);
+}
+
+/* Roll back the period to the previous one. */
+static void back_period_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    if(bench->active_period > 0){
+        bench->active_period -= 1;
+    }
+    update_period_label(bench);
+}
+
+/* Advance to the next period. */
+static void next_period_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    if(bench->active_period < g_list_length(gnc_budget_get_period_list(bench->budget)) - 1){
+        bench->active_period += 1;
+    }
+    update_period_label(bench);
+}
+
+/* Advance to the last period. */
+static void last_period_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetWorkbench* bench = data;
+    bench->active_period = g_list_length(gnc_budget_get_period_list(bench->budget)) - 1;
+    update_period_label(bench);
+}
+
+/* Create the budget workbench dialog. */
+static void create_budget_workbench(BudgetWorkbench* bench)
+{
+    GtkWidget *box;
+    GDate* startDate;
+    GtkWidget* button;
+     
+    /* Load the widgets from the glade xml file. */
+    bench->xml = gnc_glade_xml_new (GNC_BUDGET_GUI_FILE, "Budget Workbench");
+    bench->wnd = glade_xml_get_widget(bench->xml, "Budget Workbench");
+
+    bench->name_entry = 
+        GTK_ENTRY(glade_xml_get_widget( bench->xml, "name_entry"));
+    bench->description_view = 
+        GTK_TEXT_VIEW(glade_xml_get_widget( bench->xml, "description_view"));
+    bench->category_view = 
+        GTK_TREE_VIEW(glade_xml_get_widget(bench->xml, "category_view"));
+    bench->balance_view = 
+        GTK_TREE_VIEW(glade_xml_get_widget(bench->xml, "balance_budget_view"));
+    bench->track_view = 
+        GTK_TREE_VIEW(glade_xml_get_widget(bench->xml, "track_view"));
+    bench->length_button = 
+        GTK_SPIN_BUTTON(glade_xml_get_widget(bench->xml, "length_button"));
+    bench->length_menu = 
+        GTK_OPTION_MENU(glade_xml_get_widget(bench->xml, "length_menu"));
+    bench->period_menu = 
+        GTK_OPTION_MENU(glade_xml_get_widget(bench->xml, "period_menu"));
+    bench->period_label= 
+        GTK_LABEL(glade_xml_get_widget(bench->xml, "period_label"));
+
+    /* Set up the period frequency view. */
+    startDate = gnc_budget_get_start_date(bench->budget);
+    bench->freqWnd = GNC_FREQUENCY(
+            gnc_frequency_new(gnc_budget_get_period_frequency(bench->budget), startDate));
+    
+    /* Change the text so that its more mainingful for this druid*/
+    gnc_frequency_set_frequency_label_text(bench->freqWnd, _("Budget Period:"));
+    gnc_frequency_set_date_label_text(bench->freqWnd, _("Starting Date:"));
+        
+    /* Reparent to the correct location */
+    box = glade_xml_get_widget (bench->xml, "budget_freq_box");
+    gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (bench->freqWnd),TRUE, TRUE, 0);
+    
+    /* Create and assign the model. */
+    bench->category_model = gnc_budget_tree_model_new(bench->budget);
+    gtk_tree_view_set_model(bench->category_view, bench->category_model);
+    gtk_tree_view_set_model(bench->balance_view, bench->category_model);
+    gtk_tree_view_set_model(bench->track_view, bench->category_model);
+
+    /* Add the columns to the various tree views. */
+    add_category_columns(bench->category_view);
+    add_balance_budget_columns(bench);
+    add_track_columns(bench->track_view);
+
+    /* Connect the signal handlers. */
+    button = glade_xml_get_widget( bench->xml, "ok_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(ok_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "apply_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(apply_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "cancel_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(cancel_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "new_category_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(new_category_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "edit_category_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(edit_category_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "delete_category_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(delete_category_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "regenerate_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(regenerate_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "first_period_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(first_period_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "back_period_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(back_period_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "next_period_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(next_period_clicked), bench);
+    button = glade_xml_get_widget( bench->xml, "last_period_button" );
+    g_signal_connect( button, "clicked",
+                        G_CALLBACK(last_period_clicked), bench);
+    
+    /* Fill in the values based on our budget. */
+    workbench_from_budget(bench);
+    update_period_label(bench);
+}
+
+/* Public interface to create a budget workbench dialog. */
+void gnc_budget_workbench_dialog_create(GncBudget* budget)
+{
+    BudgetWorkbench* bench;
+
+    bench = g_new0(BudgetWorkbench, 1);
+    printf("Creating Workbench dialog: Budget: %p\n", budget);
+
+    bench->budget = budget;
+    bench->active_period = 0;
+    create_budget_workbench(bench);
+
+    printf("Showing Workbench dialog: Budget: %p\n", bench->budget);
+    gtk_widget_show_all(bench->wnd);
+}
--- /dev/null
+++ src/gnome/druid-budget-create.h
@@ -0,0 +1,44 @@
+/********************************************************************\
+ * druid-budget-create.h -- Public interface for the Budget         *
+ *                          creation druid.                         *
+ * Copyright (C) 08 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * 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 or more details.                      *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gui
+ *     @{ */
+/** @file druid-budget-create.h
+ *  @breif Public interface for the budget creation druid.
+ *  @author Created by Darin Willits 08 sep 2003 
+ *  @author Copyright (c) 08 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+#ifndef __DRUID_BUDGET_CREATE_H__
+#define __DRUID_BUDGET_CREATE_H__
+
+#include <glib.h>
+#include <gnome.h>
+
+/** Launch the Create Budget druid. */
+void gnc_budget_druid_create(GtkTreeModel* treeModel);
+
+
+#endif // __DRUID_BUDGET_CREATE_H__
--- /dev/null
+++ src/gnome/dialog-budget-list.c
@@ -0,0 +1,243 @@
+/********************************************************************\
+ * dialog-budget-list.c --  Implementation of the budget list       *
+ *                          dialog.                                 *
+ * Copyright (C) 08 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gui
+ *     @{ */
+/** @file dialog-budget-list.c
+ *  @breif Implementation of the budget list dialog.
+ *  @author Created by Darin Willits 08 sep 2003 
+ *  @author Copyright (c) 08 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ * This dialog presents the user with a list of the available budget 
+ * objects.  From here they can create a new budget or edit/delete
+ * an existing one.
+ */
+
+// Includes
+#include <glib.h>
+#include <gnome.h>
+
+#include "dialog-budget-list.h"
+#include "dialog-budget-workbench.h"
+#include "druid-budget-create.h"
+#include "dialog-utils.h"
+#include "gnc-ui-util.h"
+
+#include "gnc-budget-gui.h"
+#include "gnc-budget-book.h"
+#include "gnc-budget.h"
+#include "gnc-budget-list-tree-model.h"
+
+
+/* The budget list dialog structure. */
+typedef struct{
+    GtkWidget* wnd;
+    GladeXML* xml;
+    
+    GtkWidget* treeView;
+    GtkTreeModel* treeModel;
+
+} BudgetListDlg;
+
+/* The budget list columns. */
+enum{
+    COLUMN_NAME,
+    COLUMN_DESCRIPTION,
+    BUDGET_LIST_NUM_COLS
+};
+
+
+/* Add the new budget object to the tree model.  
+ * FIXME: This will be unnecessary once we create a tree model
+ * which directly relates to the book's list of budgets but for 
+ * now we have to hack around it.  This is ugly though and prone
+ * to error so it should/must be fixed.
+ */
+void add_budget_to_model( gpointer data, gpointer user_data )
+{
+    GncBudget* budget;
+    GtkTreeIter iter;
+    GtkTreeModel* treeModel;
+    /*BudgetListDlg* dlg;*/
+    
+    budget = data;
+    treeModel = user_data;
+
+    if((budget == NULL) || (treeModel == NULL)){
+        return;
+    }
+    
+    gtk_list_store_append (GTK_LIST_STORE(treeModel), &iter);
+    gtk_list_store_set (GTK_LIST_STORE(treeModel), &iter,
+			  COLUMN_NAME, gnc_budget_get_name(budget),
+			  COLUMN_DESCRIPTION, gnc_budget_get_description(budget),
+			  -1);
+}
+
+/* Initialize the tree model with the list of budgets from the
+ * book.
+ */
+/*
+static void fill_model(BudgetListDlg* dlg)
+{
+    GList *budgetList;
+    GtkListStore* store;
+
+    store = gtk_list_store_new (BUDGET_LIST_NUM_COLS,
+			      G_TYPE_STRING,
+			      G_TYPE_STRING);
+
+    dlg->treeModel = GTK_TREE_MODEL(store);
+    
+    budgetList = gnc_book_get_budgets(gnc_get_current_book());
+    g_list_foreach( budgetList, add_budget_to_model,  dlg->treeModel);
+}
+*/
+/* Add the columns to the tree view. */
+static void add_columns(GtkTreeView* treeView)
+{
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+
+    /* column for name */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Name",
+						     renderer,
+						     "text",
+						     COLUMN_NAME,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+
+    /* column for description */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Description",
+						     renderer,
+						     "text",
+						     COLUMN_DESCRIPTION,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+}
+
+/* Destroy the budget list dialog. */
+static void budget_list_dialog_destroy(BudgetListDlg* dlg)
+{
+    if(dlg == NULL){
+        return;
+    }
+    gtk_widget_destroy(dlg->wnd);
+    g_free(dlg);
+}
+
+/* Event handler for the close button. */
+static void close_button_clicked(GtkWidget* object, gpointer data)
+{
+    budget_list_dialog_destroy(data);
+}
+
+/* Event handler for the new button. */
+static void new_button_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetListDlg* dlg = data;
+
+    gnc_budget_druid_create(dlg->treeModel);
+}
+
+/* Event handler for the edit button.  Create a budget workbench 
+ * dialog with the given budget object. */
+static void edit_button_clicked(GtkWidget* object, gpointer data)
+{
+    GtkTreeIter iter;
+    BudgetListDlg* dlg = data;
+    GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(dlg->treeView));
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dlg->treeView));
+
+    /* If a budget is selected use it to create a budget workbench. */
+    if (gtk_tree_selection_get_selected (selection, NULL, &iter)){
+        gint i;
+        GtkTreePath *path;
+        GncBudget* budget;
+        GList* budgetList;
+
+        path = gtk_tree_model_get_path (model, &iter);
+        i = gtk_tree_path_get_indices (path)[0];
+    
+        budgetList = gnc_book_get_budgets(gnc_get_current_book());
+        budget = g_list_nth_data(budgetList, i);
+
+        if(budget != NULL){
+            printf("Creating Workbench: Budget: %p\n", budget);
+            /* Create the workbench. */
+            gnc_budget_workbench_dialog_create(budget);
+        }
+        
+        gtk_tree_path_free (path);
+    }
+}
+
+/* Create the budget list dialog. */
+static void budget_create_list_dialog(BudgetListDlg* dlg)
+{
+    GladeXML *xml;
+    GtkWidget *new_button;
+    GtkWidget *edit_button;
+    GtkWidget *close_button;
+    
+    /* Load the main dialog widget. */
+    xml = gnc_glade_xml_new (GNC_BUDGET_GUI_FILE, "Budget List");
+    dlg->wnd = glade_xml_get_widget(xml, "Budget List");
+    dlg->xml = xml;
+    
+    /* Create and fill the model */
+    /*fill_model(dlg);*/
+    dlg->treeModel = gnc_budget_list_tree_model_new(gnc_get_current_book());
+    
+    dlg->treeView = glade_xml_get_widget(xml, "Budget List View");
+    gtk_tree_view_set_model (GTK_TREE_VIEW(dlg->treeView), dlg->treeModel);
+
+    add_columns(GTK_TREE_VIEW(dlg->treeView));
+
+    
+    /* Connect signals. */
+    new_button = glade_xml_get_widget( dlg->xml, "new_button" );
+    g_signal_connect( new_button, "clicked",
+                        G_CALLBACK(new_button_clicked), dlg);
+    edit_button = glade_xml_get_widget( dlg->xml, "edit_button" );
+    g_signal_connect( edit_button, "clicked",
+                        G_CALLBACK(edit_button_clicked), dlg);
+    close_button = glade_xml_get_widget( dlg->xml, "close_button" );
+    g_signal_connect( close_button, "clicked",
+                        G_CALLBACK(close_button_clicked), dlg);
+}
+
+/* Public interface for creating a budget list dialog. */
+void gnc_budget_list_dialog_create(void)
+{
+    BudgetListDlg* dlg;
+
+    dlg = g_new0(BudgetListDlg, 1);
+
+    budget_create_list_dialog(dlg);
+    
+    gtk_widget_show_all(dlg->wnd);
+}
--- /dev/null
+++ src/gnome/dialog-budget-workbench.h
@@ -0,0 +1,43 @@
+/********************************************************************\
+ * dialog-budget-workbench.h -- Definition of the interface         *
+ *                              for the budget workbench dialog.    *
+ * Copyright (C) 14 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gnome
+ *     @{ */
+/** @file dialog-budget-workbench.h
+ *  @breif Definition of the budget workbench dialog interface.
+ *  @author Created by Darin Willits 14 sep 2003 
+ *  @author Copyright (c) 14 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+#ifndef __DIALOG_BUDGET_WORKBENCH_H__
+#define __DIALOG_BUDGET_WORKBENCH_H__
+
+#include "gnc-budget.h"
+
+/* Create a budget workbench dialog using the given budget object.
+ */
+void gnc_budget_workbench_dialog_create(GncBudget* budget);
+
+#endif // __DIALOG_BUDGET_WORKBENCH_H__
Index: Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/Makefile.am,v
retrieving revision 1.107.4.14
retrieving revision 1.107.4.15
diff -Lsrc/gnome/Makefile.am -Lsrc/gnome/Makefile.am -u -r1.107.4.14 -r1.107.4.15
--- src/gnome/Makefile.am
+++ src/gnome/Makefile.am
@@ -24,6 +24,9 @@
 libgw_gnc_la_LIBADD = libgncgnome.la
 
 libgncgnome_la_SOURCES = \
+  dialog-budget-category.c \
+  dialog-budget-list.c \
+  dialog-budget-workbench.c \
   dialog-commodities.c \
   dialog-fincalc.c \
   dialog-find-transactions.c \
@@ -38,6 +41,7 @@
   gnc-totd-dialog.c \
   dialog-userpass.c \
   dialog-scheduledxaction.c \
+  druid-budget-create.c \
   druid-acct-period.c \
   druid-hierarchy.c \
   druid-loan.c \
@@ -75,6 +79,9 @@
 mime_DATA = gnucash.keys gnucash.mime
 
 noinst_HEADERS = \
+  dialog-budget-category.h \
+  dialog-budget-list.h \
+  dialog-budget-workbench.h \
   dialog-fincalc.h \
   dialog-find-transactions.h \
   dialog-new-user.h \
@@ -84,6 +91,7 @@
   dialog-sxsincelast.h \
   gnc-totd-dialog.h \
   dialog-scheduledxaction.h \
+  druid-budget-create.h \
   druid-acct-period.h \
   druid-hierarchy.h \
   druid-loan.h \
--- /dev/null
+++ src/gnome/druid-budget-create.c
@@ -0,0 +1,326 @@
+/********************************************************************\
+ * druid-budget-create.c -- Implementation of the budget create     *
+ *                          druid.                                  *
+ * Copyright (C) 08 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gui 
+ *     @{ */
+/** @file druid-budget-create.c
+ *  @breif Implementation of the budget create druid.
+ *  @author Created by Darin Willits 08 sep 2003 
+ *  @author Copyright (c) 08 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ */
+
+// Includes
+#include <glib.h>
+#include <gnome.h>
+#include <libgnomeui/libgnomeui.h>
+
+#include "druid-budget-create.h"
+#include "gnc-budget.h"
+#include "dialog-budget-list.h"
+#include "gnc-budget-tree-model.h"
+#include "dialog-budget-category.h"
+#include "dialog-budget-workbench.h"
+
+#include "dialog-utils.h"
+#include "gnc-ui-util.h"
+#include "misc-gnome-utils.h"
+#include "gnc-frequency.h"
+#include "gnc-date-edit.h"
+
+#include "gnc-budget-gui.h"
+#include "gnc-budget-book.h"
+#include "gnc-budget.h"
+
+
+#define BUDGET_NAME_ENTRY           "name_entry"
+#define BUDGET_DESC_VIEW            "description_view"
+#define BUDGET_LENGTH_BUTTON        "length_button"
+#define BUDGET_TIME_SCALE           "time_scale_menu"
+#define BUDGET_TREE_VIEW            "budget_tree_view"
+#define BUDGET_LENGTH_BUTTON        "length_button"
+#define BUDGET_LENGTH_MENU          "length_menu"
+#define BUDGET_PERIOD_MENU          "period_menu"
+
+#define BUDGET_DRUID    "Budget Druid"
+#define BUDGET_FINISH_PAGE "finish_page"
+
+
+
+typedef struct{
+    GtkWidget* wnd;
+    GladeXML* xml;
+    GtkTreeModel* budgetListModel;
+    GtkTreeModel* budgetCatModel;
+
+    GtkEntry* nameEntry;
+    GtkTextView* descriptionView;
+    GtkTreeView* budgetView;
+    GtkSpinButton*  length_button;
+    GtkOptionMenu*  length_menu;
+    GNCFrequency* freqWnd;
+    
+    GncBudget* budget;
+    
+} BudgetDruid;
+
+
+static void budget_druid_destroy(BudgetDruid* druid)
+{
+    if(druid == NULL){
+        return;
+    }
+    gtk_widget_destroy(druid->wnd);
+    g_free(druid);
+}
+
+static void cancel_clicked(GnomeDruid *druid, gpointer user_data)
+{
+    budget_druid_destroy(user_data);
+}
+
+static void apply_clicked(GnomeDruidPage *page, GtkWidget* arg1, gpointer data)
+{
+    QofBook* book;
+    BudgetDruid* druid = data;
+    const gchar *name, *description;
+    FreqSpec* freqSpec;
+    //time_t tmpTimeT;
+    //GDate outDate;
+    GDate* startDate;
+    gint length;//, period;
+    
+    book = gnc_get_current_book();
+
+    if(druid->budget == NULL){
+        /* something terribly wrong. */
+        return;
+    }
+    
+    /* Set the name and description of the budget. */
+    name = gtk_entry_get_text(druid->nameEntry);
+    description = xxxgtk_textview_get_text(druid->descriptionView);
+
+    gnc_budget_set_name(druid->budget, name);
+    gnc_budget_set_description(druid->budget, description);
+    
+    /* Set the length of the budget. */
+    length = gtk_spin_button_get_value_as_int(druid->length_button);
+    if(gtk_option_menu_get_history(druid->length_menu) == 1){
+        gnc_budget_set_length_years(druid->budget, length);
+    }
+    else{
+        gnc_budget_set_length_months(druid->budget, length);
+    }
+    
+    freqSpec = gnc_budget_get_period_frequency(druid->budget);
+    startDate = gnc_budget_get_start_date(druid->budget);
+    if(freqSpec == NULL){
+        freqSpec = xaccFreqSpecMalloc(gnc_budget_get_book(druid->budget));
+    }
+    gnc_frequency_save_state( druid->freqWnd, freqSpec, startDate);
+    gnc_budget_set_period_frequency(druid->budget, freqSpec);
+ 
+    /* Add the budget to the book. */
+    gnc_book_add_budget(book, druid->budget);
+ 
+    /* FIXME: This is just a temporary mesure and won't be necessary once
+     * we connect up to the gnc gui event system.  We will also need to be
+     * generating the proper events from the budget engine structures so 
+     * for now we will just do this.
+     */
+    /*add_budget_to_model(druid->budget, druid->budgetListModel);*/
+
+    printf("Generating periods: Druid %p Budget: %p\n", druid, druid->budget);
+    /* Generate the list of budget periods. */
+    gnc_budget_generate_periods(druid->budget);
+    
+    budget_druid_destroy(druid);
+}
+
+static void add_columns(GtkTreeView* treeView)
+{
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+
+    /* column for severities */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Name",
+						     renderer,
+						     "text",
+						     GNC_BUDGET_TREE_MODEL_COL_NAME,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+
+    /* column for value */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Value",
+						     renderer,
+						     "text",
+						     GNC_BUDGET_TREE_MODEL_COL_VALUE,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+    
+    /* column for freq */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Frequency",
+						     renderer,
+						     "text",
+						     GNC_BUDGET_TREE_MODEL_COL_FREQ,
+						     NULL);
+    gtk_tree_view_append_column (treeView, column);
+}
+
+static void edit_category_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetDruid* druid = data;
+    GtkTreeSelection *selection;
+    GtkTreeIter iter;
+    GncBudgetCategory *category = NULL;
+
+    printf("Editing Category... Druid: %p Budget: %p\n",druid, druid->budget);
+    selection = gtk_tree_view_get_selection (druid->budgetView);
+    if (!gtk_tree_selection_get_selected (selection, &druid->budgetCatModel, &iter)){
+        printf("Nothing selected...\n");
+        return;
+    }
+
+    category = gnc_budget_tree_model_get_category(GNC_BUDGET_TREE_MODEL(druid->budgetCatModel), &iter);
+
+    gnc_budget_category_dialog_create(druid->budget, category);
+}
+
+static void new_category_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetDruid* druid = data;
+
+    printf("Creating new Category... Budget: %p\n", druid->budget);
+    gnc_budget_category_new_dialog_create(druid->budget);
+}
+
+static void delete_category_clicked(GtkWidget* object, gpointer data)
+{
+    BudgetDruid* druid = data;
+    GtkTreeSelection *selection;
+    GtkTreeIter iter;
+    GncBudgetCategory *category, *inflowCat, *outflowCat;
+
+    printf("Deleting Category...\n");
+    selection = gtk_tree_view_get_selection (druid->budgetView);
+    if (!gtk_tree_selection_get_selected (selection, &druid->budgetCatModel, &iter)){
+        printf("Nothing selected...\n");
+        return;
+    }
+
+    category = gnc_budget_tree_model_get_category(GNC_BUDGET_TREE_MODEL(druid->budgetCatModel), &iter);
+    inflowCat = gnc_budget_get_inflow_category(druid->budget);
+    outflowCat = gnc_budget_get_outflow_category(druid->budget);
+
+    if((category != inflowCat) && (category != outflowCat)){
+        gnc_budget_category_delete(category);
+    }
+    else{
+        printf("Cannot delete this category...\n");
+    }
+    
+}
+
+static void create_budget_druid(BudgetDruid* druid)
+{
+    GladeXML *xml;
+    GtkWidget *box;
+    GnomeDruid* budgetDruid;
+    GtkWidget *final_page;
+    GtkWidget* editCategoryButton;
+    GtkWidget* newCategoryButton;
+    GtkWidget* deleteCategoryButton;
+     
+    druid->budget = gnc_budget_new(gnc_get_current_book());
+
+    xml = gnc_glade_xml_new (GNC_BUDGET_GUI_FILE, "New Budget Druid");
+    druid->wnd = glade_xml_get_widget(xml, "New Budget Druid");
+    druid->xml = xml;
+
+    druid->nameEntry = 
+        GTK_ENTRY(glade_xml_get_widget( druid->xml, BUDGET_NAME_ENTRY));
+    druid->descriptionView = 
+        GTK_TEXT_VIEW(glade_xml_get_widget( druid->xml, BUDGET_DESC_VIEW));
+    druid->budgetView = 
+        GTK_TREE_VIEW(glade_xml_get_widget(druid->xml, BUDGET_TREE_VIEW));
+    druid->length_button = 
+        GTK_SPIN_BUTTON(glade_xml_get_widget(druid->xml, BUDGET_LENGTH_BUTTON));
+    druid->length_menu = 
+        GTK_OPTION_MENU(glade_xml_get_widget(druid->xml, BUDGET_LENGTH_MENU));
+
+    /* Set the default length to 1 year. */
+    gtk_option_menu_set_history(druid->length_menu, 1);
+
+    /* Set up the period frequency view. */
+    druid->freqWnd = GNC_FREQUENCY(
+            gnc_frequency_new(gnc_budget_get_period_frequency(druid->budget), 
+                                gnc_budget_get_start_date(druid->budget)));
+    
+    /* Change the text so that its more mainingful for this druid*/
+    gnc_frequency_set_frequency_label_text(druid->freqWnd, _("Budget Period:"));
+    gnc_frequency_set_date_label_text(druid->freqWnd, _("Starting Date:"));
+        
+    /* Reparent to the correct location */
+    box = glade_xml_get_widget (druid->xml, "budget_freq_box");
+    gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (druid->freqWnd),TRUE, TRUE, 0);
+ 
+    /* Create the budget Tree model. */
+    druid->budgetCatModel = gnc_budget_tree_model_new(druid->budget);
+    gtk_tree_view_set_model(druid->budgetView, druid->budgetCatModel);
+
+    add_columns(druid->budgetView);
+        
+    /* Connect signals. */
+    final_page = glade_xml_get_widget( druid->xml, BUDGET_FINISH_PAGE );
+    g_signal_connect(final_page, "finish", G_CALLBACK(apply_clicked), druid);
+
+    budgetDruid =  GNOME_DRUID(glade_xml_get_widget( druid->xml, BUDGET_DRUID ));
+    g_signal_connect(budgetDruid, "cancel", G_CALLBACK(cancel_clicked), druid);
+
+    editCategoryButton = glade_xml_get_widget( druid->xml, "edit_category_button" );
+    g_signal_connect(editCategoryButton, "clicked", G_CALLBACK(edit_category_clicked), druid);
+    
+    newCategoryButton = glade_xml_get_widget( druid->xml, "new_category_button" );
+    g_signal_connect(newCategoryButton, "clicked", G_CALLBACK(new_category_clicked), druid);
+    
+    deleteCategoryButton = glade_xml_get_widget( druid->xml, "delete_category_button" );
+    g_signal_connect(deleteCategoryButton, "clicked", G_CALLBACK(delete_category_clicked), druid);
+}
+
+void gnc_budget_druid_create(GtkTreeModel* treeModel)
+{
+    BudgetDruid* druid;
+
+    druid = g_new0(BudgetDruid, 1);
+
+    druid->budgetListModel = treeModel;
+    
+    create_budget_druid(druid);
+    
+    gtk_widget_show_all(druid->wnd);
+}
--- /dev/null
+++ src/gnome-utils/gnc-budget-tree-model.c
@@ -0,0 +1,726 @@
+/********************************************************************\
+ * gnc-budget-tree-model.c -- Implementation of the budget tree     *
+ *                            model.                                *
+ * Copyright (C) 09 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gnome-util
+ *     @{ */
+/** @file gnc-budget-tree-model.c
+ *  @breif Implementation of the budget tree model.
+ *  @author Created by Darin Willits 09 sep 2003 
+ *  @author Copyright (c) 09 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ *  This should be fun...
+ */
+
+// Includes
+#include "config.h"
+#include <string.h>
+#include "gnc-trace.h"
+
+#include "gnc-budget-tree-model.h"
+#include "gnc-budget-cat.h"
+
+static short module = MOD_GUI;
+
+/** Initialize and clean-up functions. */
+static void gnc_budget_tree_model_class_init (GncBudgetTreeModelClass *klass);
+static void gnc_budget_tree_model_init (GncBudgetTreeModel *model);
+static void gnc_budget_tree_model_finalize (GObject *object);
+static void gnc_budget_tree_model_destroy (GtkObject *object);
+static void gnc_budget_tree_model_gtk_tree_model_init (GtkTreeModelIface *iface);
+
+/* GtkTreeModel Interface functions. */
+static guint gnc_budget_tree_model_get_flags (GtkTreeModel *tree_model);
+static int gnc_budget_tree_model_get_n_columns (GtkTreeModel *tree_model);
+static GType gnc_budget_tree_model_get_column_type (GtkTreeModel *tree_model,
+						     int index);
+static gboolean gnc_budget_tree_model_get_iter (GtkTreeModel *tree_model,
+						 GtkTreeIter *iter,
+						 GtkTreePath *path);
+static GtkTreePath *gnc_budget_tree_model_get_path (GtkTreeModel *tree_model,
+						     GtkTreeIter *iter);
+static void gnc_budget_tree_model_get_value (GtkTreeModel *tree_model,
+					      GtkTreeIter *iter,
+					      int column,
+					      GValue *value);
+static gboolean	gnc_budget_tree_model_iter_next (GtkTreeModel *tree_model,
+						  GtkTreeIter *iter);
+static gboolean	gnc_budget_tree_model_iter_children (GtkTreeModel *tree_model,
+						      GtkTreeIter *iter,
+						      GtkTreeIter *parent);
+static gboolean	gnc_budget_tree_model_iter_has_child (GtkTreeModel *tree_model,
+						       GtkTreeIter *iter);
+static int gnc_budget_tree_model_iter_n_children (GtkTreeModel *tree_model,
+						   GtkTreeIter *iter);
+static gboolean	gnc_budget_tree_model_iter_nth_child (GtkTreeModel *tree_model,
+						       GtkTreeIter *iter,
+						       GtkTreeIter *parent,
+						       int n);
+static gboolean	gnc_budget_tree_model_iter_parent (GtkTreeModel *tree_model,
+						    GtkTreeIter *iter,
+    						    GtkTreeIter *child);
+
+/* Private internal data structure. */
+struct GncBudgetTreeModelPrivate
+{
+    GncBudget* budget;
+    GncBudgetCategory* top_category;
+    GncBudgetCategory* balance_category;
+	gint event_handler_id;
+};
+
+/************************************************************/
+/*               g_object required functions                */
+/************************************************************/
+
+static GtkObjectClass *parent_class = NULL;
+
+GType
+gnc_budget_tree_model_get_type (void)
+{
+	static GType gnc_budget_tree_model_type = 0;
+
+	if (gnc_budget_tree_model_type == 0) {
+		static const GTypeInfo our_info = {
+			sizeof (GncBudgetTreeModelClass), /* class_size */
+			NULL,   			   /* base_init */
+			NULL,				   /* base_finalize */
+			(GClassInitFunc) gnc_budget_tree_model_class_init,
+			NULL,				   /* class_finalize */
+			NULL,				   /* class_data */
+			sizeof (GncBudgetTreeModel),	   /* */
+			0,				   /* n_preallocs */
+			(GInstanceInitFunc) gnc_budget_tree_model_init
+		};
+		
+		static const GInterfaceInfo budget_tree_model_info = {
+			(GInterfaceInitFunc) gnc_budget_tree_model_gtk_tree_model_init,
+			NULL,
+			NULL
+		};
+
+		gnc_budget_tree_model_type = g_type_register_static (GTK_TYPE_OBJECT,
+								      "GncBudgetTreeModel",
+								      &our_info, 0);
+        
+		g_type_add_interface_static (gnc_budget_tree_model_type,
+					     GTK_TYPE_TREE_MODEL,
+					     &budget_tree_model_info);
+	}
+    
+	return gnc_budget_tree_model_type;
+}
+
+static void
+gnc_budget_tree_model_class_init (GncBudgetTreeModelClass *klass)
+{
+	GObjectClass *o_class;
+	GtkObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	o_class = G_OBJECT_CLASS (klass);
+	object_class = GTK_OBJECT_CLASS (klass);
+
+	/* GObject signals */
+	o_class->finalize = gnc_budget_tree_model_finalize;
+
+	/* GtkObject signals */
+	object_class->destroy = gnc_budget_tree_model_destroy;
+}
+
+static void
+gnc_budget_tree_model_init (GncBudgetTreeModel *model)
+{
+	ENTER("model %p", model);
+	while (model->stamp == 0) {
+		model->stamp = g_random_int ();
+	}
+
+	model->priv = g_new0 (GncBudgetTreeModelPrivate, 1);
+	model->priv->budget = NULL;
+	LEAVE(" ");
+}
+
+static void
+gnc_budget_tree_model_finalize (GObject *object)
+{
+	GncBudgetTreeModel *model;
+
+	ENTER("model %p", object);
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNC_IS_BUDGET_TREE_MODEL (object));
+
+	model = GNC_BUDGET_TREE_MODEL(object);
+	g_free (model->priv);
+
+	if (G_OBJECT_CLASS (parent_class)->finalize)
+	  (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+	LEAVE(" ");
+}
+
+static void
+gnc_budget_tree_model_destroy (GtkObject *object)
+{
+	GncBudgetTreeModel *model;
+
+	ENTER("model %p", object);
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNC_IS_BUDGET_TREE_MODEL(object));
+
+	model = GNC_BUDGET_TREE_MODEL(object);
+
+	/*active_models = g_list_remove(active_models, model);
+
+	if (model->priv->event_handler_id) {
+	  gnc_engine_unregister_event_handler (model->priv->event_handler_id);
+	  model->priv->event_handler_id = 0;
+	}
+    */
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+	  (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+	LEAVE(" ");
+}
+
+/******************************************************
+ * GtkTreeModel Interface Methods.
+ *
+ * ****************************************************/
+
+static void gnc_budget_tree_model_gtk_tree_model_init(GtkTreeModelIface *iface)
+{
+	iface->get_flags       = gnc_budget_tree_model_get_flags;
+	iface->get_n_columns   = gnc_budget_tree_model_get_n_columns;
+	iface->get_column_type = gnc_budget_tree_model_get_column_type;
+	iface->get_iter        = gnc_budget_tree_model_get_iter;
+	iface->get_path        = gnc_budget_tree_model_get_path;
+	iface->get_value       = gnc_budget_tree_model_get_value;
+	iface->iter_next       = gnc_budget_tree_model_iter_next;
+	iface->iter_children   = gnc_budget_tree_model_iter_children;
+	iface->iter_has_child  = gnc_budget_tree_model_iter_has_child;
+	iface->iter_n_children = gnc_budget_tree_model_iter_n_children;
+	iface->iter_nth_child  = gnc_budget_tree_model_iter_nth_child;
+	iface->iter_parent     = gnc_budget_tree_model_iter_parent;
+}
+
+static guint gnc_budget_tree_model_get_flags (GtkTreeModel *tree_model)
+{
+    return 0;
+}
+
+static int gnc_budget_tree_model_get_n_columns (GtkTreeModel *tree_model)
+{
+    GncBudgetTreeModel *model;
+    gint numCols;
+	model = GNC_BUDGET_TREE_MODEL(tree_model);
+    numCols =  GNC_BUDGET_TREE_MODEL_NUM_STATIC_COLUMNS + 
+                        gnc_budget_get_num_periods(model->priv->budget);
+    printf("NumCols: %d\n", numCols);
+    return numCols;
+}
+
+static GType gnc_budget_tree_model_get_column_type (GtkTreeModel *tree_model, int index)
+{
+ 	g_return_val_if_fail (GNC_IS_BUDGET_TREE_MODEL(tree_model), G_TYPE_INVALID);
+    //g_return_val_if_fail ((index < GNC_BUDGET_TREE_MODEL_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
+
+    return G_TYPE_STRING;
+/*
+	switch (index) {
+        case GNC_BUDGET_TREE_MODEL_COL_NAME:
+		case GNC_BUDGET_TREE_MODEL_COL_VALUE:
+        case GNC_BUDGET_TREE_MODEL_COL_FREQ:
+			return G_TYPE_STRING;
+		default:
+			g_assert_not_reached ();
+			return G_TYPE_INVALID;
+	}
+*/
+}
+
+static gboolean gnc_budget_tree_model_get_iter (GtkTreeModel *tree_model, 
+                                                GtkTreeIter *iter,
+						                        GtkTreePath *path)
+{
+	GncBudgetTreeModel *model;
+    GncBudgetCategory* category;
+	gint i = 0, *indices;
+	GtkTreePath *path_copy;
+
+	{
+	    gchar *path_string = gtk_tree_path_to_string(path);
+	    ENTER("model %p, iter %p, path %s", tree_model, iter, path_string);
+	    g_free(path_string);
+	}
+	g_return_val_if_fail (GNC_IS_BUDGET_TREE_MODEL(tree_model), FALSE);
+
+	model = GNC_BUDGET_TREE_MODEL(tree_model);
+
+	path_copy = gtk_tree_path_copy(path);
+
+	if ((model->priv->budget == NULL) || (model->priv->top_category == NULL)) {
+		LEAVE("failed (2)");
+		return FALSE;
+	}
+
+    category = model->priv->top_category;
+    
+    indices = gtk_tree_path_get_indices (path);
+    for(i = 0; i < gtk_tree_path_get_depth (path); i++){
+        category = gnc_budget_category_get_child(category, indices[i]);
+        
+        if(category == NULL){
+            LEAVE("failed (3)");
+            return FALSE;
+        }
+    }
+    
+    if(category == NULL){
+        return FALSE;
+    }
+    
+	iter->stamp = model->stamp;
+	iter->user_data = category;
+
+	LEAVE("category %s", gnc_budget_category_get_name(category));
+	return TRUE;    
+}
+
+static GtkTreePath *gnc_budget_tree_model_get_path (GtkTreeModel *tree_model,
+                        						     GtkTreeIter *iter)
+{
+ 	GncBudgetTreeModel *model = GNC_BUDGET_TREE_MODEL(tree_model);
+	GtkTreePath *path;
+    GncBudgetCategory* category, *parent;
+
+	g_return_val_if_fail (GNC_IS_BUDGET_TREE_MODEL(model), NULL);
+	g_return_val_if_fail (iter != NULL, NULL);
+	g_return_val_if_fail (iter->user_data != NULL, NULL);
+	g_return_val_if_fail (iter->stamp == model->stamp, NULL);
+	
+	if (model->priv->budget == NULL){
+		return NULL;
+    }
+
+	path = gtk_tree_path_new ();
+    category = iter->user_data;
+
+    if(category == model->priv->top_category){
+        gtk_tree_path_prepend_index(path, 0);
+
+	    {
+		    gchar* path_string = gtk_tree_path_to_string(path);
+			LEAVE("path (2) %s", path_string);
+			g_free(path_string);
+		}
+		return path;
+    }
+
+    
+    do{
+        parent = gnc_budget_category_get_parent(category);
+        gtk_tree_path_prepend_index(path,
+                gnc_budget_category_get_index_in_parent_list(category));
+                                            
+        category = gnc_budget_category_get_parent(category);
+    }while(parent != model->priv->top_category);
+
+    {
+        gchar* path_string = gtk_tree_path_to_string(path);
+        LEAVE("path (2) %s", path_string);
+        g_free(path_string);
+    } 
+	return path;   
+}
+
+static void gnc_budget_tree_model_get_value (GtkTreeModel *tree_model,
+				                    	      GtkTreeIter *iter,
+                					          int column,
+					                          GValue *value)
+{
+	GncBudgetTreeModel* model = GNC_BUDGET_TREE_MODEL(tree_model);
+    GncBudgetCategory* category;
+    char buffer[256];
+    gchar* tempStr;
+    double floatValue;
+    GString* freqStr;
+    int index;
+
+	g_return_if_fail (GNC_IS_BUDGET_TREE_MODEL(model));
+	g_return_if_fail (iter != NULL);
+	g_return_if_fail (iter->user_data != NULL);
+	g_return_if_fail (iter->stamp == model->stamp);
+
+    category = (GncBudgetCategory*)iter->user_data;
+    ENTER("Col: %d, Category: %s", column, gnc_budget_category_get_name(category));
+    if(column == GNC_BUDGET_TREE_MODEL_COL_EDITABLE){
+        g_value_init(value, G_TYPE_BOOLEAN);
+        
+        if((category == gnc_budget_get_inflow_category(model->priv->budget)) ||
+           (category == gnc_budget_get_outflow_category(model->priv->budget)) ||
+           (category == model->priv->balance_category)){
+            g_value_set_boolean(value, FALSE);
+        }
+        else{
+            g_value_set_boolean(value, TRUE);
+        }
+        return;
+    }
+
+    if((column >= GNC_BUDGET_TREE_MODEL_NUM_STATIC_COLUMNS) && 
+        (column < (GNC_BUDGET_TREE_MODEL_NUM_STATIC_COLUMNS + 
+                    gnc_budget_get_num_periods(model->priv->budget)))){
+        index = column - (GNC_BUDGET_TREE_MODEL_NUM_STATIC_COLUMNS);
+        g_value_init (value, G_TYPE_STRING);
+        
+        if(category == gnc_budget_get_inflow_category(model->priv->budget)){
+            floatValue = gnc_budget_category_sum_child_values_by_index(
+                                    gnc_budget_get_inflow_category(model->priv->budget), index);
+        }
+        else if(category == gnc_budget_get_outflow_category(model->priv->budget)){
+            floatValue = gnc_budget_category_sum_child_values_by_index(
+                                    gnc_budget_get_outflow_category(model->priv->budget), index);
+        }
+        else if(category == model->priv->balance_category){
+            floatValue = gnc_budget_category_sum_child_values_by_index(
+                                    gnc_budget_get_inflow_category(model->priv->budget), index);
+            floatValue += (-1) * gnc_budget_category_sum_child_values_by_index(
+                                    gnc_budget_get_outflow_category(model->priv->budget), index);
+        }
+        else{
+            floatValue = gnc_numeric_to_double(
+                gnc_budget_category_get_value_by_index(category, index));
+        }
+        
+        sprintf(buffer, "%0.2f", floatValue);
+        tempStr = g_strdup(buffer);
+		
+        g_value_set_string(value, tempStr);
+        g_free(tempStr);
+        return;
+    }
+    
+	switch (column) {
+		case GNC_BUDGET_TREE_MODEL_COL_NAME:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, gnc_budget_category_get_name(category));
+			break;
+		case GNC_BUDGET_TREE_MODEL_COL_VALUE:
+			/*g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, "");*/
+			g_value_init (value, G_TYPE_STRING);
+            
+            floatValue = gnc_numeric_to_double(gnc_budget_category_get_value(category));
+            sprintf(buffer, "%0.2f", floatValue);
+            tempStr = g_strdup(buffer);
+			g_value_set_string(value, tempStr);
+            g_free(tempStr);
+			break;
+		case GNC_BUDGET_TREE_MODEL_COL_FREQ:
+			/*g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, "");*/
+			g_value_init (value, G_TYPE_STRING);
+            freqStr = g_string_sized_new(16);
+            xaccFreqSpecGetFreqStr(gnc_budget_category_get_frequency(category), freqStr);
+			g_value_set_string (value, freqStr->str);
+			break;
+        case GNC_BUDGET_TREE_MODEL_COL_LAST_OVERFLOW:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, "0.0");
+            break;
+        case GNC_BUDGET_TREE_MODEL_COL_ACTUAL:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, "0.0");
+            break;
+        case GNC_BUDGET_TREE_MODEL_COL_PLANNED:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, "0.0");
+            break;
+        case GNC_BUDGET_TREE_MODEL_COL_CUR_OVERFLOW:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, "0.0");
+            break;
+		default:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, "0.0");
+            break;
+	}
+    
+    LEAVE("category %s, column %d", gnc_budget_category_get_name(category), column);
+}
+
+static gboolean	gnc_budget_tree_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+ 	GncBudgetTreeModel *model = GNC_BUDGET_TREE_MODEL(tree_model);
+    int numChildren, index;
+    GncBudgetCategory* parent, *category;
+
+	g_return_val_if_fail (GNC_IS_BUDGET_TREE_MODEL(model), FALSE);
+	g_return_val_if_fail (iter != NULL, FALSE);
+	g_return_val_if_fail (iter->user_data != NULL, FALSE);
+	g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
+    ENTER("iter_next:category %s", gnc_budget_category_get_name(iter->user_data));
+
+    category = iter->user_data;
+
+    if(category == model->priv->top_category){
+	    iter->stamp = 0;
+		LEAVE("failed (1)");
+        return FALSE; 
+    }
+    
+    parent = gnc_budget_category_get_parent(category);
+    
+    numChildren = gnc_budget_category_get_num_children(parent);
+    index = gnc_budget_category_get_index_in_parent_list(category);
+
+    if(index > (numChildren - 2)){
+		iter->stamp = 0;
+		LEAVE("failed (2)");
+		return FALSE;
+    }
+
+    category = gnc_budget_category_get_child(parent, index + 1);
+
+    if(category == NULL){
+		iter->stamp = 0;
+		LEAVE("failed (3)");
+		return FALSE;
+    }
+
+    iter->user_data = category;
+
+    LEAVE("iter_next:category %s", gnc_budget_category_get_name(iter->user_data));
+	return TRUE;   
+}
+
+static gboolean	gnc_budget_tree_model_iter_children (GtkTreeModel *tree_model,
+                        						      GtkTreeIter *iter,
+						                              GtkTreeIter *parent)
+{
+    GncBudgetCategory* parentCat, *category;
+ 	GncBudgetTreeModel *model = GNC_BUDGET_TREE_MODEL(tree_model);
+    g_return_val_if_fail (GNC_IS_BUDGET_TREE_MODEL(tree_model), FALSE);
+    g_return_val_if_fail (iter != NULL, FALSE);
+
+	if (parent == NULL){
+        iter->user_data = model->priv->top_category;
+	    iter->stamp = model->stamp;
+		return TRUE;
+    }
+    parentCat = parent->user_data;
+    category = gnc_budget_category_get_child(parentCat, 0);
+
+    if(category == NULL){
+        return FALSE;
+    }
+
+    iter->user_data = category;
+    iter->stamp = model->stamp;
+        
+    LEAVE("iter_children");
+	return TRUE;   
+}
+
+static gboolean	gnc_budget_tree_model_iter_has_child (GtkTreeModel *tree_model,
+                        						       GtkTreeIter *iter)
+{
+	GncBudgetTreeModel *model;
+    GncBudgetCategory* category;
+
+	g_return_val_if_fail (GNC_IS_BUDGET_TREE_MODEL(tree_model), FALSE);
+
+	model = GNC_BUDGET_TREE_MODEL(tree_model);
+
+	g_return_val_if_fail (iter != NULL, FALSE);
+	g_return_val_if_fail (iter->user_data != NULL, FALSE);
+	g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
+
+    category = iter->user_data;
+
+    if(gnc_budget_category_get_num_children(category) == 0){
+        LEAVE("no");
+        return FALSE;
+    }
+
+	LEAVE("yes");
+	return TRUE;
+}
+
+static int gnc_budget_tree_model_iter_n_children (GtkTreeModel *tree_model,
+                        						   GtkTreeIter *iter)
+{
+	GncBudgetTreeModel *model;
+    GncBudgetCategory* category;
+
+	g_return_val_if_fail (GNC_IS_BUDGET_TREE_MODEL(tree_model), FALSE);
+
+	model = GNC_BUDGET_TREE_MODEL(tree_model);
+
+	g_return_val_if_fail (iter != NULL, FALSE);
+	g_return_val_if_fail (iter->user_data != NULL, FALSE);
+	g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
+
+    category = iter->user_data;
+
+	LEAVE("count is %d", gnc_budget_category_get_num_children(category));
+	return gnc_budget_category_get_num_children(category);    
+}
+
+static gboolean	gnc_budget_tree_model_iter_nth_child (GtkTreeModel *tree_model,
+                        						        GtkTreeIter *iter,
+						                                GtkTreeIter *parent,
+						                                int n)
+{
+	GncBudgetTreeModel *model;
+    GncBudgetCategory* category, *parentCat;
+	
+	g_return_val_if_fail(GNC_IS_BUDGET_TREE_MODEL(tree_model), FALSE);
+    g_return_val_if_fail (iter != NULL, FALSE);
+
+	model = GNC_BUDGET_TREE_MODEL(tree_model);
+
+	if (parent == NULL){
+        parentCat = model->priv->top_category;
+    }
+    else{
+        parentCat = parent->user_data;
+    }
+
+    category = gnc_budget_category_get_child(parentCat, n);
+    
+	iter->user_data = category;
+	iter->stamp = model->stamp;
+
+	if (iter->user_data == NULL) {
+		iter->stamp = 0;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean	gnc_budget_tree_model_iter_parent (GtkTreeModel *tree_model,
+                        						    GtkTreeIter *iter,
+    					                    	    GtkTreeIter *child)
+{
+ 	GncBudgetTreeModel *model;
+    GncBudgetCategory* category, *parentCat;
+	
+    model = GNC_BUDGET_TREE_MODEL(tree_model);
+	
+	g_return_val_if_fail(GNC_IS_BUDGET_TREE_MODEL(tree_model), FALSE);
+	g_return_val_if_fail (child != NULL, FALSE);
+	g_return_val_if_fail (child->user_data != NULL, FALSE);
+	g_return_val_if_fail (child->stamp == model->stamp, FALSE);
+	
+    g_return_val_if_fail (iter != NULL, FALSE);
+
+
+    category = child->user_data;
+    
+    parentCat = gnc_budget_category_get_parent(category);
+    
+	iter->user_data = parentCat;
+	iter->stamp = model->stamp;
+
+	if (iter->user_data == NULL) {
+		iter->stamp = 0;
+		return FALSE;
+	}
+
+    return TRUE;
+}
+
+
+
+
+
+
+
+
+
+
+
+/*******************************************************
+ * Public Interface.
+ * 
+ * *****************************************************/
+
+GtkTreeModel* gnc_budget_tree_model_new(GncBudget* budget)
+{
+	GncBudgetTreeModel *model;
+	
+	ENTER("budget %p", budget);
+
+    /*
+	for (item = active_models; item; item = g_list_next(item)) {
+		model = (GncTreeModelAccount *)item->data;
+		if (model->priv->root == group) {
+			LEAVE("returning existing model %p", model);
+			return GTK_TREE_MODEL(model);
+		}
+	}
+    */
+
+	model = g_object_new (GNC_TYPE_BUDGET_TREE_MODEL, NULL);
+
+	model->priv->budget = budget;
+    printf("Creating dummy category.  Budget %p\n", budget);
+	model->priv->top_category = gnc_budget_category_new(gnc_budget_get_book(budget), budget);
+    gnc_budget_category_set_name(model->priv->top_category, "Dummy Category");
+    printf("Adding inflow category...\n");
+    gnc_budget_category_add_child(model->priv->top_category, 
+                                    gnc_budget_get_inflow_category(budget));
+    printf("Adding outflow category...\n");
+    gnc_budget_category_add_child(model->priv->top_category, 
+                                    gnc_budget_get_outflow_category(budget));
+	
+    model->priv->balance_category = gnc_budget_category_new(gnc_budget_get_book(budget), budget);
+    gnc_budget_category_set_name(model->priv->balance_category, "Total Budget Balance");
+    gnc_budget_category_add_child(model->priv->top_category, model->priv->balance_category);
+
+    /*
+	priv->event_handler_id =
+	  gnc_engine_register_event_handler (gnc_tree_model_account_event_handler, model);
+    
+	active_models = g_list_append (active_models, model);
+    */
+    
+	LEAVE("model %p", model);
+	return GTK_TREE_MODEL (model);
+
+}
+
+
+GncBudgetCategory* gnc_budget_tree_model_get_category(GncBudgetTreeModel* model, GtkTreeIter* iter)
+{
+	g_return_val_if_fail (GNC_IS_BUDGET_TREE_MODEL(model), NULL);
+	g_return_val_if_fail (iter != NULL, NULL);
+	g_return_val_if_fail (iter->user_data != NULL, NULL);
+	g_return_val_if_fail (iter->stamp == model->stamp, NULL);
+
+    printf("Category Selected: %s\n", gnc_budget_category_get_name(iter->user_data));
+	return (GncBudgetCategory *) iter->user_data;    
+}
--- /dev/null
+++ src/gnome-utils/gnc-budget-tree-model.h
@@ -0,0 +1,91 @@
+/********************************************************************\
+ * gnc-budget-tree-model.h --  Defintion of the tree model for      *
+ *                             budget objects.                      *
+ * Copyright (C) 09 sep 2003    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gnome-util
+ *     @{ */
+/** @file gnc-budget-tree-model.h
+ *  @breif Definition of the tree model for budget objects.
+ *  @author Created by Darin Willits 09 sep 2003 
+ *  @author Copyright (c) 09 sep 2003 Darin Willits <darin at willits.ca>
+ *
+ *  Lets try implementing our own GtkTreeModel shall we??
+ */
+
+#ifndef __GNC_BUDGET_TREE_MODEL_H__
+#define __GNC_BUDGET_TREE_MODEL_H__
+
+#include <gtk/gtktreemodel.h>
+#include "gnc-budget.h"
+
+G_BEGIN_DECLS
+
+/* type macros */
+#define GNC_TYPE_BUDGET_TREE_MODEL              (gnc_budget_tree_model_get_type ())
+#define GNC_BUDGET_TREE_MODEL(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_BUDGET_TREE_MODEL, GncBudgetTreeModel))
+#define GNC_BUDGET_TREE_MODEL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_BUDGET_TREE_MODEL, GncBudgetTreeModelClass))
+#define GNC_IS_BUDGET_TREE_MODEL(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_BUDGET_TREE_MODEL))
+#define GNC_IS_BUDGET_TREE_MODEL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_BUDGET_TREE_MODEL))
+#define GNC_BUDGET_TREE_MODEL_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_BUDGET_TREE_MODEL, GncBudgetTreeModelClass))
+
+/** Column defintions */
+typedef enum{
+    GNC_BUDGET_TREE_MODEL_COL_NAME,
+    GNC_BUDGET_TREE_MODEL_COL_VALUE,
+    GNC_BUDGET_TREE_MODEL_COL_FREQ,
+    GNC_BUDGET_TREE_MODEL_COL_LAST_OVERFLOW,
+    GNC_BUDGET_TREE_MODEL_COL_ACTUAL,
+    GNC_BUDGET_TREE_MODEL_COL_PLANNED,
+    GNC_BUDGET_TREE_MODEL_COL_CUR_OVERFLOW,
+    GNC_BUDGET_TREE_MODEL_COL_EDITABLE,
+    GNC_BUDGET_TREE_MODEL_NUM_STATIC_COLUMNS
+} GncBudgetTreeModelColumns;
+
+
+/** Structure definitions */
+typedef struct GncBudgetTreeModelPrivate GncBudgetTreeModelPrivate;
+
+typedef struct{
+	GtkObject parent;
+
+	GncBudgetTreeModelPrivate *priv;
+
+	int stamp;
+} GncBudgetTreeModel;
+
+typedef struct {
+	GtkObjectClass parent;
+} GncBudgetTreeModelClass;
+
+
+
+/* Standard g_object type */
+GType gnc_budget_tree_model_get_type(void);
+
+/* Create a new GncBudgetTreeModel object. */
+GtkTreeModel* gnc_budget_tree_model_new(GncBudget* budget);
+
+GncBudgetCategory* gnc_budget_tree_model_get_category(GncBudgetTreeModel* model, GtkTreeIter* iter);
+
+G_END_DECLS
+#endif // __GNC_BUDGET_TREE_MODEL_H__
--- /dev/null
+++ src/gnome-utils/gnc-budget-list-tree-model.c
@@ -0,0 +1,572 @@
+/********************************************************************\
+ * gnc-budget-list-tree-model.c -- Implementation of the Budget List*
+ *                                 Tree model.                      *
+ * Copyright (C) 09 feb 2004    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup gnome-util
+ *     @{ */
+/** @file gnc-budget-list-tree-model.c
+ *  @breif Implementation of the Budget List Tree model.
+ *  @author Created by Darin Willits 09 feb 2004 
+ *  @author Copyright (c) 09 feb 2004 Darin Willits <darin at willits.ca>
+ *
+ */
+
+
+// Includes
+#include "config.h"
+#include <string.h>
+#include "gnc-trace.h"
+
+#include "gnc-budget-list-tree-model.h"
+#include "gnc-budget-book.h"
+#include "gnc-engine-util.h"
+#include "gnc-event.h"
+
+
+static short module = MOD_GUI;
+
+/** Initialize and clean-up functions. */
+static void gnc_budget_list_tree_model_class_init (GncBudgetListTreeModelClass *klass);
+static void gnc_budget_list_tree_model_init (GncBudgetListTreeModel *model);
+static void gnc_budget_list_tree_model_finalize (GObject *object);
+static void gnc_budget_list_tree_model_destroy (GtkObject *object);
+static void gnc_budget_list_tree_model_gtk_tree_model_init (GtkTreeModelIface *iface);
+
+/* GtkTreeModel Interface functions. */
+static guint gnc_budget_list_tree_model_get_flags (GtkTreeModel *tree_model);
+static int gnc_budget_list_tree_model_get_n_columns (GtkTreeModel *tree_model);
+static GType gnc_budget_list_tree_model_get_column_type (GtkTreeModel *tree_model,
+						     int index);
+static gboolean gnc_budget_list_tree_model_get_iter (GtkTreeModel *tree_model,
+						 GtkTreeIter *iter,
+						 GtkTreePath *path);
+static GtkTreePath *gnc_budget_list_tree_model_get_path (GtkTreeModel *tree_model,
+						     GtkTreeIter *iter);
+static void gnc_budget_list_tree_model_get_value (GtkTreeModel *tree_model,
+					      GtkTreeIter *iter,
+					      int column,
+					      GValue *value);
+static gboolean	gnc_budget_list_tree_model_iter_next (GtkTreeModel *tree_model,
+						  GtkTreeIter *iter);
+static gboolean	gnc_budget_list_tree_model_iter_children (GtkTreeModel *tree_model,
+						      GtkTreeIter *iter,
+						      GtkTreeIter *parent);
+static gboolean	gnc_budget_list_tree_model_iter_has_child (GtkTreeModel *tree_model,
+						       GtkTreeIter *iter);
+static int gnc_budget_list_tree_model_iter_n_children (GtkTreeModel *tree_model,
+						   GtkTreeIter *iter);
+static gboolean	gnc_budget_list_tree_model_iter_nth_child (GtkTreeModel *tree_model,
+						       GtkTreeIter *iter,
+						       GtkTreeIter *parent,
+						       int n);
+static gboolean	gnc_budget_list_tree_model_iter_parent (GtkTreeModel *tree_model,
+						        GtkTreeIter *iter,
+    						    GtkTreeIter *child);
+static gboolean gnc_budget_list_tree_model_get_iter_from_budget (GncBudgetListTreeModel *model,
+					      GncBudget *budget,
+					      GtkTreeIter *iter);
+
+static void gnc_budget_list_tree_model_event_handler (GUID *entity, QofIdType type,
+						  GNCEngineEventType event_type,
+						  gpointer user_data);
+
+/* Private internal data structure. */
+struct GncBudgetListTreeModelPrivate
+{
+    QofBook* book;
+    GList* budgets;
+	gint event_handler_id;
+};
+
+/************************************************************/
+/*               g_object required functions                */
+/************************************************************/
+
+static GtkObjectClass *parent_class = NULL;
+
+GType
+gnc_budget_list_tree_model_get_type (void)
+{
+	static GType gnc_budget_list_tree_model_type = 0;
+
+	if (gnc_budget_list_tree_model_type == 0) {
+		static const GTypeInfo our_info = {
+			sizeof (GncBudgetListTreeModelClass), /* class_size */
+			NULL,   			   /* base_init */
+			NULL,				   /* base_finalize */
+			(GClassInitFunc) gnc_budget_list_tree_model_class_init,
+			NULL,				   /* class_finalize */
+			NULL,				   /* class_data */
+			sizeof (GncBudgetListTreeModel),	   /* */
+			0,				   /* n_preallocs */
+			(GInstanceInitFunc) gnc_budget_list_tree_model_init
+		};
+		
+		static const GInterfaceInfo budget_list_tree_model_info = {
+			(GInterfaceInitFunc) gnc_budget_list_tree_model_gtk_tree_model_init,
+			NULL,
+			NULL
+		};
+
+		gnc_budget_list_tree_model_type = g_type_register_static (GTK_TYPE_OBJECT,
+								      "GncBudgetListTreeModel",
+								      &our_info, 0);
+        
+		g_type_add_interface_static (gnc_budget_list_tree_model_type,
+					     GTK_TYPE_TREE_MODEL,
+					     &budget_list_tree_model_info);
+	}
+    
+	return gnc_budget_list_tree_model_type;
+}
+
+static void
+gnc_budget_list_tree_model_class_init (GncBudgetListTreeModelClass *klass)
+{
+	GObjectClass *o_class;
+	GtkObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	o_class = G_OBJECT_CLASS (klass);
+	object_class = GTK_OBJECT_CLASS (klass);
+
+	/* GObject signals */
+	o_class->finalize = gnc_budget_list_tree_model_finalize;
+
+	/* GtkObject signals */
+	object_class->destroy = gnc_budget_list_tree_model_destroy;
+}
+
+static void
+gnc_budget_list_tree_model_init (GncBudgetListTreeModel *model)
+{
+	ENTER("model %p", model);
+	while (model->stamp == 0) {
+		model->stamp = g_random_int ();
+	}
+
+	model->priv = g_new0 (GncBudgetListTreeModelPrivate, 1);
+	model->priv->book = NULL;
+	LEAVE(" ");
+}
+
+static void
+gnc_budget_list_tree_model_finalize (GObject *object)
+{
+	GncBudgetListTreeModel *model;
+
+	ENTER("model %p", object);
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL (object));
+
+	model = GNC_BUDGET_LIST_TREE_MODEL(object);
+	g_free (model->priv);
+
+	if (G_OBJECT_CLASS (parent_class)->finalize)
+	  (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+	LEAVE(" ");
+}
+
+static void
+gnc_budget_list_tree_model_destroy (GtkObject *object)
+{
+	GncBudgetListTreeModel *model;
+
+	ENTER("model %p", object);
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(object));
+
+	model = GNC_BUDGET_LIST_TREE_MODEL(object);
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+	  (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+	LEAVE(" ");
+}
+
+/******************************************************
+ * GtkTreeModel Interface Methods.
+ *
+ * ****************************************************/
+
+static void gnc_budget_list_tree_model_gtk_tree_model_init(GtkTreeModelIface *iface)
+{
+	iface->get_flags       = gnc_budget_list_tree_model_get_flags;
+	iface->get_n_columns   = gnc_budget_list_tree_model_get_n_columns;
+	iface->get_column_type = gnc_budget_list_tree_model_get_column_type;
+	iface->get_iter        = gnc_budget_list_tree_model_get_iter;
+	iface->get_path        = gnc_budget_list_tree_model_get_path;
+	iface->get_value       = gnc_budget_list_tree_model_get_value;
+	iface->iter_next       = gnc_budget_list_tree_model_iter_next;
+	iface->iter_children   = gnc_budget_list_tree_model_iter_children;
+	iface->iter_has_child  = gnc_budget_list_tree_model_iter_has_child;
+	iface->iter_n_children = gnc_budget_list_tree_model_iter_n_children;
+	iface->iter_nth_child  = gnc_budget_list_tree_model_iter_nth_child;
+	iface->iter_parent     = gnc_budget_list_tree_model_iter_parent;
+}
+
+static guint gnc_budget_list_tree_model_get_flags (GtkTreeModel *tree_model)
+{
+    return 0;
+}
+
+static int gnc_budget_list_tree_model_get_n_columns (GtkTreeModel *tree_model)
+{
+    return GNC_BUDGET_LIST_TREE_MODEL_NUM_COLUMNS;
+}
+
+static GType gnc_budget_list_tree_model_get_column_type (GtkTreeModel *tree_model, int index)
+{
+ 	g_return_val_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(tree_model), G_TYPE_INVALID);
+    //g_return_val_if_fail ((index < GNC_BUDGET_TREE_MODEL_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
+
+    return G_TYPE_STRING;
+/*
+	switch (index) {
+        case GNC_BUDGET_TREE_MODEL_COL_NAME:
+		case GNC_BUDGET_TREE_MODEL_COL_VALUE:
+        case GNC_BUDGET_TREE_MODEL_COL_FREQ:
+			return G_TYPE_STRING;
+		default:
+			g_assert_not_reached ();
+			return G_TYPE_INVALID;
+	}
+*/
+}
+
+static gboolean gnc_budget_list_tree_model_get_iter (GtkTreeModel *tree_model, 
+                                                GtkTreeIter *iter,
+						                        GtkTreePath *path)
+{
+	GncBudgetListTreeModel *model = GNC_BUDGET_LIST_TREE_MODEL (tree_model);
+	guint i;
+
+	g_return_val_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(model), FALSE);
+	g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
+	
+	if (model->priv->budgets == NULL)
+		return FALSE;
+
+	i = gtk_tree_path_get_indices (path)[0];
+
+	g_return_val_if_fail (i >= 0 && i < g_list_length (model->priv->budgets), FALSE);
+
+	iter->stamp = model->stamp;
+	iter->user_data = g_list_nth(model->priv->budgets, i);
+
+	if (iter->user_data == NULL) {
+		iter->stamp = 0;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static GtkTreePath *gnc_budget_list_tree_model_get_path (GtkTreeModel *tree_model,
+                        						     GtkTreeIter *iter)
+{
+    GncBudgetListTreeModel *model = GNC_BUDGET_LIST_TREE_MODEL(tree_model);
+	GtkTreePath *path;
+
+	g_return_val_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(model), NULL);
+	g_return_val_if_fail (iter != NULL, NULL);
+	g_return_val_if_fail (iter->user_data != NULL, NULL);
+	g_return_val_if_fail (iter->stamp == model->stamp, NULL);
+	
+	if (model->priv->budgets== NULL)
+		return NULL;
+
+	path = gtk_tree_path_new ();
+
+	gtk_tree_path_append_index (path, g_list_position (model->priv->budgets, iter->user_data));
+
+	return path;
+
+}
+
+static void gnc_budget_list_tree_model_get_value (GtkTreeModel *tree_model,
+				                    	      GtkTreeIter *iter,
+                					          int column,
+					                          GValue *value)
+{
+	GncBudgetListTreeModel* model = GNC_BUDGET_LIST_TREE_MODEL(tree_model);
+    GncBudget* budget;
+	
+    g_return_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(model));
+	g_return_if_fail (iter != NULL);
+	g_return_if_fail (iter->user_data != NULL);
+	g_return_if_fail (iter->stamp == model->stamp);
+
+    budget = (GncBudget*)((GList*)iter->user_data)->data;
+    
+	switch (column) {
+		case GNC_BUDGET_LIST_TREE_MODEL_COL_NAME:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, gnc_budget_get_name(budget));
+			break;
+		case GNC_BUDGET_LIST_TREE_MODEL_COL_DESCRIPTION:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string(value, gnc_budget_get_description(budget));
+			break;
+		default:
+			g_assert_not_reached ();
+	}
+}
+
+static gboolean	gnc_budget_list_tree_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+ 	GncBudgetListTreeModel *model = GNC_BUDGET_LIST_TREE_MODEL(tree_model);
+
+	g_return_val_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(model), FALSE);
+	g_return_val_if_fail (iter != NULL, FALSE);
+	g_return_val_if_fail (iter->user_data != NULL, FALSE);
+	g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
+
+	if (g_list_next (iter->user_data) == NULL)
+		return FALSE;
+
+	iter->user_data = g_list_next(iter->user_data);
+
+	return TRUE;   
+}
+
+static gboolean	gnc_budget_list_tree_model_iter_children (GtkTreeModel *tree_model,
+                        						      GtkTreeIter *iter,
+						                              GtkTreeIter *parent)
+{
+ 	GncBudgetListTreeModel *model = GNC_BUDGET_LIST_TREE_MODEL(tree_model);
+    g_return_val_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(tree_model), FALSE);
+    g_return_val_if_fail (iter != NULL, FALSE);
+
+	if (parent != NULL){
+		return FALSE;
+    }
+    
+    iter->user_data = model->priv->budgets;
+    iter->stamp = model->stamp;
+        
+	return TRUE;   
+}
+
+static gboolean	gnc_budget_list_tree_model_iter_has_child (GtkTreeModel *tree_model,
+                        						       GtkTreeIter *iter)
+{
+	return FALSE;
+}
+
+static int gnc_budget_list_tree_model_iter_n_children (GtkTreeModel *tree_model,
+                        						   GtkTreeIter *iter)
+{
+	g_return_val_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(tree_model), FALSE);
+	
+    if (iter == NULL)
+		return g_list_length (GNC_BUDGET_LIST_TREE_MODEL(tree_model)->priv->budgets);
+
+    g_return_val_if_fail (GNC_BUDGET_LIST_TREE_MODEL(tree_model)->stamp == iter->stamp, -1);
+
+	return 0;
+}
+
+static gboolean	gnc_budget_list_tree_model_iter_nth_child (GtkTreeModel *tree_model,
+                        						        GtkTreeIter *iter,
+						                                GtkTreeIter *parent,
+						                                int n)
+{
+	GncBudgetListTreeModel *model;
+	
+	g_return_val_if_fail(GNC_IS_BUDGET_LIST_TREE_MODEL(tree_model), FALSE);
+    g_return_val_if_fail (iter != NULL, FALSE);
+
+	model = GNC_BUDGET_LIST_TREE_MODEL(tree_model);
+
+	if (parent != NULL){
+        return FALSE;
+    }
+    
+	g_return_val_if_fail (n >= 0 && n < (int)g_list_length (model->priv->budgets), FALSE);
+
+	iter->stamp = model->stamp;
+	iter->user_data = g_list_nth (model->priv->budgets, n);
+
+
+	if (iter->user_data == NULL) {
+		iter->stamp = 0;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean	gnc_budget_list_tree_model_iter_parent (GtkTreeModel *tree_model,
+                        						    GtkTreeIter *iter,
+    					                    	    GtkTreeIter *child)
+{
+    return FALSE;
+}
+
+/*
+ * Convert a model/account pair into a gtk_tree_model_iter.  This
+ * routine should only be called from the file
+ * gnc-tree-view-account.c.
+ */
+gboolean
+gnc_budget_list_tree_model_get_iter_from_budget (GncBudgetListTreeModel *model,
+					      GncBudget *budget,
+					      GtkTreeIter *iter)
+{
+    
+	ENTER("model %p, budget %p, iter %p", model, budget, iter);
+	g_return_val_if_fail (GNC_IS_BUDGET_LIST_TREE_MODEL(model), FALSE);
+	g_return_val_if_fail ((budget != NULL), FALSE);
+	g_return_val_if_fail ((iter != NULL), FALSE);
+    
+	if (model->priv->book != gnc_budget_get_book(budget)) {
+		LEAVE("Books don't match");
+		return FALSE;
+	}
+
+	iter->user_data = g_list_find(model->priv->budgets, budget);
+	iter->stamp = model->stamp;
+
+    return TRUE;
+}
+
+
+
+
+/*******************************************************
+ * Public Interface.
+ * 
+ * *****************************************************/
+
+GtkTreeModel* gnc_budget_list_tree_model_new(QofBook* book)
+{
+	GncBudgetListTreeModel *model;
+	
+	model = g_object_new (GNC_TYPE_BUDGET_LIST_TREE_MODEL, NULL);
+
+	model->priv->book = book;
+	model->priv->budgets = gnc_book_get_budgets(book);
+	
+    model->priv->event_handler_id =
+	  gnc_engine_register_event_handler (gnc_budget_list_tree_model_event_handler, model);
+	
+	return GTK_TREE_MODEL (model);
+}
+
+
+void gnc_budget_list_tree_model_event_handler (GUID *entity, QofIdType type,
+						  GNCEngineEventType event_type,
+						  gpointer user_data)
+{
+   	GncBudgetListTreeModel *model;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	GncBudget *budget;
+	const gchar *budget_name;
+
+	/* hard failures */
+	g_return_if_fail(GNC_IS_BUDGET_LIST_TREE_MODEL(user_data));
+
+	/* soft failures */
+	if (safe_strcmp(type, GNC_ID_BUDGET) != 0)
+	  return;
+
+	ENTER("entity %p of type %s, event %d, model %p",
+	      entity, type, event_type, user_data);
+	model = (GncBudgetListTreeModel*)user_data;
+
+	/* Get the account.*/
+	/* DRH - Put the book in the model private data so this code
+	 * supports multiple simultaneous books. */
+	budget = gnc_budget_lookup(entity, model->priv->book);
+    budget_name = gnc_budget_get_name(budget);
+    	
+    switch (event_type) {
+	 case GNC_EVENT_ADD:
+	  /* Tell the filters/views where the new account was added. */
+	  DEBUG("add budget %p (%s)", budget, budget_name);
+
+      /* We have to get the new list of budgets since it has now probably
+       * changed. */
+      model->priv->budgets = gnc_book_get_budgets(model->priv->book);
+      
+	  if (gnc_budget_list_tree_model_get_iter_from_budget (model, budget, &iter)) {
+	    path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
+	    gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter);
+	    //gnc_tree_model_account_path_changed (model, path);
+	    gtk_tree_path_free(path);
+	  }
+	  break;
+
+	 case GNC_EVENT_REMOVE:
+	  /* Record the path of this account for later use in destruction 
+	  DEBUG("remove account %p (%s)", account, account_name);
+	  path = gnc_tree_model_account_get_path_from_account (model, account);
+	  if (path == NULL) {
+	    LEAVE("account not in model");
+	    return;
+	  }
+
+	  data = malloc(sizeof(*data));
+	  data->guid = *entity;
+	  data->model = model;
+	  data->path = path;
+	  pending_removals = g_slist_append (pending_removals, data);
+	  LEAVE(" ");
+      */
+	  return;
+
+	 case GNC_EVENT_MODIFY:
+	  /*DEBUG("change account %p (%s)", account, account_name);
+	  path = gnc_tree_model_account_get_path_from_account (model, account);
+	  if (path == NULL) {
+	    LEAVE("account not in model");
+	    return;
+	  }
+	  if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path)) {
+	    gtk_tree_path_free(path);
+	    LEAVE("can't find iter for path");
+	    return;
+	  }
+	  gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
+	  gtk_tree_path_free(path);
+	  LEAVE(" ");*/
+	  return;
+
+	 case GNC_EVENT_DESTROY:
+	  /* Tell the filters/view the account has been deleted. */
+	  /*DEBUG("destroy account %p (%s)", account, account_name);
+	  g_slist_foreach (pending_removals,
+			   (GFunc)gnc_tree_model_account_delete_event_helper,
+			   entity);*/
+	  break;
+
+	 default:
+	  LEAVE("ignored event for %p (%s)", budget, budget_name);
+	  return;
+	}
+	LEAVE(" new stamp %u", model->stamp);
+    
+}
+
Index: Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome-utils/Makefile.am,v
retrieving revision 1.48.2.22
retrieving revision 1.48.2.23
diff -Lsrc/gnome-utils/Makefile.am -Lsrc/gnome-utils/Makefile.am -u -r1.48.2.22 -r1.48.2.23
--- src/gnome-utils/Makefile.am
+++ src/gnome-utils/Makefile.am
@@ -39,6 +39,8 @@
   druid-utils.c \
   gnc-account-sel.c \
   gnc-amount-edit.c \
+  gnc-budget-list-tree-model.c \
+  gnc-budget-tree-model.c \
   gnc-commodity-edit.c \
   gnc-currency-edit.c \
   gnc-date-delta.c \
@@ -90,6 +92,8 @@
   dialog-utils.h \
   druid-utils.h \
   gnc-account-sel.h \
+  gnc-budget-list-tree-model.h \
+  gnc-budget-tree-model.h \
   gnc-amount-edit.h \
   gnc-commodity-edit.h \
   gnc-currency-edit.h \
--- /dev/null
+++ src/gnome-utils/gnc-budget-list-tree-model.h
@@ -0,0 +1,87 @@
+/********************************************************************\
+ * gnc-budget-list-tree-model.h -- Tree Model for the internal list *
+ *                                 of budgets.                      *
+ * Copyright (C) 09 feb 2004    Darin Willits <darin at willits.ca>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+/** @addtogroup engine
+ *     @{ */
+/** @file gnc-budget-list-tree-model.h
+ *  @breif The tree model which represents the internal list of Budget
+ *  objects.
+ *  @author Created by Darin Willits 09 feb 2004 
+ *  @author Copyright (c) 09 feb 2004 Darin Willits <darin at willits.ca>
+ *
+ */
+
+
+#ifndef __GNC_BUDGET_LIST_TREE_MODEL_H__
+#define __GNC_BUDGET_LIST_TREE_MODEL_H__
+
+#include <gtk/gtktreemodel.h>
+#include "qofbook.h"
+
+G_BEGIN_DECLS
+
+/* type macros */
+#define GNC_TYPE_BUDGET_LIST_TREE_MODEL              (gnc_budget_list_tree_model_get_type ())
+#define GNC_BUDGET_LIST_TREE_MODEL(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_BUDGET_LIST_TREE_MODEL, GncBudgetListTreeModel))
+#define GNC_BUDGET_LIST_TREE_MODEL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_BUDGET_LIST_TREE_MODEL, GncBudgetListTreeModelClass))
+#define GNC_IS_BUDGET_LIST_TREE_MODEL(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_BUDGET_LIST_TREE_MODEL))
+#define GNC_IS_BUDGET_LIST_TREE_MODEL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_BUDGET_LIST_TREE_MODEL))
+#define GNC_BUDGET_LIST_TREE_MODEL_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_BUDGET_LIST_TREE_MODEL, GncBudgetListTreeModelClass))
+
+/** Column defintions */
+typedef enum{
+    GNC_BUDGET_LIST_TREE_MODEL_COL_NAME,
+    GNC_BUDGET_LIST_TREE_MODEL_COL_DESCRIPTION,
+    GNC_BUDGET_TREE_MODEL_COL_EDITABLE,
+    GNC_BUDGET_LIST_TREE_MODEL_NUM_COLUMNS,
+} GncBudgetListTreeModelColumns;
+
+
+/** Structure definitions */
+typedef struct GncBudgetListTreeModelPrivate GncBudgetListTreeModelPrivate;
+
+typedef struct{
+	GtkObject parent;
+
+	GncBudgetListTreeModelPrivate *priv;
+
+	int stamp;
+} GncBudgetListTreeModel;
+
+typedef struct {
+	GtkObjectClass parent;
+} GncBudgetListTreeModelClass;
+
+
+
+/* Standard g_object type */
+GType gnc_budget_list_tree_model_get_type(void);
+
+/* Create a new GncBudgetTreeModel object. */
+GtkTreeModel* gnc_budget_list_tree_model_new(QofBook* book);
+
+G_END_DECLS
+
+
+#endif // __GNC_BUDGET_LIST_TREE_MODEL_H__


More information about the gnucash-changes mailing list