r17378 - gnucash/branches/2.2 - [r17288, ...] Merge aqbanking3 changes into branch.

Andreas Köhler andi5 at cvs.gnucash.org
Tue Jul 22 18:32:29 EDT 2008


Author: andi5
Date: 2008-07-22 18:32:29 -0400 (Tue, 22 Jul 2008)
New Revision: 17378
Trac: http://svn.gnucash.org/trac/changeset/17378

Added:
   gnucash/branches/2.2/src/import-export/aqbanking/
   gnucash/branches/2.2/src/import-export/aqbanking/Makefile.am
   gnucash/branches/2.2/src/import-export/aqbanking/aqbanking.glade
   gnucash/branches/2.2/src/import-export/aqbanking/dialog-ab-trans.c
   gnucash/branches/2.2/src/import-export/aqbanking/dialog-ab-trans.h
   gnucash/branches/2.2/src/import-export/aqbanking/dialog-daterange.c
   gnucash/branches/2.2/src/import-export/aqbanking/dialog-daterange.h
   gnucash/branches/2.2/src/import-export/aqbanking/druid-ab-initial.c
   gnucash/branches/2.2/src/import-export/aqbanking/druid-ab-initial.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-getbalance.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-getbalance.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-gettrans.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-gettrans.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-kvp.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-kvp.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-trans-templ.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-trans-templ.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-transfer.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-transfer.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-utils.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-utils.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-file-aqb-import.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-file-aqb-import.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-gwen-gui.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-gwen-gui.h
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking-ui.xml
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking.c
   gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking.h
   gnucash/branches/2.2/src/import-export/aqbanking/gncmod-aqbanking.c
   gnucash/branches/2.2/src/import-export/aqbanking/schemas/
   gnucash/branches/2.2/src/import-export/aqbanking/schemas/Makefile.am
   gnucash/branches/2.2/src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in
Modified:
   gnucash/branches/2.2/configure.in
   gnucash/branches/2.2/doc/examples/downloaded.mt940
   gnucash/branches/2.2/macros/svn2cl.xsl
   gnucash/branches/2.2/po/POTFILES.in
   gnucash/branches/2.2/src/bin/gnucash-bin.c
   gnucash/branches/2.2/src/import-export/Makefile.am
   gnucash/branches/2.2/src/import-export/hbci/Makefile.am
Log:
[r17288,...] Merge aqbanking3 changes into branch.

[r17288] Merge branches/aqbanking3 (r17287) into trunk.

Port the HBCI import-export module to AqBanking3.  Depending on the aqbanking
version found, either the classic hbci/ module or the new, very similar, module
aqbanking3/ for AqBanking >= 3 is built and installed.  The influence on the
rest of the code is minimal.

[r17337] The gwenhywfar callback function showbox_cb() must not return 0.

Return the id reserved for it instead.

[r17338] Run some iterations of the main loop in showbox_cb to give the window a chance to be showed.

[r17346] Do not prepare the match page in the online banking wizard twice.

This would online_init() the api too often and lead to a crash.

[r17347] Bug #543049: Import all balances and txns in aqbanking contexts returned.

* All aqbanking imports use the same code
* An account number returned by the bank may differ from the one sent, so that
  the correct result is not found
* The bank may also send transaction data and delete that on its servers.  This
  may lead to severe data loss if we did not tried to import of what is returned
  as much as possible


Modified: gnucash/branches/2.2/configure.in
===================================================================
--- gnucash/branches/2.2/configure.in	2008-07-22 22:32:15 UTC (rev 17377)
+++ gnucash/branches/2.2/configure.in	2008-07-22 22:32:29 UTC (rev 17378)
@@ -832,38 +832,46 @@
 ### --------------------------------------------------------------------------
 ### MT940
 AC_ARG_ENABLE( mt940,
-  [  --enable-mt940               Obsolete, included in --enable-hbci],
+  [  --enable-mt940               obsolete, included in --enable-aqbanking],
   if test "x$enableval" != "xno" ; then
-    AC_MSG_ERROR([--enable-mt940 is obsolete -- all functionality is already included in --enable-hbci])
+    AC_MSG_ERROR([--enable-mt940 is obsolete -- all functionality is already included in --enable-aqbanking])
   fi)
 
 ### --------------------------------------------------------------------------
-### HBCI
+### AqBanking
+
+AC_ARG_ENABLE( aqbanking,
+  [  --enable-aqbanking           compile with AqBanking support],
+  if test "x$enableval" != "xno" ; then
+    want_aqbanking=yes
+  fi)
 AC_ARG_ENABLE( hbci,
-  [  --enable-hbci                compile with HBCI support (needs AqBanking)],
+  [  --enable-hbci                an alias for --enable-aqbanking],
   if test "x$enableval" != "xno" ; then
-    HBCI_DIR=hbci
+    want_aqbanking=yes
   fi)
-if test x${HBCI_DIR} = xhbci ;
+if test x${want_aqbanking} = xyes ;
 then
-    # Check for Aqbanking library
-    # aqbanking-1.6.1 was released on 2005-11-04; aqbanking ships with
-    # a pkg-config file since 1.6.1.
-    PKG_CHECK_MODULES(HBCI, aqbanking >= 1.6.1 aqbanking < 2.9.0 gwenhywfar, [], [
-      AC_MSG_ERROR([Could not find aqbanking > 1.6.0 and < 2.9.0. If you use --enable-hbci, you *have* to have aqbanking installed. Note that gnucash requires aqbanking2 and not (yet) aqbanking3!])
+  # Check for Aqbanking library
+  # aqbanking-1.6.1 was released on 2005-11-04; aqbanking ships with
+  # a pkg-config file since 1.6.1.
+  PKG_CHECK_MODULES(AQBANKING, aqbanking >= 3.0.0 gwenhywfar, [AQBANKING_DIR=aqbanking], [
+    PKG_CHECK_MODULES(AQBANKING, aqbanking >= 1.6.1 aqbanking < 2.9.0 gwenhywfar, [AQBANKING_DIR=hbci], [
+      AC_MSG_ERROR([Could not find aqbanking > 1.6.0. If you use --enable-aqbanking or --enable-hbci, you *have* to have aqbanking installed!])
     ])
+  ])
 
-    # also check for ktoblzcheck
-    AC_CHECK_HEADERS(ktoblzcheck.h)
-    if test "x$ac_cv_header_ktoblzcheck_h" != xno; then
-	HBCI_LIBS="${HBCI_LIBS} -lktoblzcheck"  
-    fi
+  # also check for ktoblzcheck
+  AC_CHECK_HEADERS(ktoblzcheck.h)
+  if test "x$ac_cv_header_ktoblzcheck_h" != xno; then
+    AQBANKING_LIBS="${AQBANKING_LIBS} -lktoblzcheck"
+  fi
 
-    AS_SCRUB_INCLUDE(HBCI_CFLAGS)
-    AC_SUBST(HBCI_LIBS)
-    AC_SUBST(HBCI_CFLAGS)
+  AS_SCRUB_INCLUDE(AQBANKING_CFLAGS)
+  AC_SUBST(AQBANKING_LIBS)
+  AC_SUBST(AQBANKING_CFLAGS)
 fi
-AC_SUBST(HBCI_DIR)
+AC_SUBST(AQBANKING_DIR)
 
 ### --------------------------------------------------------------------------
 ### i18n
@@ -1515,6 +1523,8 @@
           src/import-export/ofx/Makefile
           src/import-export/ofx/test/Makefile
           src/import-export/log-replay/Makefile
+          src/import-export/aqbanking/Makefile
+          src/import-export/aqbanking/schemas/Makefile
           src/import-export/hbci/Makefile
           src/import-export/hbci/glade/Makefile
           src/import-export/hbci/schemas/Makefile
@@ -1582,8 +1592,8 @@
 if test x${OFX_DIR} != x; then
 components="$components ofx"
 fi
-if test x${HBCI_DIR} != x; then
-components="$components hbci"
+if test x${AQBANKING_DIR} != x; then
+components="$components $AQBANKING_DIR"
 fi
 
 AC_MSG_RESULT([

Modified: gnucash/branches/2.2/doc/examples/downloaded.mt940
===================================================================
--- gnucash/branches/2.2/doc/examples/downloaded.mt940	2008-07-22 22:32:15 UTC (rev 17377)
+++ gnucash/branches/2.2/doc/examples/downloaded.mt940	2008-07-22 22:32:29 UTC (rev 17378)
@@ -1,4 +1,3 @@
-
 :20:STARTUMS  
 :25:80007777/2602272001
 :28C:0

Modified: gnucash/branches/2.2/macros/svn2cl.xsl
===================================================================
--- gnucash/branches/2.2/macros/svn2cl.xsl	2008-07-22 22:32:15 UTC (rev 17377)
+++ gnucash/branches/2.2/macros/svn2cl.xsl	2008-07-22 22:32:29 UTC (rev 17378)
@@ -106,6 +106,9 @@
    <before>16560</before>
   </branch>
   <branch>
+   <prefix>gnucash/branches/aqbanking3</prefix>
+  </branch>
+  <branch>
    <prefix>gnucash/branches/reshuffle-modules</prefix>
   </branch>
   <branch>

Modified: gnucash/branches/2.2/po/POTFILES.in
===================================================================
--- gnucash/branches/2.2/po/POTFILES.in	2008-07-22 22:32:15 UTC (rev 17377)
+++ gnucash/branches/2.2/po/POTFILES.in	2008-07-22 22:32:29 UTC (rev 17378)
@@ -337,6 +337,17 @@
 src/gnome-utils/search-param.c
 src/gnome-utils/window-main-summarybar.c
 src/gnome/window-reconcile.c
+src/import-export/aqbanking/aqbanking.glade
+src/import-export/aqbanking/dialog-ab-trans.c
+src/import-export/aqbanking/druid-ab-initial.c
+src/import-export/aqbanking/gnc-ab-getbalance.c
+src/import-export/aqbanking/gnc-ab-gettrans.c
+src/import-export/aqbanking/gnc-ab-transfer.c
+src/import-export/aqbanking/gnc-ab-utils.c
+src/import-export/aqbanking/gnc-file-aqb-import.c
+src/import-export/aqbanking/gnc-gwen-gui.c
+src/import-export/aqbanking/gnc-plugin-aqbanking.c
+src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in
 src/import-export/generic-import.glade
 src/import-export/gnc-import-desc-format.c
 src/import-export/gnc-import-format-cb.c

Modified: gnucash/branches/2.2/src/bin/gnucash-bin.c
===================================================================
--- gnucash/branches/2.2/src/bin/gnucash-bin.c	2008-07-22 22:32:15 UTC (rev 17377)
+++ gnucash/branches/2.2/src/bin/gnucash-bin.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -339,6 +339,7 @@
         { "gnucash/import-export/qif-import", 0, FALSE },
         { "gnucash/import-export/ofx", 0, TRUE },
         { "gnucash/import-export/log-replay", 0, TRUE },
+        { "gnucash/import-export/aqbanking", 0, TRUE },
         { "gnucash/import-export/hbci", 0, TRUE },
         { "gnucash/report/report-system", 0, FALSE },
         { "gnucash/report/stylesheets", 0, FALSE },

Modified: gnucash/branches/2.2/src/import-export/Makefile.am
===================================================================
--- gnucash/branches/2.2/src/import-export/Makefile.am	2008-07-22 22:32:15 UTC (rev 17377)
+++ gnucash/branches/2.2/src/import-export/Makefile.am	2008-07-22 22:32:29 UTC (rev 17378)
@@ -1,7 +1,7 @@
 SUBDIRS = . schemas qif qif-import \
-	${OFX_DIR} ${HBCI_DIR} log-replay test
+	${OFX_DIR} ${AQBANKING_DIR} log-replay test
 DIST_SUBDIRS = schemas qif qif-import qif-io-core \
-	ofx hbci log-replay test
+	ofx aqbanking hbci log-replay test
 
 pkglib_LTLIBRARIES=libgncmod-generic-import.la
 

Added: gnucash/branches/2.2/src/import-export/aqbanking/Makefile.am
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/Makefile.am	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/Makefile.am	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,78 @@
+SUBDIRS = . schemas
+
+pkglib_LTLIBRARIES = libgncmod-aqbanking.la
+
+libgncmod_aqbanking_la_SOURCES = \
+  dialog-ab-trans.c \
+  dialog-daterange.c \
+  druid-ab-initial.c \
+  gnc-ab-getbalance.c \
+  gnc-ab-gettrans.c \
+  gnc-ab-kvp.c \
+  gnc-ab-trans-templ.c \
+  gnc-ab-transfer.c \
+  gnc-ab-utils.c \
+  gnc-file-aqb-import.c \
+  gnc-gwen-gui.c \
+  gnc-plugin-aqbanking.c \
+  gncmod-aqbanking.c
+
+noinst_HEADERS = \
+  dialog-ab-trans.h \
+  dialog-daterange.h \
+  druid-ab-initial.h \
+  gnc-ab-getbalance.h \
+  gnc-ab-gettrans.h \
+  gnc-ab-kvp.h \
+  gnc-ab-trans-templ.h \
+  gnc-ab-transfer.h \
+  gnc-ab-utils.h \
+  gnc-file-aqb-import.h \
+  gnc-gwen-gui.h \
+  gnc-plugin-aqbanking.h
+
+libgncmod_aqbanking_la_LDFLAGS = -avoid-version
+
+libgncmod_aqbanking_la_LIBADD = \
+  ${top_builddir}/src/import-export/libgncmod-generic-import.la \
+  ${top_builddir}/src/gnome/libgnc-gnome.la \
+  ${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
+  ${top_builddir}/src/app-utils/libgncmod-app-utils.la \
+  ${top_builddir}/src/engine/libgncmod-engine.la \
+  ${top_builddir}/src/core-utils/libgnc-core-utils.la \
+  ${top_builddir}/src/gnc-module/libgnc-module.la \
+  ${GNOME_LIBS} \
+  ${GLADE_LIBS} \
+  ${QOF_LIBS} \
+  ${GLIB_LIBS} \
+  ${AQBANKING_LIBS}
+
+AM_CFLAGS = \
+  -I${top_srcdir}/src \
+  -I${top_srcdir}/src/import-export \
+  -I${top_srcdir}/src/gnome \
+  -I${top_srcdir}/src/register/ledger-core \
+  -I${top_srcdir}/src/register/register-gnome \
+  -I${top_srcdir}/src/register/register-core \
+  -I${top_srcdir}/src/gnome-utils \
+  -I${top_srcdir}/src/app-utils \
+  -I${top_srcdir}/src/engine \
+  -I${top_srcdir}/src/core-utils \
+  -I${top_srcdir}/src/gnc-module \
+  ${GNOME_CFLAGS} \
+  ${GLADE_CFLAGS} \
+  ${QOF_CFLAGS} \
+  ${GLIB_CFLAGS} \
+  ${AQBANKING_CFLAGS}
+
+uidir = $(GNC_UI_DIR)
+ui_DATA = \
+  gnc-plugin-aqbanking-ui.xml
+
+gladedir = $(GNC_GLADE_DIR)
+glade_DATA = \
+  aqbanking.glade
+
+EXTRA_DIST = ${ui_DATA} ${glade_DATA}
+
+INCLUDES = -DG_LOG_DOMAIN=\"gnc.import.aqbanking\"

Added: gnucash/branches/2.2/src/import-export/aqbanking/aqbanking.glade
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/aqbanking.glade	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/aqbanking.glade	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,2655 @@
+<?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="GtkWindow" id="AqBanking Init Druid">
+  <property name="title" translatable="yes">Initial Online Banking Setup</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">650</property>
+  <property name="default_height">580</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <signal name="key_press_event" handler="dai_key_press_event_cb" last_modification_time="Mon, 24 Mar 2008 03:19:32 GMT"/>
+  <signal name="destroy" handler="dai_destroy_cb" last_modification_time="Mon, 24 Mar 2008 03:20:48 GMT"/>
+
+  <child>
+    <widget class="GnomeDruid" id="ab_init_druid">
+      <property name="border_width">4</property>
+      <property name="visible">True</property>
+      <property name="show_help">False</property>
+      <signal name="cancel" handler="dai_cancel_cb" last_modification_time="Mon, 24 Mar 2008 03:19:42 GMT"/>
+
+      <child>
+	<widget class="GnomeDruidPageEdge" id="druidpagestart1">
+	  <property name="visible">True</property>
+	  <property name="position">GNOME_EDGE_START</property>
+	  <property name="title" translatable="yes">Initial Online Banking Setup</property>
+	  <property name="text" translatable="yes">This druid helps you setting up your Online Banking connection with your bank.
+
+You first need to apply for Online Banking access at your bank. If your bank  decides to grant you electronic access, they will send you a letter containing 
+
+* The bank code of your bank
+* The user ID that identifies you to your bank
+* The Internet address of your bank's Online Banking server
+* For HBCI Online Banking, information about the cryptographic public key of your bank (&quot;Ini-Letter&quot;).
+
+This information will be needed in the following. Press &quot;Forward&quot; now.
+
+NOTE: NO WARRANTIES FOR ANYTHING. Some banks run a poorly implemented Online Banking server. You should not rely on time-critical transfers through Online Banking, because sometimes the bank does not give you correct feedback when a transfer is rejected.
+
+Press &quot;Cancel&quot; if you do not wish to setup any Online Banking connection now.</property>
+	  <property name="title_color">#ffffffffffff</property>
+	  <property name="text_color">#000000000000</property>
+	  <property name="background_color">#9999bfbf9999</property>
+	  <property name="logo_background_color">#ffffffffffff</property>
+	  <property name="textbox_color">#ffffffffffff</property>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageStandard" id="wizard_page">
+	  <property name="visible">True</property>
+	  <property name="title" translatable="yes">Start Online Banking Wizard</property>
+	  <property name="title_foreground">#ffffffffffff</property>
+	  <property name="background">#9999bfbf9999</property>
+	  <property name="logo_background">#ffffffffffff</property>
+	  <signal name="prepare" handler="dai_wizard_page_prepare_cb" after="yes" last_modification_time="Mon, 24 Mar 2008 03:19:50 GMT"/>
+
+	  <child internal-child="vbox">
+	    <widget class="GtkVBox" id="vbox132">
+	      <property name="border_width">12</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">12</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877441">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">The Setup of your Online Banking connection is handled by the external program &quot;AqBanking Setup Wizard&quot;. Please press the button below to start this program.	</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">True</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment7">
+		  <property name="visible">True</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xscale">0</property>
+		  <property name="yscale">1</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">0</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkButton" id="ab_wizard_button">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label" translatable="yes">_Start AqBanking Wizard</property>
+		      <property name="use_underline">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		      <signal name="clicked" handler="dai_wizard_button_clicked_cb" last_modification_time="Mon, 24 Mar 2008 03:20:00 GMT"/>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageStandard" id="account_match_page">
+	  <property name="visible">True</property>
+	  <property name="title" translatable="yes">Match Online Banking accounts with GnuCash accounts</property>
+	  <property name="title_foreground">#ffffffffffff</property>
+	  <property name="background">#9999bfbf9999</property>
+	  <property name="logo_background">#ffffffffffff</property>
+	  <signal name="prepare" handler="dai_match_page_prepare_cb" after="yes" last_modification_time="Mon, 24 Mar 2008 03:20:08 GMT"/>
+
+	  <child internal-child="vbox">
+	    <widget class="GtkVBox" id="druid-vbox3">
+	      <property name="border_width">12</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox157">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">12</property>
+
+		  <child>
+		    <widget class="GtkScrolledWindow" id="scrolledwindow25">
+		      <property name="visible">True</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="shadow_type">GTK_SHADOW_IN</property>
+		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		      <child>
+			<widget class="GtkTreeView" id="account_page_view">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="headers_visible">True</property>
+			  <property name="rules_hint">True</property>
+			  <property name="reorderable">False</property>
+			  <property name="enable_search">True</property>
+			  <property name="fixed_height_mode">False</property>
+			  <property name="hover_selection">False</property>
+			  <property name="hover_expand">False</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="label828">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Click on the line of an Online Banking account name if you want to match it to a GnuCash account. Click &quot;Forward&quot; when all desired accounts are matching.</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">True</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>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">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="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+      </child>
+
+      <child>
+	<widget class="GnomeDruidPageEdge" id="initial_finish_page">
+	  <property name="visible">True</property>
+	  <property name="position">GNOME_EDGE_FINISH</property>
+	  <property name="title" translatable="yes">Online Banking Setup Finished</property>
+	  <property name="text" translatable="yes">The setup for matching Online Banking accounts to GnuCash accounts is now finished.  You can now invoke Online Banking actions on those accounts.
+
+If you want to add another bank, user, or account, you can start this druid again anytime.
+
+Press &quot;Apply&quot; now.</property>
+	  <property name="title_color">#ffffffffffff</property>
+	  <property name="text_color">#000000000000</property>
+	  <property name="background_color">#9999bfbf9999</property>
+	  <property name="logo_background_color">#ffffffffffff</property>
+	  <property name="textbox_color">#ffffffffffff</property>
+	  <signal name="finish" handler="dai_finish_cb" last_modification_time="Mon, 24 Mar 2008 03:20:18 GMT"/>
+	</widget>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkDialog" id="Transaction Dialog">
+  <property name="border_width">5</property>
+  <property name="title" translatable="yes">Online Transaction</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="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox2">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">2</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area2">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="exec_later_button">
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Execute later (unimpl.)</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-9</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="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="exec_now_button">
+	      <property name="visible">True</property>
+	      <property name="tooltip" translatable="yes">Execute this online transaction now</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-8</property>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment6">
+		  <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>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">0</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox122">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">2</property>
+
+		      <child>
+			<widget class="GtkImage" id="image4">
+			  <property name="visible">True</property>
+			  <property name="stock">gtk-execute</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="label8877454">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Execute Now</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>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">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>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox151">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="heading_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Enter an Online Transaction</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_CENTER</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>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHSeparator" id="hseparator7">
+	      <property name="visible">True</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkTable" id="table6">
+	      <property name="visible">True</property>
+	      <property name="n_rows">21</property>
+	      <property name="n_columns">3</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">0</property>
+	      <property name="column_spacing">0</property>
+
+	      <child>
+		<widget class="GtkEntry" id="recp_account_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">12</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="recp_account_heading">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Recipient Account Number</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">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="GtkEntry" id="recp_bankcode_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">8</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		  <signal name="changed" handler="dat_bankcode_changed_cb" last_modification_time="Tue, 03 Jun 2008 22:22:13 GMT"/>
+		</widget>
+		<packing>
+		  <property name="left_attach">2</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="recp_bankcode_heading">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Recipient Bank Code</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">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="recp_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">27</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="recp_name_heading">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Recipient Name</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_CENTER</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</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="recp_bankname_heading">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">at Bank</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">4</property>
+		  <property name="bottom_attach">5</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="recp_bankname_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">(filled in automatically)</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_CENTER</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">5</property>
+		  <property name="bottom_attach">6</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877434">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Amount</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_CENTER</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">7</property>
+		  <property name="bottom_attach">8</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877433">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Payment Purpose (only for recipient)</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_CENTER</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">10</property>
+		  <property name="bottom_attach">11</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877435">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Payment Purpose continued</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_CENTER</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">12</property>
+		  <property name="bottom_attach">13</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="orig_name_heading">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Originator 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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">15</property>
+		  <property name="bottom_attach">16</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="orig_name_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">something</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">16</property>
+		  <property name="bottom_attach">17</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="orig_bankname_heading">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">at Bank</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">17</property>
+		  <property name="bottom_attach">18</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="orig_bankname_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">something</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">18</property>
+		  <property name="bottom_attach">19</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="orig_account_heading">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Originator Account Number</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">2</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">15</property>
+		  <property name="bottom_attach">16</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="orig_account_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">something</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">2</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">16</property>
+		  <property name="bottom_attach">17</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="orig_bankcode_heading">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Bank Code</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">2</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">17</property>
+		  <property name="bottom_attach">18</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="orig_bankcode_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">something</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">2</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">18</property>
+		  <property name="bottom_attach">19</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox117">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">4</property>
+
+		  <child>
+		    <widget class="GtkVButtonBox" id="vbutonbox158">
+		      <property name="visible">True</property>
+		      <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkButton" id="add_templ_button">
+			  <property name="visible">True</property>
+			  <property name="tooltip" translatable="yes">Add the current online transaction as a new transaction template</property>
+			  <property name="can_focus">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <signal name="clicked" handler="dat_add_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:39:57 GMT"/>
+
+			  <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">0</property>
+			      <property name="yscale">0</property>
+			      <property name="top_padding">0</property>
+			      <property name="bottom_padding">0</property>
+			      <property name="left_padding">0</property>
+			      <property name="right_padding">0</property>
+
+			      <child>
+				<widget class="GtkHBox" id="hbox119">
+				  <property name="visible">True</property>
+				  <property name="homogeneous">False</property>
+				  <property name="spacing">2</property>
+
+				  <child>
+				    <widget class="GtkImage" id="image1">
+				      <property name="visible">True</property>
+				      <property name="stock">gtk-add</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="label8877451">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">Add current</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>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">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>
+
+		      <child>
+			<widget class="GtkButton" id="moveup_templ_button">
+			  <property name="visible">True</property>
+			  <property name="tooltip" translatable="yes">Move the selected transaction template one row up</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-go-up</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <signal name="clicked" handler="dat_moveup_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:32:42 GMT"/>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="movedown_templ_button">
+			  <property name="visible">True</property>
+			  <property name="tooltip" translatable="yes">Move the selected transaction template one row down</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-go-down</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <signal name="clicked" handler="dat_movedown_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:32:50 GMT"/>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="sort_templ_button">
+			  <property name="visible">True</property>
+			  <property name="tooltip" translatable="yes">Sort the list of transaction templates alphabetically</property>
+			  <property name="can_focus">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <signal name="clicked" handler="dat_sort_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:32:33 GMT"/>
+
+			  <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>
+			      <property name="top_padding">0</property>
+			      <property name="bottom_padding">0</property>
+			      <property name="left_padding">0</property>
+			      <property name="right_padding">0</property>
+
+			      <child>
+				<widget class="GtkHBox" id="hbox120">
+				  <property name="visible">True</property>
+				  <property name="homogeneous">False</property>
+				  <property name="spacing">2</property>
+
+				  <child>
+				    <widget class="GtkImage" id="image2">
+				      <property name="visible">True</property>
+				      <property name="stock">gtk-sort-ascending</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="label8877452">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">Sort</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>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">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>
+
+		      <child>
+			<widget class="GtkButton" id="del_templ_button">
+			  <property name="visible">True</property>
+			  <property name="tooltip" translatable="yes">Delete the currently selected transaction template</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>
+			  <property name="focus_on_click">True</property>
+			  <signal name="clicked" handler="dat_del_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:41:33 GMT"/>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		      <property name="pack_type">GTK_PACK_END</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkScrolledWindow" id="template_scrolledwindow">
+		      <property name="visible">True</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="shadow_type">GTK_SHADOW_IN</property>
+		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		      <child>
+			<widget class="GtkTreeView" id="template_list">
+			  <property name="visible">True</property>
+			  <property name="headers_visible">False</property>
+			  <property name="rules_hint">True</property>
+			  <property name="reorderable">False</property>
+			  <property name="enable_search">True</property>
+			  <property name="fixed_height_mode">False</property>
+			  <property name="hover_selection">False</property>
+			  <property name="hover_expand">False</property>
+			  <signal name="row_activated" handler="templ_list_row_activated_cb" last_modification_time="Wed, 04 Jun 2008 20:43:02 GMT"/>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		      <property name="pack_type">GTK_PACK_END</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label8877442">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Use Transaction Template</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_CENTER</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>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">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="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">20</property>
+		  <property name="bottom_attach">21</property>
+		  <property name="x_options">fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="purpose_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">27</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">11</property>
+		  <property name="bottom_attach">12</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="purpose_cont2_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">27</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">13</property>
+		  <property name="bottom_attach">14</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="purpose_cont_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">27</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">2</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">11</property>
+		  <property name="bottom_attach">12</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="purpose_cont3_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">27</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">2</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">13</property>
+		  <property name="bottom_attach">14</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="amount_hbox">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">8</property>
+		  <property name="bottom_attach">9</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHSeparator" id="hseparator8">
+		  <property name="visible">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">19</property>
+		  <property name="bottom_attach">20</property>
+		  <property name="y_padding">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHSeparator" id="hseparator4">
+		  <property name="visible">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">14</property>
+		  <property name="bottom_attach">15</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHSeparator" id="hseparator5">
+		  <property name="visible">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">6</property>
+		  <property name="bottom_attach">7</property>
+		  <property name="y_padding">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHSeparator" id="hseparator6">
+		  <property name="visible">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">9</property>
+		  <property name="bottom_attach">10</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></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>
+
+<widget class="GtkDialog" id="Connection Dialog">
+  <property name="border_width">5</property>
+  <property name="title" translatable="yes">Online Banking Connection Window</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">350</property>
+  <property name="default_height">420</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="has_separator">True</property>
+  <signal name="delete_event" handler="ggg_delete_event_cb" last_modification_time="Thu, 03 Apr 2008 23:38:57 GMT"/>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox3">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">2</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="abort_button">
+	      <property name="visible">True</property>
+	      <property name="sensitive">False</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="focus_on_click">True</property>
+	      <property name="response_id">0</property>
+	      <signal name="clicked" handler="ggg_abort_clicked_cb" last_modification_time="Sun, 30 Mar 2008 14:13:47 GMT"/>
+	    </widget>
+	  </child>
+
+	  <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="focus_on_click">True</property>
+	      <property name="response_id">0</property>
+	      <signal name="clicked" handler="ggg_close_clicked_cb" last_modification_time="Sun, 30 Mar 2008 14:14:09 GMT"/>
+	    </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="vbox149">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">18</property>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox160">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877443">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Progress&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <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">1</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">12</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkTable" id="entries_table">
+		      <property name="visible">True</property>
+		      <property name="n_rows">3</property>
+		      <property name="n_columns">2</property>
+		      <property name="homogeneous">False</property>
+		      <property name="row_spacing">6</property>
+		      <property name="column_spacing">12</property>
+
+		      <child>
+			<widget class="GtkLabel" id="label8877424">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Current Job</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_CENTER</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>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">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="GtkEntry" id="top_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">*</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="GtkProgressBar" id="top_progress">
+			  <property name="visible">True</property>
+			  <property name="sensitive">False</property>
+			  <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+			  <property name="fraction">0</property>
+			  <property name="pulse_step">0.10000000149</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</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="label8877426">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Progress</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_CENTER</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>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">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="label8877425">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Current Action</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_CENTER</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>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">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="GtkEntry" id="second_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">*</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">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="y_options"></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>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox162">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877444">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Log Messages&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment1">
+		  <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">1</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">12</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkScrolledWindow" id="scrolledwindow30">
+		      <property name="visible">True</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="shadow_type">GTK_SHADOW_IN</property>
+		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		      <child>
+			<widget class="GtkTextView" id="log_text">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">False</property>
+			  <property name="overwrite">False</property>
+			  <property name="accepts_tab">True</property>
+			  <property name="justification">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap_mode">GTK_WRAP_WORD</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>
+		  </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="GtkCheckButton" id="close_checkbutton">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Close when finished</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">True</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>
+	</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="Date Range Dialog">
+  <property name="border_width">5</property>
+  <property name="title" translatable="yes">Get Transactions Online</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="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</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">2</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="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="focus_on_click">True</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="focus_on_click">True</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="vbox152">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">18</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="heading_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Date range of transactions to retrieve:</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_CENTER</property>
+	      <property name="wrap">True</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>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox163">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877445">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;From&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment9">
+		  <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">1</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">12</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkVBox" id="vbox164">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">6</property>
+
+		      <child>
+			<widget class="GtkRadioButton" id="first_button">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">_Earliest possible date</property>
+			  <property name="use_underline">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</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="last_retrieval_button">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">_Last retrieval date</property>
+			  <property name="use_underline">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <property name="active">True</property>
+			  <property name="inconsistent">False</property>
+			  <property name="draw_indicator">True</property>
+			  <property name="group">first_button</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="hbox123">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">12</property>
+
+			  <child>
+			    <widget class="GtkRadioButton" id="enter_from_button">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label" translatable="yes">E_nter date:</property>
+			      <property name="use_underline">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
+			      <property name="active">False</property>
+			      <property name="inconsistent">False</property>
+			      <property name="draw_indicator">True</property>
+			      <property name="group">first_button</property>
+			      <signal name="toggled" handler="ddr_toggled_cb" last_modification_time="Sun, 30 Mar 2008 01:56:58 GMT"/>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkHBox" id="enter_from_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">False</property>
+			  <property name="fill">False</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>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox165">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877446">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;To&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment10">
+		  <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">1</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">12</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkVBox" id="vbox166">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">6</property>
+
+		      <child>
+			<widget class="GtkRadioButton" id="now_button">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">_Now</property>
+			  <property name="use_underline">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <property name="active">True</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="GtkHBox" id="hbox124">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">12</property>
+
+			  <child>
+			    <widget class="GtkRadioButton" id="enter_to_button">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label" translatable="yes">Ente_r date:</property>
+			      <property name="use_underline">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
+			      <property name="active">False</property>
+			      <property name="inconsistent">False</property>
+			      <property name="draw_indicator">True</property>
+			      <property name="group">now_button</property>
+			      <signal name="toggled" handler="ddr_toggled_cb" last_modification_time="Sun, 30 Mar 2008 01:56:46 GMT"/>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkHBox" id="enter_to_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>
+		</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>
+	</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="Template Name Dialog">
+  <property name="border_width">5</property>
+  <property name="title" translatable="yes">Name for new template</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="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox6">
+      <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_area6">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelbutton1">
+	      <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="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okbutton1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_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="focus_on_click">True</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="vbox159">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">12</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label8877450">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Enter name for new template:</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>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkEntry" id="template_name">
+	      <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">250</property>
+	      <property name="text" translatable="yes"></property>
+	      <property name="has_frame">True</property>
+	      <property name="invisible_char">*</property>
+	      <property name="activates_default">True</property>
+	    </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>
+
+<widget class="GtkDialog" id="Password Dialog">
+  <property name="border_width">5</property>
+  <property name="title" translatable="yes">Enter Password</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="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox7">
+      <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_area7">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelbutton2">
+	      <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="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okbutton2">
+	      <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="focus_on_click">True</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="vbox167">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">18</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="heading_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Enter your password</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</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>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkTable" id="table7">
+	      <property name="visible">True</property>
+	      <property name="n_rows">3</property>
+	      <property name="n_columns">2</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">6</property>
+	      <property name="column_spacing">12</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label8877456">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Password:</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">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="confirm_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Confirm Password:</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>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">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="input_entry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">False</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">●</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="GtkEntry" id="confirm_entry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">False</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">●</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">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkCheckButton" id="remember_pin">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label" translatable="yes">Remember _PIN</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">2</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>
+	    </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>
+
+<widget class="GtkWindow" id="Preferences">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">window1</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="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+
+  <child>
+    <widget class="GtkTable" id="aqbanking_prefs">
+      <property name="visible">True</property>
+      <property name="n_rows">3</property>
+      <property name="n_columns">4</property>
+      <property name="homogeneous">False</property>
+      <property name="row_spacing">0</property>
+      <property name="column_spacing">0</property>
+
+      <child>
+	<widget class="GtkLabel" id="label8877457">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">&lt;b&gt;Online Banking&lt;/b&gt;</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">True</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>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">4</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="GtkCheckButton" id="gconf/dialogs/import/hbci/remember_pin">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="label" translatable="yes">Remember _PIN</property>
+	  <property name="use_underline">True</property>
+	  <property name="relief">GTK_RELIEF_NORMAL</property>
+	  <property name="focus_on_click">True</property>
+	  <property name="active">False</property>
+	  <property name="inconsistent">False</property>
+	  <property name="draw_indicator">True</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">4</property>
+	  <property name="top_attach">1</property>
+	  <property name="bottom_attach">2</property>
+	  <property name="x_padding">12</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkCheckButton" id="checkbutton3">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="label" translatable="yes">_Verbose debug messages</property>
+	  <property name="use_underline">True</property>
+	  <property name="relief">GTK_RELIEF_NORMAL</property>
+	  <property name="focus_on_click">True</property>
+	  <property name="active">False</property>
+	  <property name="inconsistent">False</property>
+	  <property name="draw_indicator">True</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">4</property>
+	  <property name="top_attach">2</property>
+	  <property name="bottom_attach">3</property>
+	  <property name="x_padding">12</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>

Added: gnucash/branches/2.2/src/import-export/aqbanking/dialog-ab-trans.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/dialog-ab-trans.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/dialog-ab-trans.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,1000 @@
+/*
+ * dialog-ab-trans.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file dialog-ab-trans.c
+ * @brief Templates for AqBanking transactions
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2004 Bernd Wagner
+ * @author Copyright (C) 2006 David Hampton <hampton at employees.org>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#if HAVE_KTOBLZCHECK_H
+#    include <ktoblzcheck.h>
+#endif
+#include <aqbanking/jobsingletransfer.h>
+#include <aqbanking/jobsingledebitnote.h>
+#include <aqbanking/jobinternaltransfer.h>
+
+#include "dialog-ab-trans.h"
+#include "dialog-transfer.h"
+#include "dialog-utils.h"
+#include "gnc-ab-trans-templ.h"
+#include "gnc-ab-utils.h"
+#include "gnc-amount-edit.h"
+#include "gnc-ui.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+static void fill_templ_helper(gpointer data, gpointer user_data);
+static AB_TRANSACTION *ab_trans_fill_values(GncABTransDialog *td);
+static gboolean check_ktoblzcheck(GtkWidget *parent, const GncABTransDialog *td,
+                                  const AB_TRANSACTION *trans);
+static gboolean clear_templ_helper(GtkTreeModel *model, GtkTreePath *path,
+                                   GtkTreeIter *iter, gpointer user_data);
+static gboolean get_templ_helper(GtkTreeModel *model, GtkTreePath *path,
+                                 GtkTreeIter *iter, gpointer data);
+static AB_JOB *get_available_empty_job(AB_ACCOUNT *ab_acc,
+                                       GncABTransType trans_type);
+
+void dat_bankcode_changed_cb(GtkEditable *editable, gpointer user_data);
+void templ_list_row_activated_cb(GtkTreeView *view, GtkTreePath *path,
+                                 GtkTreeViewColumn *column, gpointer user_data);
+static gboolean find_templ_helper(GtkTreeModel *model, GtkTreePath *path,
+                                  GtkTreeIter *iter, gpointer user_data);
+void dat_add_templ_cb(GtkButton *button, gpointer user_data);
+void dat_moveup_templ_cb(GtkButton *button, gpointer user_data);
+void dat_movedown_templ_cb(GtkButton *button, gpointer user_data);
+void dat_sort_templ_cb(GtkButton *button, gpointer user_data);
+void dat_del_templ_cb(GtkButton *button, gpointer user_data);
+
+enum {
+    TEMPLATE_NAME,
+    TEMPLATE_POINTER,
+    TEMPLATE_NUM_COLUMNS
+};
+
+struct _GncABTransDialog {
+    /* The dialog itself */
+    GtkWidget *dialog;
+    GtkWidget *parent;
+    AB_ACCOUNT *ab_acc;
+
+    /* Whether this is a transfer or a direct debit */
+    GncABTransType trans_type;
+
+    /* Recipient */
+    GtkWidget *recp_name_entry;
+    GtkWidget *recp_account_entry;
+    GtkWidget *recp_bankcode_entry;
+
+    /* Amount */
+    GtkWidget *amount_edit;
+
+    /* Purpose, description */
+    GtkWidget *purpose_entry;
+    GtkWidget *purpose_cont_entry;
+    GtkWidget *purpose_cont2_entry;
+    GtkWidget *purpose_cont3_entry;
+
+    /* Recipient's bank name (may be filled in automatically sometime later) */
+    GtkWidget *recp_bankname_label;
+
+    /* The template choosing GtkTreeView/GtkListStore */
+    GtkTreeView *template_gtktreeview;
+    GtkListStore *template_list_store;
+
+    /* Flag, if template list has been changed */
+    gboolean templ_changed;
+
+    /* The aqbanking transaction that got created here */
+    AB_TRANSACTION *ab_trans;
+
+    /* The gnucash transaction that got created here */
+    Transaction *gnc_trans;
+
+#if HAVE_KTOBLZCHECK_H
+    /* object for Account number checking */
+    AccountNumberCheck *blzcheck;
+#endif
+};
+
+static void
+fill_templ_helper(gpointer data, gpointer user_data)
+{
+    GncABTransTempl *templ = data;
+    GtkListStore *store = user_data;
+    GtkTreeIter iter;
+
+    g_return_if_fail(templ && store);
+    gtk_list_store_append(store, &iter);
+    gtk_list_store_set(store, &iter,
+                       TEMPLATE_NAME, gnc_ab_trans_templ_get_name(templ),
+                       TEMPLATE_POINTER, templ,
+                       -1);
+}
+
+/**
+ * Create a new AB_TRANSACTION, fill the values from the entry fields into it
+ * and return it.  The caller must AB_TRANSACTION_free() it when finished.
+ */
+static AB_TRANSACTION *
+ab_trans_fill_values(GncABTransDialog *td)
+{
+    /* Fill in the user-entered values */
+    AB_TRANSACTION *trans = AB_Transaction_new();
+    AB_VALUE *value;
+
+    AB_Transaction_SetLocalBankCode(trans, AB_Account_GetBankCode(td->ab_acc));
+    AB_Transaction_SetLocalAccountNumber(
+        trans, AB_Account_GetAccountNumber(td->ab_acc));
+    AB_Transaction_SetLocalCountry(trans, "DE");
+
+    AB_Transaction_SetRemoteBankCode(
+        trans, gtk_entry_get_text(GTK_ENTRY(td->recp_bankcode_entry)));
+    AB_Transaction_SetRemoteAccountNumber(
+        trans, gtk_entry_get_text(GTK_ENTRY(td->recp_account_entry)));
+    AB_Transaction_SetRemoteCountry(trans, "DE");
+    AB_Transaction_AddRemoteName(
+        trans, gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)), FALSE);
+
+    AB_Transaction_AddPurpose(
+        trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_entry)), FALSE);
+    AB_Transaction_AddPurpose(
+        trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_cont_entry)), FALSE);
+    AB_Transaction_AddPurpose(
+        trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_cont2_entry)), FALSE);
+    AB_Transaction_AddPurpose(
+        trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_cont3_entry)), FALSE);
+
+    value = AB_Value_fromDouble(gnc_amount_edit_get_damount(
+                                    GNC_AMOUNT_EDIT(td->amount_edit)));
+    /* FIXME: Replace "EUR" by account-dependent string here. */
+    AB_Value_SetCurrency(value, "EUR");
+    AB_Transaction_SetValue(trans, value);
+    AB_Value_free(value);
+
+    /* If this is a direct debit, a textkey/ "Textschluessel"/transactionCode
+     * different from the default has to be set. */
+    switch (td->trans_type) {
+    case SINGLE_DEBITNOTE:
+        /* AB_Transaction_SetTransactionCode (trans, 05); */
+        AB_Transaction_SetTextKey(trans, 05);
+        break;
+    default:
+        /* AB_Transaction_SetTransactionCode (trans, 51); */
+        AB_Transaction_SetTextKey (trans, 51);
+    }
+
+    return trans;
+}
+
+GncABTransDialog *
+gnc_ab_trans_dialog_new(GtkWidget *parent, AB_ACCOUNT *ab_acc,
+                        gint commodity_scu, GncABTransType trans_type,
+                        GList *templates)
+{
+    GncABTransDialog *td;
+    GladeXML *xml;
+    const gchar *ab_ownername;
+    const gchar *ab_accountnumber;
+    const gchar *ab_bankname;
+    const gchar *ab_bankcode;
+    GtkWidget *heading_label;
+    GtkWidget *recp_name_heading;
+    GtkWidget *recp_account_heading;
+    GtkWidget *recp_bankcode_heading;
+    GtkWidget *amount_hbox;
+    GtkWidget *orig_name_heading;
+    GtkWidget *orig_name_label;
+    GtkWidget *orig_account_heading;
+    GtkWidget *orig_account_label;
+    GtkWidget *orig_bankname_heading;
+    GtkWidget *orig_bankname_label;
+    GtkWidget *orig_bankcode_heading;
+    GtkWidget *orig_bankcode_label;
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+
+    g_return_val_if_fail(ab_acc, NULL);
+
+    ab_ownername = AB_Account_GetOwnerName(ab_acc);
+    if (!ab_ownername)
+        ab_ownername = "";
+    ab_accountnumber = AB_Account_GetAccountNumber(ab_acc);
+    ab_bankcode = AB_Account_GetBankCode(ab_acc);
+    ab_bankname = AB_Account_GetBankName(ab_acc);
+    if (!ab_bankname || !*ab_bankname)
+        ab_bankname = _("(unknown)");
+
+    td = g_new0(GncABTransDialog, 1);
+    td->parent = parent;
+    td->ab_acc = ab_acc;
+    td->trans_type = trans_type;
+
+#if HAVE_KTOBLZCHECK_H
+    td->blzcheck = AccountNumberCheck_new();
+#endif
+
+    xml = gnc_glade_xml_new("aqbanking.glade", "Transaction Dialog");
+    td->dialog = glade_xml_get_widget(xml, "Transaction Dialog");
+    g_object_set_data_full(G_OBJECT(td->dialog), "xml", xml, g_object_unref);
+    glade_xml_signal_autoconnect_full(xml, gnc_glade_autoconnect_full_func, td);
+
+    if (parent)
+        gtk_window_set_transient_for(GTK_WINDOW(td->dialog), GTK_WINDOW(parent));
+
+    /* Extract widgets */
+    heading_label = glade_xml_get_widget(xml, "heading_label");
+    recp_name_heading = glade_xml_get_widget(xml, "recp_name_heading");
+    td->recp_name_entry = glade_xml_get_widget(xml, "recp_name_entry");
+    recp_account_heading = glade_xml_get_widget(xml, "recp_account_heading");
+    td->recp_account_entry = glade_xml_get_widget(xml, "recp_account_entry");
+    recp_bankcode_heading = glade_xml_get_widget(xml, "recp_bankcode_heading");
+    td->recp_bankcode_entry = glade_xml_get_widget(xml, "recp_bankcode_entry");
+    td->recp_bankname_label = glade_xml_get_widget(xml, "recp_bankname_label");
+    amount_hbox = glade_xml_get_widget(xml, "amount_hbox");
+    td->purpose_entry = glade_xml_get_widget(xml, "purpose_entry");
+    td->purpose_cont_entry = glade_xml_get_widget(xml, "purpose_cont_entry");
+    td->purpose_cont2_entry = glade_xml_get_widget(xml, "purpose_cont2_entry");
+    td->purpose_cont3_entry = glade_xml_get_widget(xml, "purpose_cont3_entry");
+    orig_name_heading = glade_xml_get_widget(xml, "orig_name_heading");
+    orig_name_label = glade_xml_get_widget(xml, "orig_name_label");
+    orig_account_heading = glade_xml_get_widget(xml, "orig_account_heading");
+    orig_account_label = glade_xml_get_widget(xml, "orig_account_label");
+    orig_bankname_heading = glade_xml_get_widget(xml, "orig_bankname_heading");
+    orig_bankname_label = glade_xml_get_widget(xml, "orig_bankname_label");
+    orig_bankcode_heading = glade_xml_get_widget(xml, "orig_bankcode_heading");
+    orig_bankcode_label = glade_xml_get_widget(xml, "orig_bankcode_label");
+    td->template_gtktreeview =
+        GTK_TREE_VIEW(glade_xml_get_widget(xml, "template_list"));
+
+    /* Amount edit */
+    td->amount_edit = gnc_amount_edit_new();
+    gtk_box_pack_start_defaults(GTK_BOX(amount_hbox), td->amount_edit);
+    gnc_amount_edit_set_evaluate_on_enter(GNC_AMOUNT_EDIT(td->amount_edit),
+                                          TRUE);
+    gnc_amount_edit_set_fraction(GNC_AMOUNT_EDIT(td->amount_edit),
+                                 commodity_scu);
+
+    /* Check for what kind of transaction this should be, and change the
+     * labels accordingly */
+    switch (trans_type) {
+    case SINGLE_TRANSFER:
+    case SINGLE_INTERNAL_TRANSFER:
+        /* all labels are already set */
+        break;
+    case SINGLE_DEBITNOTE:
+        gtk_label_set_text(GTK_LABEL (heading_label),
+                           /* Translators: Strings from this file are
+                             * needed only in countries that have one of
+                             * aqbanking's Online Banking techniques
+                             * available. This is 'OFX DirectConnect'
+                             * (U.S. and others), 'HBCI' (in Germany),
+                             * or 'YellowNet' (Switzerland). If none of
+                             * these techniques are available in your
+                             * country, you may safely ignore strings
+                             * from the import-export/hbci
+                             * subdirectory. */
+                            _("Enter an Online Direct Debit Note"));
+
+        gtk_label_set_text(GTK_LABEL(recp_name_heading),
+                           _("Debited Account Owner"));
+        gtk_label_set_text(GTK_LABEL(recp_account_heading),
+                           _("Debited Account Number"));
+        gtk_label_set_text(GTK_LABEL(recp_bankcode_heading),
+                           _("Debited Account Bank Code"));
+
+        gtk_label_set_text(GTK_LABEL(orig_name_heading),
+                           _("Credited Account Owner"));
+        gtk_label_set_text(GTK_LABEL(orig_account_heading),
+                           _("Credited Account Number"));
+        gtk_label_set_text(GTK_LABEL(orig_bankcode_heading),
+                           _("Credited Account Bank Code"));
+        break;
+
+    default:
+        g_critical("gnc_ab_trans_dialog_new: Oops, unknown GncABTransType %d",
+                   trans_type);
+    }
+
+    gtk_label_set_text(GTK_LABEL(orig_name_label), ab_ownername);
+    gtk_label_set_text(GTK_LABEL(orig_account_label), ab_accountnumber);
+    gtk_label_set_text(GTK_LABEL(orig_bankname_label), ab_bankname);
+    gtk_label_set_text (GTK_LABEL (orig_bankcode_label), ab_bankcode);
+
+    /* Fill list for choosing a transaction template */
+    td->template_list_store = gtk_list_store_new(TEMPLATE_NUM_COLUMNS,
+                                                 G_TYPE_STRING, G_TYPE_POINTER);
+    g_list_foreach(templates, fill_templ_helper, td->template_list_store);
+    gtk_tree_view_set_model(td->template_gtktreeview,
+                            GTK_TREE_MODEL(td->template_list_store));
+    td->templ_changed = FALSE;
+    /* Keep a reference to the store */
+
+    /* Show this list */
+    renderer = gtk_cell_renderer_text_new();
+    column = gtk_tree_view_column_new_with_attributes(
+        "Template Name", renderer, "text", TEMPLATE_NAME, NULL);
+    gtk_tree_view_append_column(td->template_gtktreeview, column);
+
+    return td;
+}
+
+static gboolean
+check_ktoblzcheck(GtkWidget *parent, const GncABTransDialog *td,
+                  const AB_TRANSACTION *trans)
+{
+#ifndef HAVE_KTOBLZCHECK_H
+    return TRUE;
+#else
+    gint blzresult;
+    const char *blztext;
+    gboolean values_ok = TRUE;
+
+    ENTER(" ");
+
+    blzresult = AccountNumberCheck_check(
+        td->blzcheck,
+        AB_Transaction_GetRemoteBankCode(trans),
+        AB_Transaction_GetRemoteAccountNumber(trans));
+    switch (blzresult) {
+    case 2:
+        gtk_widget_show(parent);
+        values_ok = gnc_verify_dialog(
+            parent, TRUE,
+            _("The internal check of the destination account number '%s' "
+              "at the specified bank with bank code '%s' failed. This means "
+              "the account number might contain an error. Should the online "
+              "transfer job be sent with this account number anyway?"),
+            AB_Transaction_GetRemoteAccountNumber(trans),
+            AB_Transaction_GetRemoteBankCode(trans));
+        blztext = "Kontonummer wahrscheinlich falsch";
+        break;
+    case 0:
+        blztext = "Kontonummer ok";
+        break;
+    case 3:
+        blztext = "bank unbekannt";
+        break;
+    case 1:
+    default:
+        blztext = "unbekannt aus unbekanntem grund";
+        break;
+    }
+
+    LEAVE("KtoBlzCheck said check is %d = %s",
+          blzresult, blztext ? blztext : "(none)");
+
+    return values_ok;
+#endif
+}
+
+gint
+gnc_ab_trans_dialog_run_until_ok(GncABTransDialog *td)
+{
+    gint result;
+    AB_JOB *job;
+    const AB_TRANSACTION_LIMITS *joblimits;
+    guint8 max_purpose_lines;
+    gboolean values_ok;
+    gchar *purpose;
+    gchar *othername;
+
+    /* Check whether the account supports this job */
+    job = get_available_empty_job(td->ab_acc, td->trans_type);
+    if (!job) {
+        g_warning("gnc_ab_trans_dialog_run_until_ok: Oops, job not available");
+        return GTK_RESPONSE_CANCEL;
+    }
+
+    /* Activate as many purpose entries as available for the job */
+    joblimits = AB_JobSingleTransfer_GetFieldLimits(job);
+    max_purpose_lines = joblimits ?
+        AB_TransactionLimits_GetMaxLinesPurpose(joblimits) : 2;
+    gtk_widget_set_sensitive(td->purpose_cont_entry, max_purpose_lines > 1);
+    gtk_widget_set_sensitive(td->purpose_cont2_entry, max_purpose_lines > 2);
+    gtk_widget_set_sensitive(td->purpose_cont3_entry, max_purpose_lines > 3);
+
+    /* Show the dialog */
+    gtk_widget_show(td->dialog);
+
+    /* Repeat until entered values make sense */
+    do {
+        /* Now run the dialog until it gets closed by a button press */
+        result = gtk_dialog_run (GTK_DIALOG (td->dialog));
+
+        /* Was cancel pressed or dialog closed?
+         *  GNC_RESPONSE_NOW == execute now
+         *  GNC_RESPONSE_LATER == scheduled for later execution (unimplemented)
+         *  GTK_RESPONSE_CANCEL == cancel
+         *  GTK_RESPONSE_DELETE_EVENT == window destroyed */
+        if (result != GNC_RESPONSE_NOW && result != GNC_RESPONSE_LATER) {
+            gtk_widget_destroy(td->dialog);
+            td->dialog = NULL;
+            break;
+        }
+
+        /* Now fill in the values from the entry fields into a new
+         * AB_TRANSACTION */
+        td->ab_trans = ab_trans_fill_values(td);
+        values_ok = TRUE;
+
+        /* Check transaction value */
+        values_ok =
+            AB_Value_GetValueAsDouble(AB_Transaction_GetValue(td->ab_trans))
+            != 0.0;
+        if (!values_ok) {
+            gtk_widget_show(td->dialog);
+            if (gnc_verify_dialog(
+                    td->dialog, TRUE, "%s",
+                    _("The amount is zero or the amount field could not be "
+                      "interpreted correctly. You might have mixed up decimal "
+                      "point and comma, compared to your locale settings. "
+                      "This does not result in a valid online transfer job. \n"
+                      "\n"
+                      "Do you want to enter the job again?"))) {
+                continue;
+            } else {
+                AB_Transaction_free(td->ab_trans);
+                td->ab_trans = NULL;
+                result = GTK_RESPONSE_CANCEL;
+                break;
+            }
+        }
+
+        /* Check transaction purpose */
+        purpose = gnc_ab_get_purpose(td->ab_trans);
+        values_ok = *purpose;
+        g_free(purpose);
+        if (!values_ok) {
+            gtk_widget_show(td->dialog);
+            if (gnc_verify_dialog(
+                    td->dialog, TRUE, "%s",
+                    _("You did not enter any transaction purpose. A purpose is "
+                      "required for an online transfer.\n"
+                      "\n"
+                      "Do you want to enter the job again?"))) {
+                continue;
+            } else {
+                AB_Transaction_free(td->ab_trans);
+                td->ab_trans = NULL;
+                result = GTK_RESPONSE_CANCEL;
+                break;
+            }
+        }
+
+        /* Check recipient / remote name */
+        othername = gnc_ab_get_remote_name(td->ab_trans);
+        values_ok = othername && *othername;
+        g_free(othername);
+        if (!values_ok) {
+            gtk_widget_show(td->dialog);
+            if (gnc_verify_dialog(
+                    td->dialog, TRUE, "%s",
+                    _("You did not enter a recipient name.  A recipient name is "
+                      "required for an online transfer.\n"
+                      "\n"
+                      "Do you want to enter the job again?"))) {
+                continue;
+            } else {
+                AB_Transaction_free(td->ab_trans);
+                td->ab_trans = NULL;
+                result = GTK_RESPONSE_CANCEL;
+                break;
+            }
+        }
+
+        /* FIXME: If this is a direct debit, set the textkey/ "Textschluessel"/
+         * transactionCode according to some GUI selection here!! */
+        /*if (td->trans_type == SINGLE_DEBITNOTE)
+          AB_TRANSACTION_setTextKey (td->hbci_trans, 05); */
+
+        /* And finally check the account code, if ktoblzcheck is available */
+        values_ok = check_ktoblzcheck(td->dialog, td, td->ab_trans);
+
+    } while (!values_ok);
+
+    /* Hide the dialog */
+    if (td->dialog)
+        gtk_widget_hide(td->dialog);
+
+    return result;
+}
+
+static gboolean
+clear_templ_helper(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
+                   gpointer user_data) {
+    GncABTransTempl *templ;
+
+    g_return_val_if_fail(model && iter, TRUE);
+
+    gtk_tree_model_get(model, iter, TEMPLATE_POINTER, &templ, -1);
+    gnc_ab_trans_templ_free(templ);
+    return FALSE;
+}
+
+void
+gnc_ab_trans_dialog_free(GncABTransDialog *td)
+{
+    if (!td) return;
+    if (td->ab_trans)
+        AB_Transaction_free(td->ab_trans);
+    if (td->dialog)
+        gtk_widget_destroy(td->dialog);
+    if (td->template_list_store) {
+        gtk_tree_model_foreach(GTK_TREE_MODEL(td->template_list_store),
+                               clear_templ_helper, NULL);
+        g_object_unref(td->template_list_store);
+    }
+#if HAVE_KTOBLZCHECK_H
+    AccountNumberCheck_delete(td->blzcheck);
+#endif
+    g_free(td);
+}
+
+static gboolean
+get_templ_helper(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
+                 gpointer data)
+{
+    GList **list = data;
+    GncABTransTempl *templ;
+
+    g_return_val_if_fail(model && iter, TRUE);
+
+    gtk_tree_model_get(model, iter, TEMPLATE_POINTER, &templ, -1);
+    *list = g_list_prepend(*list, templ);
+    return FALSE;
+}
+
+GList *
+gnc_ab_trans_dialog_get_templ(const GncABTransDialog *td, gboolean *changed)
+{
+    GList *list = NULL;
+
+    g_return_val_if_fail(td, NULL);
+
+    if (changed) {
+        *changed = td->templ_changed;
+        if (!*changed)
+            return NULL;
+    }
+
+    gtk_tree_model_foreach(GTK_TREE_MODEL(td->template_list_store),
+                           get_templ_helper, &list);
+    list = g_list_reverse(list);
+    return list;
+}
+
+GtkWidget *
+gnc_ab_trans_dialog_get_parent(const GncABTransDialog *td)
+{
+    g_return_val_if_fail(td, NULL);
+    return td->parent;
+}
+
+const AB_TRANSACTION *
+gnc_ab_trans_dialog_get_ab_trans(const GncABTransDialog *td)
+{
+    g_return_val_if_fail(td, NULL);
+    return td->ab_trans;
+}
+
+static AB_JOB *
+get_available_empty_job(AB_ACCOUNT *ab_acc, GncABTransType trans_type)
+{
+    AB_JOB *job;
+
+    switch (trans_type) {
+    case SINGLE_DEBITNOTE:
+        job = AB_JobSingleDebitNote_new(ab_acc);
+        break;
+    case SINGLE_INTERNAL_TRANSFER:
+        job = AB_JobInternalTransfer_new(ab_acc);
+        break;
+    case SINGLE_TRANSFER:
+    default:
+        job = AB_JobSingleTransfer_new(ab_acc);
+    };
+
+    if (!job || AB_Job_CheckAvailability(job, 0)) {
+        if (job) AB_Job_free(job);
+        return NULL;
+    }
+    return job;
+}
+
+AB_JOB *
+gnc_ab_trans_dialog_get_job(const GncABTransDialog *td)
+{
+    g_return_val_if_fail(td, NULL);
+    return gnc_ab_get_trans_job(td->ab_acc, td->ab_trans, td->trans_type);
+}
+
+AB_JOB *
+gnc_ab_get_trans_job(AB_ACCOUNT *ab_acc, const AB_TRANSACTION *ab_trans,
+                     GncABTransType trans_type)
+{
+    AB_JOB *job;
+
+    g_return_val_if_fail(ab_acc && ab_trans, NULL);
+
+    job = get_available_empty_job(ab_acc, trans_type);
+    if (job) {
+        switch (trans_type) {
+        case SINGLE_DEBITNOTE:
+            AB_JobSingleDebitNote_SetTransaction(job, ab_trans);
+            break;
+        case SINGLE_INTERNAL_TRANSFER:
+            AB_JobInternalTransfer_SetTransaction(job, ab_trans);
+            break;
+        case SINGLE_TRANSFER:
+        default:
+            AB_JobSingleTransfer_SetTransaction(job, ab_trans);
+        };
+    }
+    return job;
+}
+
+void
+templ_list_row_activated_cb(GtkTreeView *view, GtkTreePath *path,
+                            GtkTreeViewColumn *column, gpointer user_data)
+{
+    GncABTransDialog *td = user_data;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    GncABTransTempl *templ;
+    const gchar *old_name, *new_name;
+    const gchar *old_account, *new_account;
+    const gchar *old_bankcode, *new_bankcode;
+    const gchar *old_purpose, *new_purpose;
+    const gchar *old_purpose_cont, *new_purpose_cont;
+    GtkWidget *amount_widget;
+    const gchar *old_amount_text;
+    gnc_numeric old_amount, new_amount;
+
+    g_return_if_fail(td);
+
+    ENTER("td=%p", td);
+    if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(td->template_list_store), &iter,
+                                 path)) {
+        LEAVE("Could not get iter");
+        return;
+    }
+    gtk_tree_model_get(GTK_TREE_MODEL(td->template_list_store), &iter,
+                       TEMPLATE_POINTER, &templ, -1);
+
+    /* Get old values */
+    old_name = gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry));
+    old_account = gtk_entry_get_text(GTK_ENTRY(td->recp_account_entry));
+    old_bankcode = gtk_entry_get_text(GTK_ENTRY(td->recp_bankcode_entry));
+    old_purpose = gtk_entry_get_text(GTK_ENTRY(td->purpose_entry));
+    old_purpose_cont = gtk_entry_get_text(GTK_ENTRY(td->purpose_cont_entry));
+    amount_widget = gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(td->amount_edit));
+    old_amount_text = gtk_entry_get_text(GTK_ENTRY(amount_widget));
+    old_amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(td->amount_edit));
+
+    /* Get new values */
+    new_name = gnc_ab_trans_templ_get_recp_name(templ);
+    new_account = gnc_ab_trans_templ_get_recp_account(templ);
+    new_bankcode = gnc_ab_trans_templ_get_recp_bankcode(templ);
+    new_purpose = gnc_ab_trans_templ_get_purpose(templ);
+    new_purpose_cont = gnc_ab_trans_templ_get_purpose_cont(templ);
+    new_amount = gnc_ab_trans_templ_get_amount(templ);
+    if (!new_name) new_name = "";
+    if (!new_account) new_account = "";
+    if (!new_bankcode) new_bankcode = "";
+    if (!new_purpose) new_purpose = "";
+    if (!new_purpose_cont) new_purpose_cont = "";
+
+    /* Check for differences to avoid overwriting entered text */
+    if ((*old_name && strcmp(old_name, new_name))
+        || (*old_account && strcmp(old_account, new_account))
+        || (*old_bankcode && strcmp(old_bankcode, new_bankcode))
+        || (*old_purpose && strcmp(old_purpose, new_purpose))
+        || (*old_purpose_cont && strcmp(old_purpose_cont, new_purpose_cont))
+        || (*old_amount_text && !gnc_numeric_equal(old_amount, new_amount))) {
+        if (!gnc_verify_dialog(
+                td->parent, FALSE,
+                _("Do you really want to overwrite your changes with the "
+                  "contents of the template \"%s\"?"),
+                gnc_ab_trans_templ_get_name(templ))) {
+
+            LEAVE("aborted");
+            return;
+        }
+    }
+
+    /* Fill in */
+    gtk_entry_set_text(GTK_ENTRY(td->recp_name_entry), new_name);
+    gtk_entry_set_text(GTK_ENTRY(td->recp_account_entry), new_account);
+    gtk_entry_set_text(GTK_ENTRY(td->recp_bankcode_entry), new_bankcode);
+    gtk_entry_set_text(GTK_ENTRY(td->purpose_entry), new_purpose);
+    gtk_entry_set_text(GTK_ENTRY(td->purpose_cont_entry), new_purpose_cont);
+    gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(td->amount_edit), new_amount);
+    LEAVE(" ");
+}
+
+void
+dat_bankcode_changed_cb(GtkEditable *editable, gpointer user_data)
+{
+#if HAVE_KTOBLZCHECK_H
+    GncABTransDialog *td = user_data;
+    const AccountNumberCheck_Record *record;
+    const gchar *input = gtk_entry_get_text(GTK_ENTRY(td->recp_bankcode_entry));
+
+    g_return_if_fail(td);
+
+    ENTER("td=%p, input=%s", td, input);
+    record = AccountNumberCheck_findBank(td->blzcheck, input);
+
+    if (record) {
+        const char *bankname = AccountNumberCheck_Record_bankName(record);
+        GError *error = NULL;
+        const char *ktoblzcheck_encoding =
+#ifdef KTOBLZCHECK_VERSION_MAJOR
+            /* This version number macro has been added in ktoblzcheck-1.10, but
+             * this function exists already since ktoblzcheck-1.7, so we're on
+             * the safe side. */
+            AccountNumberCheck_stringEncoding()
+#else
+            /* Every ktoblzcheck release before 1.10 is guaranteed to return
+             * strings only in ISO-8859-15. */
+            "ISO-8859-15"
+#endif
+            ;
+        gchar *utf8_bankname = g_convert(bankname, strlen(bankname), "UTF-8",
+                                         ktoblzcheck_encoding, NULL, NULL,
+                                         &error);
+
+        if (error) {
+            g_critical("Error converting bankname \"%s\" to UTF-8", bankname);
+            g_error_free (error);
+            /* Conversion was erroneous, so don't use the string */
+            utf8_bankname = g_strdup(_("(unknown)"));
+        }
+        gtk_label_set_text(GTK_LABEL(td->recp_bankname_label),
+                           *utf8_bankname ? utf8_bankname : _("(unknown)"));
+        DEBUG("Found: %s", utf8_bankname);
+        g_free(utf8_bankname);
+    } else {
+        gtk_label_set_text(GTK_LABEL(td->recp_bankname_label), _("(unknown)"));
+    }
+    LEAVE(" ");
+#endif
+}
+
+struct _FindTemplData {
+    const gchar *name;
+    const GncABTransTempl *pointer;
+};
+
+static gboolean
+find_templ_helper(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
+                  gpointer user_data)
+{
+    struct _FindTemplData *data = user_data;
+    gchar *name;
+    GncABTransTempl *templ;
+    gboolean match;
+
+    g_return_val_if_fail(model && data, TRUE);
+    gtk_tree_model_get(model, iter,
+                       TEMPLATE_NAME, &name,
+                       TEMPLATE_POINTER, &templ,
+                       -1);
+    if (data->name) {
+        /* Search for the template by name */
+        g_return_val_if_fail(!data->pointer, TRUE);
+        match = strcmp(name, data->name) == 0;
+        if (match) data->pointer = templ;
+    } else {
+        /* Search for the template by template pointer */
+        g_return_val_if_fail(!data->name, TRUE);
+        match = templ == data->pointer;
+        if (match) data->name = g_strdup(name);
+    }
+    g_free(name);
+    return match;
+}
+
+void
+dat_add_templ_cb(GtkButton *button, gpointer user_data)
+{
+    GncABTransDialog *td = user_data;
+    GladeXML *xml;
+    GtkWidget *dialog;
+    GtkWidget *entry;
+    gint retval;
+    const gchar *name;
+    GncABTransTempl *templ;
+    struct _FindTemplData data;
+    GtkTreeSelection *selection;
+    GtkTreeIter cur_iter;
+    GtkTreeIter new_iter;
+
+    g_return_if_fail(td);
+
+    ENTER("td=%p", td);
+    xml = gnc_glade_xml_new ("aqbanking.glade", "Template Name Dialog");
+    dialog = glade_xml_get_widget(xml, "Template Name Dialog");
+    g_object_set_data_full(G_OBJECT(dialog), "xml", xml, g_object_unref);
+    entry = glade_xml_get_widget(xml, "template_name");
+
+    /* Suggest recipient name as name of the template */
+    gtk_entry_set_text(GTK_ENTRY(entry),
+                       gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)));
+
+    do {
+        retval = gtk_dialog_run(GTK_DIALOG(dialog));
+        if (retval != GTK_RESPONSE_OK)
+            break;
+
+        name = gtk_entry_get_text(GTK_ENTRY(entry));
+        if (!*name)
+            break;
+
+        data.name = name;
+        data.pointer = NULL;
+        gtk_tree_model_foreach(GTK_TREE_MODEL(td->template_list_store),
+                               find_templ_helper, &data);
+        if (data.pointer) {
+            gnc_error_dialog(dialog,
+                             _("A template with the given name already exists.  "
+                               "Please enter another name."));
+            continue;
+        }
+
+        /* Create a new template */
+        templ = gnc_ab_trans_templ_new_full(
+            name,
+            gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)),
+            gtk_entry_get_text(GTK_ENTRY(td->recp_account_entry)),
+            gtk_entry_get_text(GTK_ENTRY(td->recp_bankcode_entry)),
+            gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(td->amount_edit)),
+            gtk_entry_get_text(GTK_ENTRY(td->purpose_entry)),
+            gtk_entry_get_text (GTK_ENTRY(td->purpose_cont_entry)));
+
+        /* Insert it, either after the selected one or at the end */
+        selection = gtk_tree_view_get_selection(td->template_gtktreeview);
+        if (gtk_tree_selection_get_selected(selection, NULL, &cur_iter)) {
+            gtk_list_store_insert_after(td->template_list_store,
+                                        &new_iter, &cur_iter);
+        } else {
+            gtk_list_store_append(td->template_list_store, &new_iter);
+        }
+        gtk_list_store_set(td->template_list_store, &new_iter,
+                           TEMPLATE_NAME, name,
+                           TEMPLATE_POINTER, templ,
+                           -1);
+        td->templ_changed = TRUE;
+        DEBUG("Added template with name %s", name);
+        break;
+    } while (TRUE);
+
+    gtk_widget_destroy(dialog);
+
+    LEAVE(" ");
+}
+
+void
+dat_moveup_templ_cb(GtkButton *button, gpointer user_data)
+{
+    GncABTransDialog *td = user_data;
+    GtkTreeSelection *selection;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    GtkTreePath *prev_path;
+    GtkTreeIter prev_iter;
+
+    g_return_if_fail(td);
+
+    selection = gtk_tree_view_get_selection(td->template_gtktreeview);
+    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
+        return;
+
+    prev_path = gtk_tree_model_get_path(model, &iter);
+    if (gtk_tree_path_prev(prev_path)) {
+        if (gtk_tree_model_get_iter(model, &prev_iter, prev_path)) {
+            gtk_list_store_move_before(GTK_LIST_STORE(model), &iter, &prev_iter);
+            td->templ_changed = TRUE;
+        }
+    }
+    gtk_tree_path_free(prev_path);
+}
+
+void
+dat_movedown_templ_cb(GtkButton *button, gpointer user_data)
+{
+    GncABTransDialog *td = user_data;
+    GtkTreeSelection *selection;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    GtkTreeIter next_iter;
+
+    g_return_if_fail(td);
+
+    selection = gtk_tree_view_get_selection(td->template_gtktreeview);
+    if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+        return;
+
+    next_iter = iter;
+    if (gtk_tree_model_iter_next(model, &next_iter)) {
+        gtk_list_store_move_after(GTK_LIST_STORE(model), &iter, &next_iter);
+        td->templ_changed = TRUE;
+    }
+}
+
+void
+dat_sort_templ_cb(GtkButton *button, gpointer user_data)
+{
+    GncABTransDialog *td = user_data;
+
+    g_return_if_fail(td);
+
+    ENTER("td=%p", td);
+    gtk_tree_sortable_set_sort_column_id(
+        GTK_TREE_SORTABLE(td->template_list_store),
+        TEMPLATE_NAME, GTK_SORT_ASCENDING);
+    gtk_tree_sortable_set_sort_column_id(
+        GTK_TREE_SORTABLE(td->template_list_store),
+        GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
+        GTK_SORT_ASCENDING);
+    td->templ_changed = TRUE;
+    LEAVE(" ");
+}
+
+void
+dat_del_templ_cb(GtkButton *button, gpointer user_data)
+{
+    GncABTransDialog *td = user_data;
+    GtkTreeSelection *selection;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    gchar *name;
+
+    g_return_if_fail(td);
+
+    ENTER("td=%p", td);
+    selection = gtk_tree_view_get_selection(td->template_gtktreeview);
+    if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
+        LEAVE("None selected");
+        return;
+    }
+
+    gtk_tree_model_get(model, &iter, TEMPLATE_NAME, &name, -1);
+    if (gnc_verify_dialog(
+            td->parent, FALSE,
+            _("Do you really want to delete the template with the name \"%s\"?"),
+            name)) {
+        gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+        td->templ_changed = TRUE;
+        DEBUG("Deleted template with name %s", name);
+    }
+    g_free(name);
+    LEAVE(" ");
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/dialog-ab-trans.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/dialog-ab-trans.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/dialog-ab-trans.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,143 @@
+/*
+ * dialog-ab-trans.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file dialog-ab-trans.h
+ * @brief Dialog for AqBanking transaction data
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2004 Bernd Wagner
+ * @author Copyright (C) 2006 David Hampton <hampton at employees.org>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef DIALOG_AB_TRANS_H
+#define DIALOG_AB_TRANS_H
+
+#include <gtk/gtk.h>
+#include <aqbanking/banking.h>
+
+#include "Account.h"
+
+G_BEGIN_DECLS
+
+#define GNC_RESPONSE_NOW GTK_RESPONSE_YES
+#define GNC_RESPONSE_LATER GTK_RESPONSE_NO
+
+typedef struct _GncABTransDialog GncABTransDialog;
+
+typedef enum _GncABTransType GncABTransType;
+enum _GncABTransType {
+    SINGLE_TRANSFER = 0,
+    SINGLE_DEBITNOTE,
+    SINGLE_INTERNAL_TRANSFER
+};
+
+/**
+ * FIXME
+ *
+ * @param parent Widget to use as parent, may be NULL
+ * @param ab_acc FIXME
+ * @param commodity_scu FIXME
+ * @param trans_type Type of transaction
+ * @param templates A GList of template transactions which will become fully
+ * managed by the dialog, so do not free it and retrieve snapshots via
+ * gnc_ab_trans_dialog_get_templ()
+ * @return FIXME
+ */
+GncABTransDialog *gnc_ab_trans_dialog_new(GtkWidget *parent, AB_ACCOUNT *ab_acc,
+                                          gint commodity_scu,
+                                          GncABTransType trans_type,
+                                          GList *templates);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ * @param ab_acc AqBanking account
+ * @return FIXME
+ */
+gint gnc_ab_trans_dialog_run_until_ok(GncABTransDialog *td);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ */
+void gnc_ab_trans_dialog_free(GncABTransDialog *td);
+
+/**
+ * Retrieve the current list of transaction templates from the dialog @a
+ * td, unless @a changed is a specified location and the templates have
+ * not been touched by the user.
+ *
+ * @param td Transaction dialog
+ * @param changed Location to store whether the templates have been
+ * changed, may be NULL
+ * @return The a newly allocated list of the internal transaction
+ * templates. Free this one via g_list_free().
+ */
+GList *gnc_ab_trans_dialog_get_templ(const GncABTransDialog *td,
+                                     gboolean *changed);
+
+/**
+ * Retrieve the widget used as parent.
+ *
+ * @param td Transaction dialog
+ * @return The parent
+ */
+GtkWidget *gnc_ab_trans_dialog_get_parent(const GncABTransDialog *td);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ * @return FIXME
+ */
+const AB_TRANSACTION *gnc_ab_trans_dialog_get_ab_trans(
+    const GncABTransDialog *td);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ * @return FIXME
+ */
+AB_JOB *gnc_ab_trans_dialog_get_job(const GncABTransDialog *td);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ * @return FIXME
+ */
+AB_JOB *gnc_ab_get_trans_job(AB_ACCOUNT *ab_acc, const AB_TRANSACTION *ab_trans,
+                             GncABTransType trans_type);
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* DIALOG_AB_TRANS_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/dialog-daterange.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/dialog-daterange.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/dialog-daterange.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,148 @@
+/*
+ * dialog-daterange.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file dialog-daterange.c
+ * @brief Dialog for date range entry
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include "dialog-daterange.h"
+#include "dialog-utils.h"
+#include "gnc-date-edit.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+typedef struct _DaterangeInfo DaterangeInfo;
+
+void ddr_toggled_cb(GtkToggleButton *button, gpointer user_data);
+
+struct _DaterangeInfo
+{
+  GtkWidget *enter_from_button;
+  GtkWidget *enter_to_button;
+  GtkWidget *from_dateedit;
+  GtkWidget *to_dateedit;
+};
+
+gboolean
+gnc_ab_enter_daterange(GtkWidget *parent,
+                       const char *heading,
+                       Timespec *from_date,
+                       gboolean *last_retv_date,
+                       gboolean *first_possible_date,
+                       Timespec *to_date,
+                       gboolean *to_now)
+{
+    GladeXML *xml;
+    GtkWidget *dialog;
+    GtkWidget *heading_label;
+    GtkWidget *first_button;
+    GtkWidget *last_retrieval_button;
+    GtkWidget *now_button;
+    DaterangeInfo info;
+    gint result;
+
+    xml = gnc_glade_xml_new("aqbanking.glade", "Date Range Dialog");
+
+    dialog = glade_xml_get_widget(xml, "Date Range Dialog");
+    g_object_set_data_full(G_OBJECT(dialog), "xml", xml, g_object_unref);
+    glade_xml_signal_autoconnect_full(xml, gnc_glade_autoconnect_full_func,
+                                      &info);
+
+    if (parent)
+        gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
+
+    heading_label  = glade_xml_get_widget(xml, "heading_label");
+    first_button  = glade_xml_get_widget(xml, "first_button");
+    last_retrieval_button  = glade_xml_get_widget(xml, "last_retrieval_button");
+    info.enter_from_button  = glade_xml_get_widget(xml, "enter_from_button");
+    now_button  = glade_xml_get_widget(xml, "now_button");
+    info.enter_to_button  = glade_xml_get_widget(xml, "enter_to_button");
+
+    info.from_dateedit = gnc_date_edit_new_ts(*from_date, FALSE, FALSE);
+    gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(xml, "enter_from_box")),
+                      info.from_dateedit);
+    gtk_widget_show(info.from_dateedit);
+
+    info.to_dateedit = gnc_date_edit_new_ts(*to_date, FALSE, FALSE);
+    gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(xml, "enter_to_box")),
+                      info.to_dateedit);
+    gtk_widget_show(info.to_dateedit);
+
+    if (*last_retv_date) {
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(last_retrieval_button),
+                                     TRUE);
+    } else {
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(first_button), TRUE);
+        gtk_widget_set_sensitive(last_retrieval_button, FALSE);
+    }
+
+    gtk_widget_set_sensitive(info.from_dateedit, FALSE);
+    gtk_widget_set_sensitive(info.to_dateedit, FALSE);
+
+    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
+
+    if (heading)
+        gtk_label_set_text(GTK_LABEL(heading_label), heading);
+
+    gtk_widget_show(dialog);
+
+    result = gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_hide(dialog);
+
+    if (result == GTK_RESPONSE_OK) {
+        *from_date = gnc_date_edit_get_date_ts(
+            GNC_DATE_EDIT(info.from_dateedit));
+        *last_retv_date = gtk_toggle_button_get_active(
+            GTK_TOGGLE_BUTTON(last_retrieval_button));
+        *first_possible_date = gtk_toggle_button_get_active(
+            GTK_TOGGLE_BUTTON(first_button));
+        *to_date = gnc_date_edit_get_date_ts(
+            GNC_DATE_EDIT(info.to_dateedit));
+        *to_now = gtk_toggle_button_get_active(
+            GTK_TOGGLE_BUTTON(now_button));
+    }
+
+    gtk_widget_destroy(dialog);
+
+    return result == GTK_RESPONSE_OK;
+}
+
+void
+ddr_toggled_cb(GtkToggleButton *button, gpointer user_data)
+{
+    DaterangeInfo *info = user_data;
+
+    g_return_if_fail(info);
+
+    gtk_widget_set_sensitive(info->from_dateedit,
+                             gtk_toggle_button_get_active(
+                                 GTK_TOGGLE_BUTTON(info->enter_from_button)));
+    gtk_widget_set_sensitive(info->to_dateedit,
+                             gtk_toggle_button_get_active(
+                                 GTK_TOGGLE_BUTTON(info->enter_to_button)));
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/dialog-daterange.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/dialog-daterange.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/dialog-daterange.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,67 @@
+/*
+ * dialog-daterange.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file dialog-daterange.h
+ * @brief Dialog for date range entry
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef DIALOG_DATERANGE_H
+#define DIALOG_DATERANGE_H
+
+#include <gtk/gtk.h>
+
+#include "qof.h"
+
+G_BEGIN_DECLS
+
+/**
+ * Show a dialog to pick a time frame using a sensible set of default options.
+ *
+ * @param parent Widget to use as parent, may be NULL
+ * @param heading Descriptive text showed at the top, may be NULL
+ * @param from_date Location to read from the initial and write to the final
+ * value of the from date entry
+ * @param last_retv_date Location to read from whether the caller knows the last
+ * retrieval date and write to whether the corresponding button has been chosen
+ * @param first_possible_date Location to write to whether the earliest possible
+ * date button has been chosen
+ * @param to_date Location to read from the initial and write to the final value
+ * of the to date entry
+ * @param to_now Location to write to whether the to now button has been chosen
+ */
+gboolean gnc_ab_enter_daterange(GtkWidget *parent,
+                                const char *heading,
+                                Timespec *from_date,
+                                gboolean *last_retv_date,
+                                gboolean *first_possible_date,
+                                Timespec *to_date,
+                                gboolean *to_now);
+
+G_END_DECLS
+
+#endif /* DIALOG_DATERANGE_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/druid-ab-initial.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/druid-ab-initial.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/druid-ab-initial.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,783 @@
+/*
+ * druid-ab-initial.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file druid-ab-initial.c
+ * @brief AqBanking setup functionality
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2006 David Hampton <hampton at employees.org>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <aqbanking/banking.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <gdk/gdkkeysyms.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "dialog-utils.h"
+#include "druid-ab-initial.h"
+#include "druid-utils.h"
+#include "gnc-ab-kvp.h"
+#include "gnc-ab-utils.h"
+#include "gnc-component-manager.h"
+#include "gnc-glib-utils.h"
+#include "gnc-ui.h"
+#include "gnc-ui-util.h"
+#include "gnc-session.h"
+#include "import-account-matcher.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+#define DRUID_AB_INITIAL_CM_CLASS "druid-ab-initial"
+
+typedef struct _ABInitialInfo ABInitialInfo;
+typedef struct _DeferredInfo DeferredInfo;
+typedef struct _AccCbData AccCbData;
+typedef struct _RevLookupData RevLookupData;
+
+gboolean dai_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
+void dai_cancel_cb(GnomeDruid *druid, gpointer user_data);
+void dai_destroy_cb(GtkObject *object, gpointer user_data);
+void dai_wizard_page_prepare_cb(GnomeDruidPage *druid_page, GtkWidget *widget, gpointer user_data);
+void dai_wizard_button_clicked_cb(GtkButton *button, gpointer user_data);
+void dai_match_page_prepare_cb(GnomeDruidPage *druid_page, GtkWidget *widget, gpointer user_data);
+void dai_finish_cb(GnomeDruidPage *druid_page, GtkWidget *widget, gpointer user_data);
+
+static gboolean banking_has_accounts(AB_BANKING *banking);
+static void hash_from_kvp_acc_cb(Account *gnc_acc, gpointer user_data);
+static void druid_enable_next_button(ABInitialInfo *info);
+static void druid_disable_next_button(ABInitialInfo *info);
+static void child_exit_cb(GPid pid, gint status, gpointer data);
+static gchar *ab_account_longname(const AB_ACCOUNT *ab_acc);
+static AB_ACCOUNT *update_account_list_acc_cb(AB_ACCOUNT *ab_acc, gpointer user_data);
+static void update_account_list(ABInitialInfo *info);
+static gboolean find_gnc_acc_cb(gpointer key, gpointer value, gpointer user_data);
+static gboolean clear_line_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data);
+static void account_list_changed_cb(GtkTreeSelection *selection, gpointer user_data);
+static void clear_kvp_acc_cb(Account *gnc_acc, gpointer user_data);
+static void save_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data);
+static void cm_close_handler(gpointer user_data);
+
+struct _ABInitialInfo {
+    GtkWidget *window;
+    GtkWidget *druid;
+
+    /* account match page */
+    gboolean match_page_prepared;
+    GtkTreeView *account_view;
+    GtkListStore *account_store;
+
+    /* managed by child_exit_cb */
+    DeferredInfo *deferred_info;
+
+    /* AqBanking stuff */
+    AB_BANKING *api;
+    /* AB_ACCOUNT* -> Account* -- DO NOT DELETE THE KEYS! */
+    GHashTable *gnc_hash;
+};
+
+struct _DeferredInfo {
+    ABInitialInfo *initial_info;
+    gchar *wizard_path;
+    gboolean qt_probably_unavailable;
+};
+
+struct _AccCbData {
+    AB_BANKING *api;
+    GHashTable *hash;
+};
+
+struct _RevLookupData {
+    Account *gnc_acc;
+    AB_ACCOUNT *ab_acc;
+};
+
+enum account_list_cols {
+    ACCOUNT_LIST_COL_INDEX = 0,
+    ACCOUNT_LIST_COL_AB_NAME,
+    ACCOUNT_LIST_COL_AB_ACCT,
+    ACCOUNT_LIST_COL_GNC_NAME,
+    ACCOUNT_LIST_COL_CHECKED,
+    NUM_ACCOUNT_LIST_COLS
+};
+
+gboolean
+dai_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
+{
+    if (event->keyval == GDK_Escape) {
+        gtk_widget_destroy(widget);
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+void
+dai_cancel_cb(GnomeDruid *druid, gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+
+    gtk_widget_destroy(info->window);
+}
+
+void
+dai_destroy_cb(GtkObject *object, gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+
+    gnc_unregister_gui_component_by_data(DRUID_AB_INITIAL_CM_CLASS, info);
+
+    if (info->deferred_info) {
+        g_message("Online Banking druid is being closed but the wizard is still "
+                  "running.  Inoring.");
+
+        /* Tell child_exit_cb() that there is no druid anymore */
+        info->deferred_info->initial_info = NULL;
+    }
+
+    if (info->gnc_hash) {
+        AB_Banking_OnlineFini(info->api);
+        g_hash_table_destroy(info->gnc_hash);
+        info->gnc_hash = NULL;
+    }
+
+    if (info->api) {
+        gnc_AB_BANKING_delete(info->api);
+        info->api = NULL;
+    }
+
+    gtk_widget_destroy(info->window);
+    info->window = NULL;
+
+    g_free(info);
+}
+
+void
+dai_wizard_page_prepare_cb(GnomeDruidPage *druid_page, GtkWidget *widget,
+                           gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+
+    g_return_if_fail(info->api);
+
+    if (banking_has_accounts(info->api))
+        druid_enable_next_button(info);
+    else
+        druid_disable_next_button(info);
+}
+
+void
+dai_wizard_button_clicked_cb(GtkButton *button, gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+    AB_BANKING *banking = info->api;
+    GWEN_BUFFER *buf;
+    gboolean wizard_exists;
+    const gchar *wizard_path;
+    gboolean qt_probably_unavailable = FALSE;
+
+    g_return_if_fail(banking);
+
+    ENTER("user_data: %p", user_data);
+
+    if (info->deferred_info) {
+        LEAVE("Wizard is still running");
+        return;
+    }
+
+    /* This is the point where we look for and start an external
+     * application shipped with aqbanking that contains the setup druid
+     * for AqBanking related stuff.  It requires qt (but not kde).  This
+     * application contains the very verbose step-by-step setup wizard
+     * for the AqBanking account, and the application is shared with
+     * other AqBanking-based financial managers that offer the AqBanking
+     * features (e.g. KMyMoney).  See gnucash-devel discussion here
+     * https://lists.gnucash.org/pipermail/gnucash-devel/2004-December/012351.html
+     */
+    buf = GWEN_Buffer_new(NULL, 300, 0, 0);
+    AB_Banking_FindWizard(banking, "", NULL, buf);
+    wizard_exists = *GWEN_Buffer_GetStart(buf) != 0;
+    wizard_path = GWEN_Buffer_GetStart(buf);
+
+    if (wizard_exists) {
+        /* Really check whether the file exists */
+        gint fd = g_open(wizard_path, O_RDONLY, 0);
+        if (fd == -1)
+            wizard_exists = FALSE;
+        else
+            close(fd);
+    }
+
+#ifdef G_OS_WIN32
+    {
+        const char *check_file = "qtdemo.exe";
+        gchar *found_program = g_find_program_in_path(check_file);
+        if (found_program) {
+            g_debug("Yes, we found the Qt demo program in %s\n", found_program);
+            g_free(found_program);
+        } else {
+            g_warning("Ouch, no Qt demo program was found. Qt not installed?\n");
+            qt_probably_unavailable = TRUE;
+        }
+    }
+#endif
+
+    druid_disable_next_button(info);
+
+    if (wizard_exists) {
+        /* Call the qt wizard. See the note above about why this
+         * approach is chosen. */
+
+        GPid pid;
+        GError *error = NULL;
+        gchar *argv[2];
+        gboolean spawned;
+
+        argv[0] = g_strdup (wizard_path);
+        argv[1] = NULL;
+        spawned = g_spawn_async (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
+                                 NULL, NULL, &pid, &error);
+        g_free (argv[0]);
+
+        if (error)
+            g_critical(
+                "Error on starting AqBanking setup wizard: Code %d: %s",
+                error->code, error->message ? error->message : "(null)");
+
+        if (!spawned) {
+            g_critical("Could not start AqBanking setup wizard: %s",
+                       error->message ? error->message : "(null)");
+            g_error_free (error);
+        } else {
+            /* Keep a reference to info that can survive info */
+            info->deferred_info = g_new0(DeferredInfo, 1);
+            info->deferred_info->initial_info = info;
+            info->deferred_info->wizard_path = g_strdup(wizard_path);
+            info->deferred_info->qt_probably_unavailable =
+                qt_probably_unavailable;
+
+            g_child_watch_add (pid, child_exit_cb, info->deferred_info);
+        }
+    } else {
+        g_warning("on_aqhbci_button: Oops, no aqhbci setup wizard found.");
+        gnc_error_dialog
+            (info->window,
+             _("The external program \"AqBanking Setup Wizard\" has not "
+               "been found. \n\n"
+               "The %s package should include the "
+               "program \"qt3-wizard\".  Please check your installation to "
+               "ensure this program is present.  On some distributions this "
+               "may require installing additional packages."),
+             QT3_WIZARD_PACKAGE);
+        druid_disable_next_button(info);
+    }
+
+    GWEN_Buffer_free(buf);
+
+    LEAVE(" ");
+}
+
+void
+dai_match_page_prepare_cb(GnomeDruidPage *druid_page, GtkWidget *widget,
+                          gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+    Account *root;
+    AccCbData data;
+
+    g_return_if_fail(info && info->api);
+
+    /* No way back */
+    gnome_druid_set_buttons_sensitive(GNOME_DRUID(info->druid),
+                                      FALSE, TRUE, TRUE, TRUE);
+
+    /* Do not run this twice */
+    if (info->match_page_prepared)
+        return;
+    else
+        info->match_page_prepared = TRUE;
+
+    /* Load aqbanking accounts */
+    AB_Banking_OnlineInit(info->api);
+
+    /* Determine current mapping */
+    root = gnc_book_get_root_account(gnc_get_current_book());
+    info->gnc_hash = g_hash_table_new(&g_direct_hash, &g_direct_equal);
+    data.api = info->api;
+    data.hash = info->gnc_hash;
+    gnc_account_foreach_descendant(
+        root, (AccountCb) hash_from_kvp_acc_cb, &data);
+
+    /* Update the graphical representation */
+    update_account_list(info);
+}
+
+void
+dai_finish_cb(GnomeDruidPage *druid_page, GtkWidget *widget,
+              gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+    Account *root;
+
+    g_return_if_fail(info && info->gnc_hash);
+
+    /* Commit the changes */
+    root = gnc_book_get_root_account(gnc_get_current_book());
+    gnc_account_foreach_descendant(root, (AccountCb) clear_kvp_acc_cb, NULL);
+    g_hash_table_foreach(info->gnc_hash, (GHFunc) save_kvp_acc_cb, NULL);
+
+    gtk_widget_destroy(info->window);
+}
+
+static gboolean
+banking_has_accounts(AB_BANKING *banking)
+{
+    AB_ACCOUNT_LIST2 *accl;
+    gboolean result;
+
+    g_return_val_if_fail(banking, FALSE);
+
+    AB_Banking_OnlineInit(banking);
+
+    accl = AB_Banking_GetAccounts(banking);
+    if (accl && (AB_Account_List2_GetSize(accl) > 0))
+        result = TRUE;
+    else
+        result = FALSE;
+
+    if (accl)
+        AB_Account_List2_free(accl);
+
+    AB_Banking_OnlineFini(banking);
+
+    return result;
+}
+
+static void
+hash_from_kvp_acc_cb(Account *gnc_acc, gpointer user_data)
+{
+    AccCbData *data = user_data;
+    AB_ACCOUNT *ab_acc;
+
+    ab_acc = gnc_ab_get_ab_account(data->api, gnc_acc);
+    if (ab_acc)
+        g_hash_table_insert(data->hash, ab_acc, gnc_acc);
+}
+
+static void
+druid_enable_next_button(ABInitialInfo *info)
+{
+    g_return_if_fail(info);
+    gnome_druid_set_buttons_sensitive(GNOME_DRUID(info->druid),
+                                      TRUE, TRUE, TRUE, TRUE);
+}
+
+static void
+druid_disable_next_button(ABInitialInfo *info)
+{
+    g_return_if_fail(info);
+    gnome_druid_set_buttons_sensitive(GNOME_DRUID(info->druid),
+                                      TRUE, FALSE, TRUE, TRUE);
+}
+
+static void
+child_exit_cb(GPid pid, gint status, gpointer data)
+{
+    DeferredInfo *deferred_info = data;
+    ABInitialInfo *info = deferred_info->initial_info;
+    gint exit_status;
+
+#ifdef G_OS_WIN32
+    exit_status = status;
+#else
+    exit_status = WEXITSTATUS(status);
+#endif
+
+    g_spawn_close_pid(pid);
+
+    if (!info) {
+        g_message("Online Banking wizard exited, but the druid has been "
+                  "destroyed already");
+        goto cleanup_child_exit_cb;
+    }
+
+    if (exit_status == 0) {
+        druid_enable_next_button(info);
+    } else {
+        if (deferred_info->qt_probably_unavailable) {
+            g_warning("on_aqhbci_button: Oops, aqhbci wizard return nonzero "
+                      "value: %d. The called program was \"%s\".\n",
+                      exit_status, deferred_info->wizard_path);
+            gnc_error_dialog
+                (info->window,
+                 _("The external program \"AqBanking Setup Wizard\" failed "
+                   "to run successfully because the "
+                   "additional software \"Qt\" was not found.  "
+                   "Please install the \"Qt/Windows Open Source Edition\" "
+                   "from Trolltech by downloading it from www.trolltech.com"
+                   "\n\n"
+                   "If you have installed Qt already, you will have to adapt "
+                   "the PATH variable of your system appropriately.  "
+                   "Contact the GnuCash developers if you need further "
+                   "assistance on how to install Qt correctly."
+                   "\n\n"
+                   "Online Banking cannot be setup without Qt.  Press \"Close\" "
+                   "now, then \"Cancel\" to cancel the Online Banking setup."));
+        } else {
+            g_warning("on_aqhbci_button: Oops, aqhbci wizard return nonzero "
+                      "value: %d. The called program was \"%s\".\n",
+                      exit_status, deferred_info->wizard_path);
+            gnc_error_dialog
+                (info->window,
+                 _("The external program \"AqBanking Setup Wizard\" failed "
+                   "to run successfully.  Online Banking can only be setup "
+                   "if this wizard has run successfully.  "
+                   "Please try running the \"AqBanking Setup Wizard\" again."));
+        }
+        druid_disable_next_button(info);
+    }
+
+cleanup_child_exit_cb:
+    g_free(deferred_info->wizard_path);
+    g_free(deferred_info);
+    if (info)
+        info->deferred_info = NULL;
+}
+
+static gchar *
+ab_account_longname(const AB_ACCOUNT *ab_acc)
+{
+    gchar *bankname;
+    gchar *result;
+    const char *bankcode;
+
+    g_return_val_if_fail(ab_acc, NULL);
+
+    bankname = gnc_utf8_strip_invalid_strdup(AB_Account_GetBankName(ab_acc));
+    bankcode = AB_Account_GetBankCode(ab_acc);
+
+    /* Translators: Strings are 1. Account code, 2. Bank name, 3. Bank code. */
+    if (bankname && *bankname)
+        result = g_strdup_printf(_("%s at %s (code %s)"),
+                                 AB_Account_GetAccountNumber(ab_acc),
+                                 bankname,
+                                 bankcode);
+    else
+        result = g_strdup_printf(_("%s at bank code %s"),
+                                 AB_Account_GetAccountNumber(ab_acc),
+                                 bankcode);
+    g_free(bankname);
+
+    return result;
+
+}
+
+static AB_ACCOUNT *
+update_account_list_acc_cb(AB_ACCOUNT *ab_acc, gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+    gchar *gnc_name, *ab_name;
+    Account *gnc_acc;
+    GtkTreeIter iter;
+
+    g_return_val_if_fail(ab_acc && info, NULL);
+
+    ab_name = ab_account_longname(ab_acc);
+
+    /* Get corresponding gnucash account */
+    gnc_acc = g_hash_table_lookup(info->gnc_hash, ab_acc);
+
+    /* Build the text for the gnucash account. */
+    if (gnc_acc)
+        gnc_name = xaccAccountGetFullName(gnc_acc);
+    else
+        gnc_name = g_strdup("");
+
+    /* Add item to the list store */
+    gtk_list_store_append(info->account_store, &iter);
+    gtk_list_store_set(info->account_store, &iter,
+                       ACCOUNT_LIST_COL_AB_NAME, ab_name,
+                       ACCOUNT_LIST_COL_AB_ACCT, ab_acc,
+                       ACCOUNT_LIST_COL_GNC_NAME, gnc_name,
+                       ACCOUNT_LIST_COL_CHECKED, FALSE,
+                       -1);
+
+    g_free(gnc_name);
+    g_free(ab_name);
+    return NULL;
+}
+
+static void
+update_account_list(ABInitialInfo *info)
+{
+    AB_ACCOUNT_LIST2 *acclist;
+
+    g_return_if_fail(info && info->api && info->gnc_hash);
+
+    /* Detach model from view while updating */
+    g_object_ref(info->account_store);
+    gtk_tree_view_set_model(info->account_view, NULL);
+
+    /* Refill the list */
+    gtk_list_store_clear(info->account_store);
+    acclist = AB_Banking_GetAccounts(info->api);
+    if (acclist)
+        AB_Account_List2_ForEach(acclist, update_account_list_acc_cb, info);
+    else
+        g_warning("update_account_list: Oops, account list from AB_Banking "
+                  "is NULL");
+
+    /* Attach model to view again */
+    gtk_tree_view_set_model(info->account_view,
+                            GTK_TREE_MODEL(info->account_store));
+    g_object_unref(info->account_store);
+}
+
+static gboolean
+find_gnc_acc_cb(gpointer key, gpointer value, gpointer user_data)
+{
+    RevLookupData *data = user_data;
+
+    g_return_val_if_fail(data, TRUE);
+
+    if (value == data->gnc_acc) {
+        data->ab_acc = (AB_ACCOUNT*) key;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static gboolean
+clear_line_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
+              gpointer user_data)
+{
+    RevLookupData *data = user_data;
+    GtkListStore *store = GTK_LIST_STORE(model);
+    gpointer ab_acc;
+
+    g_return_val_if_fail(data && store, FALSE);
+
+    gtk_tree_model_get(model, iter, ACCOUNT_LIST_COL_AB_ACCT, &ab_acc, -1);
+
+    if (ab_acc == data->ab_acc) {
+        gtk_list_store_set(store, iter, ACCOUNT_LIST_COL_GNC_NAME, "",
+                           ACCOUNT_LIST_COL_CHECKED, TRUE, -1);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static void
+account_list_changed_cb(GtkTreeSelection *selection, gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    AB_ACCOUNT *ab_acc;
+    gchar *longname, *gnc_name;
+    Account *old_value, *gnc_acc;
+    const gchar *currency;
+    gnc_commodity *commodity = NULL;
+    gboolean ok_pressed;
+
+    g_return_if_fail(info);
+
+    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
+        return;
+    gtk_tree_model_get(model, &iter, ACCOUNT_LIST_COL_AB_ACCT, &ab_acc, -1);
+
+    /* Avoid recursion when unselecting the item again */
+    g_signal_handlers_block_by_func(selection, account_list_changed_cb, info);
+    gtk_tree_selection_unselect_iter(selection, &iter);
+    g_signal_handlers_unblock_by_func(selection, account_list_changed_cb, info);
+
+    if (ab_acc) {
+        old_value = g_hash_table_lookup(info->gnc_hash, ab_acc);
+
+        longname = ab_account_longname(ab_acc);
+        currency = AB_Account_GetCurrency(ab_acc);
+        if (currency && *currency) {
+            commodity = gnc_commodity_table_lookup(
+                gnc_commodity_table_get_table(gnc_get_current_book()),
+                GNC_COMMODITY_NS_CURRENCY,
+                currency);
+        }
+
+        gnc_acc = gnc_import_select_account(info->window, NULL, TRUE,
+                                            longname, commodity, ACCT_TYPE_BANK,
+                                            old_value, &ok_pressed);
+        g_free(longname);
+
+        if (ok_pressed && old_value != gnc_acc) {
+            if (gnc_acc) {
+                RevLookupData data;
+
+                /* Lookup and clear other mappings to gnc_acc */
+                data.gnc_acc = gnc_acc;
+                data.ab_acc = NULL;
+                g_hash_table_find(info->gnc_hash, (GHRFunc) find_gnc_acc_cb,
+                                  &data);
+                if (data.ab_acc) {
+                    g_hash_table_remove(info->gnc_hash, data.ab_acc);
+                    gtk_tree_model_foreach(
+                        GTK_TREE_MODEL(info->account_store),
+                        (GtkTreeModelForeachFunc) clear_line_cb,
+                        &data);
+                }
+
+                /* Map ab_acc to gnc_acc */
+                g_hash_table_insert(info->gnc_hash, ab_acc, gnc_acc);
+                gnc_name = xaccAccountGetFullName(gnc_acc);
+                gtk_list_store_set(info->account_store, &iter,
+                                   ACCOUNT_LIST_COL_GNC_NAME, gnc_name,
+                                   ACCOUNT_LIST_COL_CHECKED, TRUE,
+                                   -1);
+                g_free(gnc_name);
+
+            } else {
+                g_hash_table_remove(info->gnc_hash, ab_acc);
+                gtk_list_store_set(info->account_store, &iter,
+                                   ACCOUNT_LIST_COL_GNC_NAME, "",
+                                   ACCOUNT_LIST_COL_CHECKED, TRUE,
+                                   -1);
+            }
+        }
+    }
+}
+
+static void
+clear_kvp_acc_cb(Account *gnc_acc, gpointer user_data)
+{
+    if (gnc_ab_get_account_uid(gnc_acc))
+        gnc_ab_set_account_uid(gnc_acc, 0);
+    if (gnc_ab_get_account_accountid(gnc_acc))
+        gnc_ab_set_account_accountid(gnc_acc, "");
+    if (gnc_ab_get_account_bankcode(gnc_acc))
+        gnc_ab_set_account_bankcode(gnc_acc, "");
+}
+
+static void
+save_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data)
+{
+    AB_ACCOUNT *ab_acc = key;
+    Account *gnc_acc = value;
+    guint32 ab_account_uid;
+    const gchar *ab_accountid, *gnc_accountid;
+    const gchar *ab_bankcode, *gnc_bankcode;
+
+    g_return_if_fail(ab_acc && gnc_acc);
+
+    ab_account_uid = AB_Account_GetUniqueId(ab_acc);
+    if (gnc_ab_get_account_uid(gnc_acc) != ab_account_uid)
+        gnc_ab_set_account_uid(gnc_acc, ab_account_uid);
+
+    ab_accountid = AB_Account_GetAccountNumber(ab_acc);
+    gnc_accountid = gnc_ab_get_account_accountid(gnc_acc);
+    if (ab_accountid
+        && (!gnc_accountid
+            || (strcmp(ab_accountid, gnc_accountid) != 0)))
+        gnc_ab_set_account_accountid(gnc_acc, ab_accountid);
+
+    ab_bankcode = AB_Account_GetBankCode(ab_acc);
+    gnc_bankcode = gnc_ab_get_account_bankcode(gnc_acc);
+    if (ab_bankcode
+        && (!gnc_bankcode
+            || (strcmp(gnc_bankcode, ab_bankcode) != 0)))
+        gnc_ab_set_account_bankcode(gnc_acc, ab_bankcode);
+}
+
+static void
+cm_close_handler(gpointer user_data)
+{
+    ABInitialInfo *info = user_data;
+
+    gtk_widget_destroy(info->window);
+}
+
+void
+gnc_ab_initial_druid(void)
+{
+    ABInitialInfo *info;
+    GladeXML *xml;
+    GtkTreeViewColumn *column;
+    GtkTreeSelection *selection;
+    gint component_id;
+
+    info = g_new0(ABInitialInfo, 1);
+
+    xml = gnc_glade_xml_new("aqbanking.glade", "AqBanking Init Druid");
+
+    info->window = glade_xml_get_widget(xml, "AqBanking Init Druid");
+    g_object_set_data_full(G_OBJECT(info->window), "xml", xml, g_object_unref);
+    glade_xml_signal_autoconnect_full(xml, gnc_glade_autoconnect_full_func,
+                                      info);
+
+    info->druid = glade_xml_get_widget(xml, "ab_init_druid");
+    gnc_druid_set_colors(GNOME_DRUID(info->druid));
+
+    info->api = gnc_AB_BANKING_new();
+    info->deferred_info = NULL;
+    info->gnc_hash = NULL;
+
+    info->match_page_prepared = FALSE;
+    info->account_view =
+        GTK_TREE_VIEW(glade_xml_get_widget(xml, "account_page_view"));
+    info->account_store = gtk_list_store_new(NUM_ACCOUNT_LIST_COLS,
+                                             G_TYPE_INT, G_TYPE_STRING,
+                                             G_TYPE_POINTER, G_TYPE_STRING,
+                                             G_TYPE_BOOLEAN);
+    gtk_tree_view_set_model(info->account_view,
+                            GTK_TREE_MODEL(info->account_store));
+    g_object_unref(info->account_store);
+
+    column = gtk_tree_view_column_new_with_attributes(
+        _("Online Banking Account Name"), gtk_cell_renderer_text_new(),
+        "text", ACCOUNT_LIST_COL_AB_NAME, (gchar*) NULL);
+    gtk_tree_view_append_column(info->account_view, column);
+
+    column = gtk_tree_view_column_new_with_attributes(
+        _("GnuCash Account Name"), gtk_cell_renderer_text_new(),
+        "text", ACCOUNT_LIST_COL_GNC_NAME, (gchar*) NULL);
+    gtk_tree_view_column_set_expand(column, TRUE);
+    gtk_tree_view_append_column(info->account_view, column);
+
+    column = gtk_tree_view_column_new_with_attributes(
+        _("New?"), gtk_cell_renderer_toggle_new(),
+        "active", ACCOUNT_LIST_COL_CHECKED, (gchar*) NULL);
+    gtk_tree_view_append_column(info->account_view, column);
+
+    selection = gtk_tree_view_get_selection(info->account_view);
+    g_signal_connect(selection, "changed",
+                     G_CALLBACK(account_list_changed_cb), info);
+
+    component_id = gnc_register_gui_component(DRUID_AB_INITIAL_CM_CLASS,
+                                              NULL, cm_close_handler, info);
+    gnc_gui_component_set_session(component_id, gnc_get_current_session());
+
+    gtk_widget_show(info->window);
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/druid-ab-initial.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/druid-ab-initial.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/druid-ab-initial.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,51 @@
+/*
+ * druid-ab-initial.h -- aqbanking creation functionality
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file druid-ab-initial.h
+ * @brief AqBanking setup functionality
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef DRUID_AB_INITIAL_H
+#define DRUID_AB_INITIAL_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ * Create and show a druid for the aqbanking setup.
+ */
+void gnc_ab_initial_druid(void);
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* DRUID_AB_INITIAL_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-getbalance.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-getbalance.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-getbalance.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,121 @@
+/*
+ * gnc-ab-getbalance.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-ab-getbalance.c
+ * @brief AqBanking getbalance functions
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <aqbanking/banking.h>
+#include <aqbanking/jobgetbalance.h>
+
+#include "gnc-ab-getbalance.h"
+#include "gnc-ab-kvp.h"
+#include "gnc-ab-utils.h"
+#include "gnc-gwen-gui.h"
+#include "gnc-ui.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+void
+gnc_ab_getbalance(GtkWidget *parent, Account *gnc_acc)
+{
+    AB_BANKING *api;
+    gboolean online = FALSE;
+    AB_ACCOUNT *ab_acc;
+    AB_JOB *job = NULL;
+    AB_JOB_LIST2 *job_list = NULL;
+    GncGWENGui *gui = NULL;
+    AB_IMEXPORTER_CONTEXT *context = NULL;
+    GncABImExContextImport *ieci = NULL;
+
+    g_return_if_fail(parent && gnc_acc);
+
+    /* Get the API */
+    api = gnc_AB_BANKING_new();
+    if (!api) {
+        g_warning("gnc_ab_gettrans: Couldn't get AqBanking API");
+        return;
+    }
+    if (AB_Banking_OnlineInit(api) != 0) {
+        g_warning("gnc_ab_gettrans: Couldn't initialize AqBanking API");
+        goto cleanup;
+    }
+    online = TRUE;
+
+    /* Get the AqBanking Account */
+    ab_acc = gnc_ab_get_ab_account(api, gnc_acc);
+    if (!ab_acc) {
+        g_warning("gnc_ab_getbalance: No AqBanking account found");
+        goto cleanup;
+    }
+
+    /* Get a GetBalance job and enqueue it */
+    job = AB_JobGetBalance_new(ab_acc);
+    if (!job || AB_Job_CheckAvailability(job, 0)) {
+        g_warning("gnc_ab_getbalance: JobGetBalance not available for this "
+                  "account");
+        goto cleanup;
+    }
+    job_list = AB_Job_List2_new();
+    AB_Job_List2_PushBack(job_list, job);
+
+    /* Get a GUI object */
+    gui = gnc_GWEN_Gui_get(parent);
+    if (!gui) {
+        g_warning("gnc_ab_getbalance: Couldn't initialize Gwenhywfar GUI");
+        goto cleanup;
+    }
+
+    /* Create a context to store the results */
+    context = AB_ImExporterContext_new();
+
+    /* Execute the job */
+    if (AB_Banking_ExecuteJobs(api, job_list, context, 0)) {
+        g_warning("gnc_ab_getbalance: Error on executing job");
+        goto cleanup;
+    }
+
+    /* Import the results */
+    ieci = gnc_ab_import_context(context, AWAIT_BALANCES, FALSE, NULL, parent);
+
+cleanup:
+    if (ieci)
+        g_free(ieci);
+    if (context)
+        AB_ImExporterContext_free(context);
+    if (gui)
+        gnc_GWEN_Gui_release(gui);
+    if (job_list)
+        AB_Job_List2_free(job_list);
+    if (job)
+        AB_Job_free(job);
+    if (online)
+        AB_Banking_OnlineFini(api);
+    gnc_AB_BANKING_fini(api);
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-getbalance.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-getbalance.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-getbalance.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,53 @@
+/*
+ * gnc-ab-get-balance.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-ab-getbalance.h
+ * @brief AqBanking getbalance functions
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_AB_GETBALANCE_H
+#define GNC_AB_GETBALANCE_H
+
+#include <gtk/gtk.h>
+
+#include "Account.h"
+
+G_BEGIN_DECLS
+
+/**
+ * Execute a GetBalance job, show the resulting balance and offer to reconcile
+ * the GnuCash account.
+ *
+ * @param parent Widget to use as parent, may be NULL
+ * @param gnc_acc GnuCash account to fetch balance for
+ */
+void gnc_ab_getbalance(GtkWidget *parent, Account *gnc_acc);
+
+G_END_DECLS
+
+#endif /* GNC_AB_GETBALANCE_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-gettrans.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-gettrans.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-gettrans.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,209 @@
+/*
+ * gnc-ab-gettrans.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-ab-gettrans.c
+ * @brief AqBanking get transactions functions
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <aqbanking/banking.h>
+#include <aqbanking/jobgettransactions.h>
+
+#include "Account.h"
+#include "dialog-daterange.h"
+#include "gnc-ab-gettrans.h"
+#include "gnc-ab-kvp.h"
+#include "gnc-ab-utils.h"
+#include "gnc-gwen-gui.h"
+#include "import-main-matcher.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+typedef struct _TransListData TransListData;
+
+static gboolean gettrans_dates(GtkWidget *parent, Account *gnc_acc, GWEN_TIME **from_date, GWEN_TIME **to_date);
+
+struct _TransListData {
+    Account *gnc_acc;
+    GNCImportMainMatcher *importer_generic;
+};
+
+static gboolean
+gettrans_dates(GtkWidget *parent, Account *gnc_acc,
+               GWEN_TIME **from_date, GWEN_TIME **to_date)
+{
+    Timespec last_timespec, until_timespec;
+    time_t now = time(NULL);
+    gboolean use_last_date = TRUE;
+    gboolean use_earliest_date = TRUE;
+    gboolean use_until_now = TRUE;
+
+    g_return_val_if_fail(from_date && to_date, FALSE);
+
+    /* Get time of last retrieval */
+    last_timespec = gnc_ab_get_account_trans_retrieval(gnc_acc);
+    if (last_timespec.tv_sec == 0) {
+        use_last_date = FALSE;
+        timespecFromTime_t(&last_timespec, now);
+    }
+    timespecFromTime_t(&until_timespec, now);
+
+    /* Let the user choose the date range of retrieval */
+    if (!gnc_ab_enter_daterange(parent, NULL,
+                                &last_timespec,
+                                &use_last_date, &use_earliest_date,
+                                &until_timespec, &use_until_now))
+        return FALSE;
+
+    /* Now calculate from date */
+    if (use_earliest_date) {
+        *from_date = NULL;
+    } else {
+        if (use_last_date)
+            last_timespec = gnc_ab_get_account_trans_retrieval(gnc_acc);
+        *from_date = GWEN_Time_fromSeconds(timespecToTime_t(last_timespec));
+    }
+
+    /* Now calculate to date */
+    if (use_until_now)
+        timespecFromTime_t(&until_timespec, now);
+    *to_date = GWEN_Time_fromSeconds(timespecToTime_t(until_timespec));
+
+    return TRUE;
+}
+
+void
+gnc_ab_gettrans(GtkWidget *parent, Account *gnc_acc)
+{
+    AB_BANKING *api;
+    gboolean online = FALSE;
+    AB_ACCOUNT *ab_acc;
+    GWEN_TIME *from_date = NULL, *to_date = NULL;
+    Timespec until_timespec;
+    AB_JOB *job = NULL;
+    AB_JOB_LIST2 *job_list = NULL;
+    GncGWENGui *gui = NULL;
+    AB_IMEXPORTER_CONTEXT *context = NULL;
+    GncABImExContextImport *ieci = NULL;
+
+    g_return_if_fail(parent && gnc_acc);
+
+    /* Get the API */
+    api = gnc_AB_BANKING_new();
+    if (!api) {
+        g_warning("gnc_ab_gettrans: Couldn't get AqBanking API");
+        return;
+    }
+    if (AB_Banking_OnlineInit(api) != 0) {
+        g_warning("gnc_ab_gettrans: Couldn't initialize AqBanking API");
+        goto cleanup;
+    }
+    online = TRUE;
+
+    /* Get the AqBanking Account */
+    ab_acc = gnc_ab_get_ab_account(api, gnc_acc);
+    if (!ab_acc) {
+        g_warning("gnc_ab_gettrans: No AqBanking account found");
+        goto cleanup;
+    }
+
+    /* Get the start and end dates for the GetTransactions job.  */
+    if (!gettrans_dates(parent, gnc_acc, &from_date, &to_date)) {
+        g_debug("gnc_ab_gettrans: gettrans_dates aborted");
+        goto cleanup;
+    }
+    /* Use this as a local storage for the until_time below. */
+    timespecFromTime_t(&until_timespec, GWEN_Time_toTime_t(to_date));
+
+    /* Get a GetTransactions job and enqueue it */
+    job = AB_JobGetTransactions_new(ab_acc);
+    if (!job || AB_Job_CheckAvailability(job, 0)) {
+        g_warning("gnc_ab_gettrans: JobGetTransactions not available for this "
+                  "account");
+        goto cleanup;
+    }
+    AB_JobGetTransactions_SetFromTime(job, from_date);
+    AB_JobGetTransactions_SetToTime(job, to_date);
+    job_list = AB_Job_List2_new();
+    AB_Job_List2_PushBack(job_list, job);
+
+    /* Get a GUI object */
+    gui = gnc_GWEN_Gui_get(parent);
+    if (!gui) {
+        g_warning("gnc_ab_gettrans: Couldn't initialize Gwenhywfar GUI");
+        goto cleanup;
+    }
+
+    /* Create a context to store the results */
+    context = AB_ImExporterContext_new();
+
+    /* Execute the job */
+    if (AB_Banking_ExecuteJobs(api, job_list, context, 0)) {
+        g_warning("gnc_ab_gettrans: Error on executing job");
+        goto cleanup;
+    }
+
+    /* Import the results */
+    ieci = gnc_ab_import_context(context, AWAIT_TRANSACTIONS, FALSE, NULL,
+                                 parent);
+    if (!(gnc_ab_ieci_get_found(ieci) & FOUND_TRANSACTIONS)) {
+        /* No transaction found */
+        GtkWidget *dialog = gtk_message_dialog_new(
+            GTK_WINDOW(parent),
+            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+            GTK_MESSAGE_INFO,
+            GTK_BUTTONS_OK,
+            "%s",
+            _("The Online Banking import returned no transactions "
+              "for the selected time period."));
+        gtk_dialog_run(GTK_DIALOG(dialog));
+        gtk_widget_destroy(dialog);
+    }
+
+    /* Store the date of this retrieval */
+    gnc_ab_set_account_trans_retrieval(gnc_acc, until_timespec);
+
+cleanup:
+    if (ieci)
+        g_free(ieci);
+    if (context)
+        AB_ImExporterContext_free(context);
+    if (gui)
+        gnc_GWEN_Gui_release(gui);
+    if (job_list)
+        AB_Job_List2_free(job_list);
+    if (job)
+        AB_Job_free(job);
+    if (to_date)
+        GWEN_Time_free(to_date);
+    if (from_date)
+        GWEN_Time_free(from_date);
+    if (online)
+        AB_Banking_OnlineFini(api);
+    gnc_AB_BANKING_fini(api);
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-gettrans.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-gettrans.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-gettrans.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,50 @@
+/*
+ * gnc-ab-get-balance.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-ab-getbalance.h
+ * @brief AqBanking getbalance functions
+ * @author Copyright (C) 2002 Christian Stimming
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_AB_GETTRANS_H
+#define GNC_AB_GETTRANS_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ * Execute a GetTransactions job.
+ *
+ * @param parent Widget to use as parent, may be NULL
+ * @param gnc_acc GnuCash account to fetch transactions for
+ */
+void gnc_ab_gettrans(GtkWidget *parent, Account *gnc_acc);
+
+G_END_DECLS
+
+#endif /* GNC_AB_GETTRANS_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-kvp.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-kvp.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-kvp.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,176 @@
+/*
+ * gnc-ab-kvp.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-ab-kvp.c
+ * @brief AqBanking KVP handling
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include "gnc-ab-kvp.h"
+
+#define AB_KEY "hbci"
+#define AB_ACCOUNT_ID "account-id"
+#define AB_ACCOUNT_UID "account-uid"
+#define AB_BANK_CODE "bank-code"
+#define AB_TRANS_RETRIEVAL "trans-retrieval"
+#define AB_TEMPLATES "template-list"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+static void force_account_dirty(Account *acct);
+static kvp_frame *gnc_ab_get_account_kvp(const Account *a, gboolean create);
+static kvp_frame *gnc_ab_get_book_kvp(QofBook *b, gboolean create);
+
+G_CONST_RETURN gchar *
+gnc_ab_get_account_accountid(const Account *a)
+{
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_ACCOUNT_ID);
+    return kvp_value_get_string(value);
+}
+
+void
+gnc_ab_set_account_accountid(Account *a, const gchar *id)
+{
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
+    kvp_value *value = kvp_value_new_string(id);
+    xaccAccountBeginEdit(a);
+    kvp_frame_set_slot_nc(frame, AB_ACCOUNT_ID, value);
+    force_account_dirty(a);
+    xaccAccountCommitEdit(a);
+}
+
+G_CONST_RETURN gchar *
+gnc_ab_get_account_bankcode(const Account *a)
+{
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_BANK_CODE);
+    return kvp_value_get_string(value);
+}
+
+void
+gnc_ab_set_account_bankcode(Account *a, const gchar *code)
+{
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
+    kvp_value *value = kvp_value_new_string(code);
+    xaccAccountBeginEdit(a);
+    kvp_frame_set_slot_nc(frame, AB_BANK_CODE, value);
+    force_account_dirty(a);
+    xaccAccountCommitEdit(a);
+}
+
+guint32
+gnc_ab_get_account_uid(const Account *a)
+{
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_ACCOUNT_UID);
+    return (guint32) kvp_value_get_gint64(value);
+}
+
+void
+gnc_ab_set_account_uid(Account *a, guint32 uid)
+{
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
+    kvp_value *value = kvp_value_new_gint64(uid);
+    xaccAccountBeginEdit(a);
+    kvp_frame_set_slot_nc(frame, AB_ACCOUNT_UID, value);
+    force_account_dirty(a);
+    xaccAccountCommitEdit(a);
+}
+
+Timespec
+gnc_ab_get_account_trans_retrieval(const Account *a)
+{
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_TRANS_RETRIEVAL);
+    return kvp_value_get_timespec(value);
+}
+
+void
+gnc_ab_set_account_trans_retrieval(Account *a, Timespec time)
+{
+    kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
+    kvp_value *value = kvp_value_new_timespec(time);
+    xaccAccountBeginEdit(a);
+    kvp_frame_set_slot_nc(frame, AB_TRANS_RETRIEVAL, value);
+    force_account_dirty(a);
+    xaccAccountCommitEdit(a);
+}
+
+GList *
+gnc_ab_get_book_template_list(QofBook *b)
+{
+    kvp_frame *frame = gnc_ab_get_book_kvp(b, FALSE);
+    kvp_value *value = kvp_frame_get_slot(frame, AB_TEMPLATES);
+    return kvp_value_get_glist(value);
+}
+
+void
+gnc_ab_set_book_template_list(QofBook *b, GList *template_list)
+{
+    kvp_frame *frame = gnc_ab_get_book_kvp(b, TRUE);
+    kvp_value *value = kvp_value_new_glist_nc(template_list);
+    kvp_frame_set_slot_nc(frame, AB_TEMPLATES, value);
+    qof_book_kvp_changed(b);
+}
+
+static void
+force_account_dirty(Account *acct)
+{
+    gchar *name = g_strdup(xaccAccountGetName(acct));
+
+    /* This is necessary because modifying the KvpFrames doesn't mark
+     * accounts dirty, which means the changes wont be propagated to the
+     * backend.
+     */
+    xaccAccountSetName(acct, name);
+    g_free(name);
+}
+
+static kvp_frame *
+gnc_ab_get_account_kvp(const Account *a, gboolean create)
+{
+    kvp_frame *toplevel = xaccAccountGetSlots(a);
+    kvp_frame *result = kvp_frame_get_frame(toplevel, AB_KEY);
+    if (!result && create) {
+        result = kvp_frame_new();
+        kvp_frame_add_frame_nc(toplevel, AB_KEY, result);
+    }
+    return result;
+}
+
+static kvp_frame *
+gnc_ab_get_book_kvp(QofBook *b, gboolean create)
+{
+    kvp_frame *toplevel = qof_book_get_slots(b);
+    kvp_frame *result = kvp_frame_get_frame(toplevel, AB_KEY);
+    if (!result && create) {
+        result = kvp_frame_new();
+        kvp_frame_add_frame_nc(toplevel, AB_KEY, result);
+    }
+    return result;
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-kvp.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-kvp.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-kvp.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,148 @@
+/*
+ * gnc-ab-kvp.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-ab-kvp.h
+ * @brief AqBanking KVP handling
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_AB_KVP_H
+#define GNC_AB_KVP_H
+
+#include <glib.h>
+
+#include "Account.h"
+
+G_BEGIN_DECLS
+
+/** @name Account
+ *  @{ */
+
+/**
+ * Return a non-copied pointer to the accountid string in the Account @a a.
+ * The gchar* is still owned by the kvp_frame, so don't free it until you want
+ * to delete the whole kvp_frame.
+ *
+ * @param a Account
+ * @return Account ID
+ */
+const gchar *gnc_ab_get_account_accountid(const Account *a);
+
+/**
+ * Set the accountid string in the Account @a a to @a id.  A copy of the string
+ * will be stored.  The Account will be marked as "dirty".
+ *
+ * @param a Account
+ * @param id Account ID
+ */
+void gnc_ab_set_account_accountid(Account *a, const gchar *id);
+
+/**
+ * Return a non-copied pointer to the bankcode string in the Account @a a.  The
+ * gchar* is still owned by the kvp_frame, so don't free it until you want to
+ * delete the whole kvp_frame.
+ *
+ * @param a Account
+ * @return Bank code
+ */
+const gchar *gnc_ab_get_account_bankcode(const Account *a);
+
+/**
+ * Set the bankcode string in the Account @a a to @a code.  A copy of the string
+ * will be stored.  The Account will be marked as "dirty".
+ *
+ * @param a Account
+ * @param code Bank code
+ */
+void gnc_ab_set_account_bankcode(Account *a, const gchar *code);
+
+/**
+ * Return the unique id for the AB_BANKING account in the Account @a a.
+ *
+ * @param a Account
+ * @return Unique ID
+ */
+guint32 gnc_ab_get_account_uid(const Account *a);
+
+/**
+ * Set the unique id for the AB_BANKING account in the Account @a a to @a uid.
+ * The Account will be marked as "dirty".
+ *
+ * @param a Account
+ * @param uid Unique ID
+ */
+void gnc_ab_set_account_uid(Account *a, guint32 uid);
+
+/**
+ * Return the time of last online transaction retrieval for Account @a a.
+ *
+ * @param a Account
+ * @return Retrieval time
+ */
+Timespec gnc_ab_get_account_trans_retrieval(const Account *a);
+
+/**
+ * Set the time of last online transaction retrieval for Account @a a.  The
+ * account will be marked as "dirty".
+ *
+ * @param a Account
+ * @param time Retrieval time
+ */
+void gnc_ab_set_account_trans_retrieval(Account *a, Timespec time);
+
+/** @} */
+
+/** @name Book
+ *  @{ */
+
+/**
+ * Return a non-copied pointer to the GList of kvp_frames which eventually are
+ * the template transactions, stored in the given book.
+ *
+ * @param b Book
+ * @return Template list
+ */
+GList *gnc_ab_get_book_template_list(QofBook *b);
+
+/**
+ * Set the GList of kvp_frames of template transactions in the Book @a b to @a
+ * template_list.  No copy of the GList will be stored, the callee becomes the
+ * owner and the caller must not free it.  The book will be marked "dirty".
+ *
+ * @param b Book
+ * @param template_list Template list
+ */
+void gnc_ab_set_book_template_list(QofBook *b, GList *template_list);
+
+/** @} */
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* GNC_AB_KVP_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-trans-templ.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-trans-templ.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-trans-templ.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,285 @@
+/*
+ * gnc-ab-trans-templ.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-ab-trans-templ.c
+ * @brief Templates for AqBanking transactions
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include "gnc-ab-trans-templ.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+/* kvp_frame slot names */
+#define TT_NAME "name"
+#define TT_RNAME "rnam"
+#define TT_RACC "racc"
+#define TT_RBCODE "rbcd"
+#define TT_PURPOS "purp"
+#define TT_PURPOSCT "purc"
+#define TT_AMOUNT "amou"
+
+struct _GncABTransTempl
+{
+  /* Name of this Template */
+  gchar *name;
+  gchar *name_key; /* Collation key */
+
+  /* Recipient */
+  gchar *recp_name;
+  gchar *recp_account;
+  gchar *recp_bankcode;
+
+  /* Amount */
+  gnc_numeric amount;
+
+  /* Purpose, description */
+  gchar *purpose;
+  gchar *purpose_cont;
+};
+
+
+GncABTransTempl *
+gnc_ab_trans_templ_new(void)
+{
+    return gnc_ab_trans_templ_new_full(NULL, NULL, NULL, NULL,
+                                       gnc_numeric_zero(), NULL, NULL);
+}
+
+GncABTransTempl *
+gnc_ab_trans_templ_new_full(const char *name, const char *recp_name,
+                            const char *recp_account, const char *recp_bankcode,
+                            gnc_numeric amount, const char *purpose,
+                            const char *purpose_cont)
+{
+    GncABTransTempl *r = g_new(GncABTransTempl, 1);
+    r->name = g_strdup(name);
+    r->name_key = g_utf8_collate_key(name, -1);
+    r->recp_name = g_strdup(recp_name);
+    r->recp_account = g_strdup(recp_account);
+    r->recp_bankcode = g_strdup(recp_bankcode);
+    r->amount = amount;
+    r->purpose = g_strdup(purpose);
+    r->purpose_cont = g_strdup(purpose_cont);
+
+    return r;
+}
+
+GncABTransTempl *
+gnc_ab_trans_templ_new_from_kvp(const kvp_frame *k)
+{
+    g_return_val_if_fail(k, NULL);
+
+    return gnc_ab_trans_templ_new_full(
+        kvp_value_get_string(kvp_frame_get_slot(k, TT_NAME)),
+        kvp_value_get_string(kvp_frame_get_slot(k, TT_RNAME)),
+        kvp_value_get_string(kvp_frame_get_slot(k, TT_RACC)),
+        kvp_value_get_string(kvp_frame_get_slot(k, TT_RBCODE)),
+        kvp_value_get_numeric(kvp_frame_get_slot(k, TT_AMOUNT)),
+        kvp_value_get_string(kvp_frame_get_slot(k, TT_PURPOS)),
+        kvp_value_get_string(kvp_frame_get_slot(k, TT_PURPOSCT)));
+}
+
+GList *
+gnc_ab_trans_templ_list_new_from_kvp_list(GList *v)
+{
+    GList *res = NULL;
+    GList *iter;
+
+    for (iter = v; iter; iter = iter->next) {
+        kvp_frame *frame = kvp_value_get_frame((kvp_value*) iter->data);
+        res = g_list_prepend(res, gnc_ab_trans_templ_new_from_kvp(frame));
+    }
+    res = g_list_reverse(res);
+
+    return res;
+}
+
+void
+gnc_ab_trans_templ_free(GncABTransTempl *t)
+{
+    if (!t) return;
+    g_free(t->name);
+    g_free(t->name_key);
+    g_free(t->recp_name);
+    g_free(t->recp_account);
+    g_free(t->recp_bankcode);
+    g_free(t->purpose);
+    g_free(t->purpose_cont);
+    g_free(t);
+}
+
+void
+gnc_ab_trans_templ_list_free(GList *l)
+{
+    GList *iter;
+    for (iter = l; iter; iter = iter->next)
+        gnc_ab_trans_templ_free((GncABTransTempl*) iter->data);
+    g_list_free(l);
+}
+
+kvp_frame *
+gnc_ab_trans_templ_to_kvp(const GncABTransTempl *t)
+{
+    kvp_frame *k;
+
+    g_return_val_if_fail(t, NULL);
+
+    k = kvp_frame_new();
+    kvp_frame_set_slot(k, TT_NAME, kvp_value_new_string(t->name));
+    kvp_frame_set_slot(k, TT_RNAME, kvp_value_new_string(t->recp_name));
+    kvp_frame_set_slot(k, TT_RACC, kvp_value_new_string(t->recp_account));
+    kvp_frame_set_slot(k, TT_RBCODE, kvp_value_new_string(t->recp_bankcode));
+    kvp_frame_set_slot(k, TT_AMOUNT, kvp_value_new_gnc_numeric(t->amount));
+    kvp_frame_set_slot(k, TT_PURPOS, kvp_value_new_string(t->purpose));
+    kvp_frame_set_slot(k, TT_PURPOSCT, kvp_value_new_string(t->purpose_cont));
+
+    return k;
+}
+
+GList *
+gnc_ab_trans_templ_list_to_kvp_list(GList *k)
+{
+    GList *res = NULL;
+    GList *iter;
+
+    for (iter = k; iter; iter = iter->next) {
+        GncABTransTempl *t = (GncABTransTempl*) iter->data;
+        kvp_value *value = kvp_value_new_frame_nc(gnc_ab_trans_templ_to_kvp(t));
+        res = g_list_prepend(res, value);
+    }
+    res = g_list_reverse(res);
+
+    return res;
+}
+
+const gchar *
+gnc_ab_trans_templ_get_name(const GncABTransTempl *t)
+{
+    g_return_val_if_fail(t, NULL);
+    return t->name;
+}
+
+const gchar *
+gnc_ab_trans_templ_get_recp_name(const GncABTransTempl *t)
+{
+    g_return_val_if_fail(t, NULL);
+    return t->recp_name;
+}
+
+const gchar *
+gnc_ab_trans_templ_get_recp_account(const GncABTransTempl *t)
+{
+    g_return_val_if_fail(t, NULL);
+    return t->recp_account;
+}
+
+const gchar *
+gnc_ab_trans_templ_get_recp_bankcode(const GncABTransTempl *t)
+{
+    g_return_val_if_fail(t, NULL);
+    return t->recp_bankcode;
+}
+
+gnc_numeric
+gnc_ab_trans_templ_get_amount(const GncABTransTempl *t)
+{
+    g_return_val_if_fail(t, gnc_numeric_zero());
+    return t->amount;
+}
+
+const gchar *
+gnc_ab_trans_templ_get_purpose(const GncABTransTempl *t)
+{
+    g_return_val_if_fail(t, NULL);
+    return t->purpose;
+}
+
+const gchar *
+gnc_ab_trans_templ_get_purpose_cont(const GncABTransTempl *t)
+{
+    g_return_val_if_fail(t, NULL);
+    return t->purpose_cont;
+}
+
+void
+gnc_ab_trans_templ_set_name(GncABTransTempl *t, const gchar *name)
+{
+    g_return_if_fail(t);
+    g_free(t->name);
+    t->name = g_strdup(name);
+}
+
+void
+gnc_ab_trans_templ_set_recp_name(GncABTransTempl *t, const gchar *recp_name)
+{
+    g_return_if_fail(t);
+    g_free(t->recp_name);
+    t->recp_name = g_strdup(recp_name);
+}
+
+void
+gnc_ab_trans_templ_set_recp_account(GncABTransTempl *t,
+                                    const gchar *recp_account)
+{
+    g_return_if_fail(t);
+    g_free(t->recp_account);
+    t->recp_account = g_strdup(recp_account);
+}
+
+void
+gnc_ab_trans_templ_set_recp_bankcode(GncABTransTempl *t,
+                                     const gchar *recp_bankcode)
+{
+    g_return_if_fail(t);
+    g_free(t->recp_bankcode);
+    t->recp_bankcode = g_strdup(recp_bankcode);
+}
+
+void
+gnc_ab_trans_templ_set_amount(GncABTransTempl *t, gnc_numeric amount)
+{
+    g_return_if_fail(t);
+    t->amount = amount;
+}
+
+void
+gnc_ab_trans_templ_set_purpose(GncABTransTempl *t, const gchar *purpose)
+{
+    g_return_if_fail(t);
+    g_free(t->purpose);
+    t->purpose = g_strdup(purpose);
+}
+
+void
+gnc_ab_trans_templ_set_purpose_cont(GncABTransTempl *t,
+                                    const gchar *purpose_cont)
+{
+    g_return_if_fail(t);
+    g_free(t->purpose_cont);
+    t->purpose_cont = g_strdup(purpose_cont);
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-trans-templ.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-trans-templ.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-trans-templ.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,221 @@
+/*
+ * gnc-ab-trans-templ.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-ab-trans-templ.h
+ * @brief Templates for AqBanking transactions
+ * @author Copyright (C) 2003 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_AB_TRANS_TEMPL_H
+#define GNC_AB_TRANS_TEMPL_H
+
+#include <glib.h>
+
+#include "qof.h"
+
+G_BEGIN_DECLS
+
+/** A template for an AqBanking transaction */
+typedef struct _GncABTransTempl GncABTransTempl;
+
+/**
+ * Create a template with unset contents.
+ *
+ * @return A newly allocated GncABTransTempl
+ */
+GncABTransTempl *gnc_ab_trans_templ_new(void);
+
+/**
+ * Create a template with given contents.
+ *
+ * @param name Name of the template
+ * @param recp_name Name of the recipient
+ * @param recp_account Account Number of the recipient
+ * @param recp_bankcode Bank Code of the recipient
+ * @param amount Amount
+ * @param purpose First purpose line
+ * @param purpose_cont Second purpose line
+ * @return A newly allocated GncABTransTempl
+ */
+GncABTransTempl *gnc_ab_trans_templ_new_full(
+    const gchar *name, const gchar *recp_name, const gchar *recp_account,
+    const gchar *recp_bankcode, gnc_numeric amount, const gchar *purpose,
+    const gchar *purpose_cont);
+
+/**
+ * Create a template, taking the values from a kvp_frame.
+ *
+ * @param k kvp_frame
+ * @return A newly allocated GncABTransTempl
+ */
+GncABTransTempl *gnc_ab_trans_templ_new_from_kvp(const kvp_frame *k);
+
+/**
+ * Create a list of templates from a list of kvp_values which in turn
+ * contain a kvp_frame.
+ *
+ * @param v GList of kvp_values
+ * @return A GList of newly allocated GncABTransTempls
+ */
+GList *gnc_ab_trans_templ_list_new_from_kvp_list(GList *v);
+
+/**
+ * Free the memory used by a template.
+ *
+ * @param t GncABTransTempl to be freed
+ */
+void gnc_ab_trans_templ_free(GncABTransTempl *t);
+
+/**
+ * Free the memory used by a list of templates, including the list itself.
+ *
+ * @param l GList of GncABTransTempl
+ */
+void gnc_ab_trans_templ_list_free(GList *l);
+
+/**
+ * Create a kvp_frame a given template.
+ *
+ * @param t Template
+ * @return A newly allocated kvp_frame
+ */
+kvp_frame *gnc_ab_trans_templ_to_kvp(const GncABTransTempl *t);
+
+/**
+ * Create a list of kvp_values, which in turn contain a kvp_frame, from a list
+ * of templates.
+ *
+ * @param k GList of GncABTransTempls
+ * @return GList of newly allocated kvp_values
+ */
+GList *gnc_ab_trans_templ_list_to_kvp_list(GList *k);
+
+/**
+ * @param t Template
+ * @return Name of the template, an internal string
+ */
+const gchar *gnc_ab_trans_templ_get_name(const GncABTransTempl *t);
+
+/**
+ * @param t Template
+ * @return Name of the recipient, an internal string
+ */
+const gchar *gnc_ab_trans_templ_get_recp_name(const GncABTransTempl *t);
+
+/**
+ * @param t Template
+ * @return Account Number of the recipient, an internal string
+ */
+const gchar *gnc_ab_trans_templ_get_recp_account(const GncABTransTempl *t);
+
+/**
+ * @param t Template
+ * @return Bank Code of the recipient, an internal string
+ */
+const gchar *gnc_ab_trans_templ_get_recp_bankcode(const GncABTransTempl *t);
+
+/**
+ * @param t Template
+ * @return Amount
+ */
+gnc_numeric gnc_ab_trans_templ_get_amount(const GncABTransTempl *t);
+
+/**
+ * @param t Template
+ * @return First purpose line, an internal string
+ */
+const gchar *gnc_ab_trans_templ_get_purpose(const GncABTransTempl *t);
+
+/**
+ * @param t Template
+ * @return Second purpose line, an internal string
+ */
+const gchar *gnc_ab_trans_templ_get_purpose_cont(const GncABTransTempl *t);
+
+/**
+ * Set the name of a template.
+ *
+ * @param t Template
+ * @param name Name
+ */
+void gnc_ab_trans_templ_set_name(GncABTransTempl *t, const gchar *name);
+
+/**
+ * Replace the Account Number of the recipient stored in a template.
+ *
+ * @param t Template
+ * @param recp_name Account Number of the recipient
+ */
+void gnc_ab_trans_templ_set_recp_name(GncABTransTempl *t,
+                                      const gchar *recp_name);
+
+/**
+ * Replace the Account Number of the recipient stored in a template.
+ *
+ * @param t Template
+ * @param recp_account Account Number of the recipient
+ */
+void gnc_ab_trans_templ_set_recp_account(GncABTransTempl *t,
+                                         const gchar *recp_account);
+
+/**
+ * Replace the Bank Code of the recipient stored in a template.
+ *
+ * @param t Template
+ * @param recp_bankcode Bank Code of the recipient
+ */
+void gnc_ab_trans_templ_set_recp_bankcode(GncABTransTempl *t,
+                                          const gchar *recp_bankcode);
+
+/**
+ * Replace the amount stored in a template.
+ *
+ * @param t Template
+ * @param amount Amount
+ */
+void gnc_ab_trans_templ_set_amount(GncABTransTempl *t, gnc_numeric amount);
+
+/**
+ * Replace the first purpose line stored in a template.
+ *
+ * @param t Template
+ * @param purpose First purpose line
+ */
+void gnc_ab_trans_templ_set_purpose(GncABTransTempl *t, const gchar *purpose);
+
+/**
+ * Replace the second purpose line stored in a template.
+ *
+ * @param t Template
+ * @param purpose_cont Second purpose line
+ */
+void gnc_ab_trans_templ_set_purpose_cont(GncABTransTempl *t,
+                                         const gchar *purpose_cont);
+
+G_END_DECLS
+
+#endif /* GNC_AB_TRANS_TEMPL_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-transfer.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-transfer.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-transfer.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,295 @@
+/*
+ * gnc-ab-transfer.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-ab-utils.c
+ * @brief AqBanking transfer functions
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2004 Bernd Wagner
+ * @author Copyright (C) 2006 David Hampton <hampton at employees.org>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <aqbanking/banking.h>
+
+#include "Transaction.h"
+#include "dialog-transfer.h"
+#include "gnc-ab-transfer.h"
+#include "gnc-ab-kvp.h"
+#include "gnc-ab-utils.h"
+#include "gnc-ab-trans-templ.h"
+#include "gnc-gwen-gui.h"
+#include "gnc-ui.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+static void save_templates(GtkWidget *parent, Account *gnc_acc, GList *templates,
+                           gboolean dont_ask);
+static void txn_created_cb(Transaction *trans, gpointer user_data);
+
+static void
+save_templates(GtkWidget *parent, Account *gnc_acc, GList *templates,
+               gboolean dont_ask)
+{
+    g_return_if_fail(gnc_acc);
+    if (dont_ask || gnc_verify_dialog(
+            parent, FALSE, "%s",
+            _("You have changed the list of online transfer templates, "
+              "but you cancelled the transfer dialog. "
+              "Do you nevertheless want to store the changes?"))) {
+        GList *kvp_list = gnc_ab_trans_templ_list_to_kvp_list(templates);
+        gnc_ab_set_book_template_list(gnc_account_get_book(gnc_acc), kvp_list);
+    }
+}
+
+static void
+txn_created_cb(Transaction *trans, gpointer user_data)
+{
+    Transaction **trans_loc = user_data;
+
+    if (!trans) return;
+    g_return_if_fail(trans_loc);
+    *trans_loc = trans;
+}
+
+void
+gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
+                 GncABTransType trans_type)
+{
+    AB_BANKING *api;
+    gboolean online = FALSE;
+    AB_ACCOUNT *ab_acc;
+    GncABTransDialog *dialog = NULL;
+    GList *templates = NULL;
+    GncABTransDialog *td = NULL;
+    gboolean successful;
+    gboolean aborted = FALSE;
+
+    g_return_if_fail(parent && gnc_acc);
+
+    /* Get the API */
+    api = gnc_AB_BANKING_new();
+    if (!api) {
+        g_warning("gnc_ab_maketrans: Couldn't get AqBanking API");
+        return;
+    }
+    if (AB_Banking_OnlineInit(api) != 0) {
+        g_warning("gnc_ab_maketrans: Couldn't initialize AqBanking API");
+        goto cleanup;
+    }
+    online = TRUE;
+
+    /* Get the AqBanking Account */
+    ab_acc = gnc_ab_get_ab_account(api, gnc_acc);
+    if (!ab_acc) {
+        g_warning("gnc_ab_gettrans: No AqBanking account found");
+        goto cleanup;
+    }
+
+    /* Get list of template transactions */
+    templates = gnc_ab_trans_templ_list_new_from_kvp_list(
+        gnc_ab_get_book_template_list(gnc_account_get_book(gnc_acc)));
+
+    /* Create new ABTransDialog */
+    td = gnc_ab_trans_dialog_new(parent, ab_acc,
+                                 xaccAccountGetCommoditySCU(gnc_acc),
+                                 trans_type, templates);
+    templates = NULL;
+
+    /* Repeat until AqBanking action was successful or user pressed cancel */
+    do {
+        GncGWENGui *gui = NULL;
+        gint result;
+        gboolean changed;
+        const AB_TRANSACTION *ab_trans;
+        AB_JOB *job = NULL;
+        AB_JOB_LIST2 *job_list = NULL;
+        XferDialog *xfer_dialog = NULL;
+        gnc_numeric amount;
+        gchar *description;
+        gchar *memo;
+        Transaction *gnc_trans = NULL;
+        AB_IMEXPORTER_CONTEXT *context = NULL;
+        GncABImExContextImport *ieci = NULL;
+
+        /* Get a GUI object */
+        gui = gnc_GWEN_Gui_get(parent);
+        if (!gui) {
+            g_warning("gnc_ab_maketrans: Couldn't initialize Gwenhywfar GUI");
+            aborted = TRUE;
+            goto repeat;
+        }
+
+        /* Let the user enter the values */
+        result = gnc_ab_trans_dialog_run_until_ok(td);
+
+        if (result != GNC_RESPONSE_NOW && result != GNC_RESPONSE_LATER) {
+            aborted = TRUE;
+            goto repeat;
+        }
+
+        /* Save the templates */
+        templates = gnc_ab_trans_dialog_get_templ(td, &changed);
+        if (changed)
+            save_templates(parent, gnc_acc, templates,
+                           (result == GNC_RESPONSE_NOW));
+        g_list_free(templates);
+        templates = NULL;
+
+        /* Get a job and enqueue it */
+        ab_trans = gnc_ab_trans_dialog_get_ab_trans(td);
+        job = gnc_ab_trans_dialog_get_job(td);
+        if (!job || AB_Job_CheckAvailability(job, 0)) {
+            if (!gnc_verify_dialog(
+                    parent, FALSE, "%s",
+                    _("The backend found an error during the preparation "
+                      "of the job. It is not possible to execute this job. \n"
+                      "\n"
+                      "Most probable the bank does not support your chosen "
+                      "job or your Online Banking account does not have the permission "
+                      "to execute this job. More error messages might be "
+                      "visible on your console log.\n"
+                      "\n"
+                      "Do you want to enter the job again?")))
+                aborted = TRUE;
+            goto repeat;
+        }
+        job_list = AB_Job_List2_new();
+        AB_Job_List2_PushBack(job_list, job);
+
+        /* Setup a Transfer Dialog for the GnuCash transaction */
+        xfer_dialog = gnc_xfer_dialog(gnc_ab_trans_dialog_get_parent(td),
+                                      gnc_acc);
+        switch (trans_type) {
+        case SINGLE_DEBITNOTE:
+            gnc_xfer_dialog_set_title(
+                xfer_dialog, _("Online Banking Direct Debit Note"));
+            gnc_xfer_dialog_lock_to_account_tree(xfer_dialog);
+            break;
+        case SINGLE_INTERNAL_TRANSFER:
+            gnc_xfer_dialog_set_title(
+                xfer_dialog, _("Online Banking Bank-Internal Transfer"));
+            gnc_xfer_dialog_lock_from_account_tree(xfer_dialog);
+            break;
+        case SINGLE_TRANSFER:
+        default:
+            gnc_xfer_dialog_set_title(
+                xfer_dialog, _("Online Banking Transaction"));
+            gnc_xfer_dialog_lock_from_account_tree(xfer_dialog);
+        }
+
+        amount = double_to_gnc_numeric(
+            AB_Value_GetValueAsDouble(AB_Transaction_GetValue(ab_trans)),
+            xaccAccountGetCommoditySCU(gnc_acc),
+            GNC_RND_ROUND);
+        gnc_xfer_dialog_set_amount(xfer_dialog, amount);
+
+        description = gnc_ab_description_to_gnc(ab_trans);
+        gnc_xfer_dialog_set_description(xfer_dialog, description);
+        g_free(description);
+
+        memo = gnc_ab_memo_to_gnc(ab_trans);
+        gnc_xfer_dialog_set_memo(xfer_dialog, memo);
+        g_free(memo);
+
+        gnc_xfer_dialog_set_txn_cb(xfer_dialog, txn_created_cb, &gnc_trans);
+
+        /* And run it */
+        successful = gnc_xfer_dialog_run_until_done(xfer_dialog);
+
+        /* On cancel, go back to the AB transaction dialog */
+        if (!successful || !gnc_trans) {
+            successful = FALSE;
+            goto repeat;
+        }
+
+        if (result == GNC_RESPONSE_NOW) {
+            /* Create a context to store possible results */
+            context = AB_ImExporterContext_new();
+
+            /* Finally, execute the job */
+            successful = AB_Banking_ExecuteJobs(api, job_list, context, 0) == 0;
+
+            if (!successful
+                || AB_Job_GetStatus(job) != AB_Job_StatusFinished) {
+                successful = FALSE;
+                if (!gnc_verify_dialog(
+                        parent, FALSE, "%s",
+                        _("An error occurred while executing the job.  Please check "
+                          "the log window for the exact error message.\n"
+                          "\n"
+                          "Do you want to enter the job again?"))) {
+                        /* _("The job was sent to the bank successfully, but the " */
+                        /*   "bank is refusing to execute the job. Please check " */
+                        /*   "the log window for the exact error message of the " */
+                        /*   "bank. The line with the error message contains a " */
+                        /*   "code number that is greater than 9000.\n" */
+                        /*   "\n" */
+                        /*   "Do you want to enter the job again?"))) { */
+                    aborted = TRUE;
+                }
+            }
+
+            /* Import the results, awaiting nothing */
+            ieci = gnc_ab_import_context(context, 0, FALSE, NULL, parent);
+        }
+        /* Simply ignore any other case */
+
+    repeat:
+        /* Clean up */
+        if (gnc_trans && !successful) {
+            xaccTransBeginEdit(gnc_trans);
+            xaccTransDestroy(gnc_trans);
+            xaccTransCommitEdit(gnc_trans);
+            gnc_trans = NULL;
+        }
+        if (ieci)
+            g_free(ieci);
+        if (context)
+            AB_ImExporterContext_free(context);
+        if (job_list) {
+            AB_Job_List2_free(job_list);
+            job_list = NULL;
+        }
+        if (job) {
+            AB_Job_free(job);
+            job = NULL;
+        }
+        if (gui) {
+            gnc_GWEN_Gui_release(gui);
+            gui = NULL;
+        }
+
+    } while (!successful && !aborted);
+
+cleanup:
+    if (td)
+        gnc_ab_trans_dialog_free(td);
+    if (online)
+        AB_Banking_OnlineFini(api);
+    gnc_AB_BANKING_fini(api);
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-transfer.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-transfer.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-transfer.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,58 @@
+/*
+ * gnc-ab-transfer.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-ab-transfer.h
+ * @brief Dialog for AqBanking transaction data
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_AB_TRANSFER_H
+#define GNC_AB_TRANSFER_H
+
+#include <gtk/gtk.h>
+
+#include "Account.h"
+#include "dialog-ab-trans.h"
+
+G_BEGIN_DECLS
+
+/**
+ * FIXME
+ *
+ * @param parent Widget to use as parent, may be NULL
+ * @param gnc_acc GnuCash account to fetch balance for
+ * @param trans_type Type of transaction
+ */
+void gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
+                      GncABTransType trans_type);
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* GNC_AB_TRANSFER_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-utils.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-utils.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-utils.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,798 @@
+/*
+ * gnc-ab-utils.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-ab-utils.c
+ * @brief AqBanking utility functions
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gwenhywfar/gwenhywfar.h>
+#include <aqbanking/banking.h>
+
+#include "RecnWindow.h"
+#include "Transaction.h"
+#include "dialog-ab-trans.h"
+#include "gnc-ab-kvp.h"
+#include "gnc-ab-utils.h"
+#include "gnc-glib-utils.h"
+#include "gnc-gwen-gui.h"
+#include "gnc-ui.h"
+#include "import-account-matcher.h"
+#include "import-main-matcher.h"
+#include "import-utilities.h"
+#include "qof.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+/* Global variables for AB_BANKING caching. */
+static AB_BANKING *gnc_AB_BANKING = NULL;
+static gint gnc_AB_BANKING_refcount = 0;
+
+static gpointer join_ab_strings_cb(const gchar *str, gpointer user_data);
+static Account *gnc_ab_accinfo_to_gnc_acc(
+    AB_IMEXPORTER_ACCOUNTINFO *account_info);
+static const AB_TRANSACTION *txn_transaction_cb(
+    const AB_TRANSACTION *element, gpointer user_data);
+static AB_IMEXPORTER_ACCOUNTINFO *txn_accountinfo_cb(
+    AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data);
+static AB_IMEXPORTER_ACCOUNTINFO *bal_accountinfo_cb(
+    AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data);
+
+struct _GncABImExContextImport {
+    guint awaiting;
+    gboolean txn_found;
+    Account *gnc_acc;
+    AB_ACCOUNT *ab_acc;
+    gboolean execute_txns;
+    AB_BANKING *api;
+    GtkWidget *parent;
+    AB_JOB_LIST2 *job_list;
+    GNCImportMainMatcher *generic_importer;
+};
+
+void
+gnc_GWEN_Init(void)
+{
+    gint i;
+
+    /* Initialize gwen library */
+    GWEN_Init();
+
+    /* Initialize gwen logging */
+    GWEN_Logger_SetLevel(NULL, GWEN_LoggerLevel_Debug);
+    GWEN_Logger_SetLevel(GWEN_LOGDOMAIN, GWEN_LoggerLevel_Debug);
+    GWEN_Logger_SetLevel(AQBANKING_LOGDOMAIN, GWEN_LoggerLevel_Debug);
+    gnc_GWEN_Gui_log_init();
+}
+
+void
+gnc_GWEN_Fini(void)
+{
+    /* Shutdown the GWEN_GUIs */
+    gnc_GWEN_Gui_shutdown();
+    GWEN_Logger_SetLevel(NULL, GWEN_LoggerLevel_Warning);
+    GWEN_Logger_SetLevel(GWEN_LOGDOMAIN, GWEN_LoggerLevel_Warning);
+    GWEN_Logger_SetLevel(AQBANKING_LOGDOMAIN, GWEN_LoggerLevel_Warning);
+
+    /* Finalize gwen library */
+    GWEN_Fini();
+}
+
+AB_BANKING *
+gnc_AB_BANKING_new(void)
+{
+    AB_BANKING *api;
+
+    if (gnc_AB_BANKING) {
+        /* API cached. */
+        api = gnc_AB_BANKING;
+
+        /* Init the API again. */
+        if (gnc_AB_BANKING_refcount == 0)
+            g_return_val_if_fail(AB_Banking_Init(api) == 0, NULL);
+
+    } else {
+        api = AB_Banking_new("gnucash", NULL, 0);
+        g_return_val_if_fail(api, NULL);
+
+        /* Init the API */
+        g_return_val_if_fail(AB_Banking_Init(api) == 0, NULL);
+
+        /* Cache it */
+        gnc_AB_BANKING = api;
+        gnc_AB_BANKING_refcount = 0;
+    }
+
+    gnc_AB_BANKING_refcount++;
+
+    return api;
+}
+
+void
+gnc_AB_BANKING_delete(AB_BANKING *api)
+{
+    if (!api)
+        api = gnc_AB_BANKING;
+
+    if (api) {
+        if (api == gnc_AB_BANKING) {
+            gnc_AB_BANKING = NULL;
+            if (gnc_AB_BANKING_refcount > 0)
+                AB_Banking_Fini(api);
+        }
+
+        AB_Banking_free(api);
+    }
+}
+
+
+gint
+gnc_AB_BANKING_fini(AB_BANKING *api)
+{
+    if (api == gnc_AB_BANKING) {
+        if (--gnc_AB_BANKING_refcount == 0)
+            return AB_Banking_Fini(api);
+    } else {
+        return AB_Banking_Fini(api);
+    }
+    return 0;
+}
+
+AB_ACCOUNT *
+gnc_ab_get_ab_account(const AB_BANKING *api, Account *gnc_acc)
+{
+    AB_ACCOUNT *ab_account = NULL;
+    const gchar *bankcode = NULL;
+    const gchar *accountid = NULL;
+    guint32 account_uid = 0;
+
+    bankcode = gnc_ab_get_account_bankcode(gnc_acc);
+    accountid = gnc_ab_get_account_accountid(gnc_acc);
+    account_uid = gnc_ab_get_account_uid (gnc_acc);
+
+    if (account_uid > 0) {
+        ab_account = AB_Banking_GetAccount(api, account_uid);
+
+        if (!ab_account && bankcode && *bankcode && accountid && *accountid) {
+            g_message("gnc_ab_get_ab_account: No AB_ACCOUNT found for UID %d, "
+                      "trying bank code\n", account_uid);
+            ab_account = AB_Banking_GetAccountByCodeAndNumber(api, bankcode,
+                                                              accountid);
+        }
+        return ab_account;
+
+    } else if (bankcode && *bankcode && accountid && *accountid) {
+        ab_account = AB_Banking_GetAccountByCodeAndNumber(api, bankcode,
+                                                          accountid);
+        return ab_account;
+    }
+
+    return NULL;
+}
+
+gchar *
+gnc_AB_VALUE_to_readable_string(const AB_VALUE *value)
+{
+    if (value)
+        return g_strdup_printf("%.2f %s",
+                               AB_Value_GetValueAsDouble(value),
+                               AB_Value_GetCurrency(value));
+    else
+        return g_strdup_printf("%.2f", 0.0);
+}
+
+/**
+ * Take a string from a GWEN_STRINGLIST, strip invalid utf8 and join it
+ * to the rest.
+ */
+static gpointer
+join_ab_strings_cb(const gchar *str, gpointer user_data)
+{
+    gchar **acc = user_data;
+    gchar *tmp;
+
+    if (!str || !*str)
+        return NULL;
+
+    tmp = g_strdup(str);
+    g_strstrip(tmp);
+    gnc_utf8_strip_invalid(tmp);
+
+    if (*acc) {
+        gchar *join = g_strjoin(" ", *acc, tmp, (gchar*) NULL);
+        g_free(*acc);
+        g_free(tmp);
+        *acc = join;
+    } else {
+        *acc = tmp;
+    }
+    return NULL;
+}
+
+gchar *
+gnc_ab_get_remote_name(const AB_TRANSACTION *ab_trans)
+{
+    const GWEN_STRINGLIST *ab_remote_name;
+    gchar *gnc_other_name = NULL;
+
+    g_return_val_if_fail(ab_trans, NULL);
+
+    ab_remote_name = AB_Transaction_GetPurpose(ab_trans);
+    if (ab_remote_name)
+        GWEN_StringList_ForEach(ab_remote_name, join_ab_strings_cb,
+                                &gnc_other_name);
+
+    if (!gnc_other_name || !*gnc_other_name) {
+        g_free(gnc_other_name);
+        gnc_other_name = NULL;
+    }
+
+    return gnc_other_name;
+}
+
+gchar *
+gnc_ab_get_purpose(const AB_TRANSACTION *ab_trans)
+{
+    const GWEN_STRINGLIST *ab_purpose;
+    gchar *gnc_description = NULL;
+
+    g_return_val_if_fail(ab_trans, g_strdup(""));
+
+    ab_purpose = AB_Transaction_GetPurpose(ab_trans);
+    if (ab_purpose)
+        GWEN_StringList_ForEach(ab_purpose, join_ab_strings_cb,
+                                &gnc_description);
+
+    if (!gnc_description)
+        gnc_description = g_strdup("");
+
+    return gnc_description;
+}
+
+gchar *
+gnc_ab_description_to_gnc(const AB_TRANSACTION *ab_trans)
+{
+  /* Description */
+    gchar *description = gnc_ab_get_purpose(ab_trans);
+    gchar *other_name = gnc_ab_get_remote_name(ab_trans);
+    gchar *retval;
+
+    if (other_name) {
+        if (description && *description) {
+            retval = g_strdup_printf("%s; %s", description, other_name);
+        } else {
+            retval = g_strdup(other_name);
+        }
+    } else {
+        if (description && *description) {
+            retval = g_strdup(description);
+        } else {
+            retval = g_strdup(_("Unspecified"));
+        }
+    }
+    g_free(description);
+    g_free(other_name);
+
+    return retval;
+}
+
+gchar *
+gnc_ab_memo_to_gnc(const AB_TRANSACTION *ab_trans)
+{
+    const gchar *ab_remote_accountnumber =
+        AB_Transaction_GetRemoteAccountNumber(ab_trans);
+    const gchar *ab_remote_bankcode =
+        AB_Transaction_GetRemoteBankCode(ab_trans);
+    gchar *ab_other_accountid =
+        g_strdup(ab_remote_accountnumber ? ab_remote_accountnumber
+                 : _("unknown"));
+    gchar *ab_other_bankcode =
+        g_strdup(ab_remote_bankcode ? ab_remote_bankcode
+                 : _("unknown"));
+    gchar *retval;
+
+    g_strstrip(ab_other_accountid);
+    g_strstrip(ab_other_bankcode);
+    /* Ensure string is in utf8 */
+    gnc_utf8_strip_invalid(ab_other_accountid);
+    gnc_utf8_strip_invalid(ab_other_bankcode);
+
+    if (ab_other_accountid && *ab_other_accountid) {
+        retval = g_strdup_printf("%s %s %s %s",
+                                 _("Account"), ab_other_accountid,
+                                 _("Bank"), ab_other_bankcode);
+    } else {
+        retval = g_strdup("");
+    }
+    g_free(ab_other_accountid);
+    g_free(ab_other_bankcode);
+
+    return retval;
+}
+
+Transaction *
+gnc_ab_trans_to_gnc(const AB_TRANSACTION *ab_trans, Account *gnc_acc)
+{
+    QofBook *book;
+    Transaction *gnc_trans;
+    const gchar *fitid;
+    const GWEN_TIME *valuta_date;
+    time_t current_time;
+    const char *custref;
+    gchar *description;
+    Split *split;
+    const AB_VALUE *ab_value;
+    gnc_numeric gnc_amount;
+    gchar *memo;
+
+    g_return_val_if_fail(ab_trans && gnc_acc, NULL);
+
+    /* Create new GnuCash transaction for the given AqBanking one */
+    book = gnc_account_get_book(gnc_acc);
+    gnc_trans = xaccMallocTransaction(book);
+    xaccTransBeginEdit(gnc_trans);
+
+    /* Set OFX unique transaction ID */
+    fitid = AB_Transaction_GetFiId(ab_trans);
+    if (fitid && *fitid)
+        gnc_import_set_trans_online_id(gnc_trans, fitid);
+
+    /* Date / Time */
+    valuta_date = AB_Transaction_GetValutaDate(ab_trans);
+    if (!valuta_date) {
+        const GWEN_TIME *normal_date = AB_Transaction_GetDate(ab_trans);
+        if (normal_date)
+            valuta_date = normal_date;
+    }
+    if (valuta_date)
+        xaccTransSetDateSecs(gnc_trans, GWEN_Time_toTime_t(valuta_date));
+    else
+        g_warning("transaction_cb: Oops, date 'valuta_date' was NULL");
+
+    current_time = time(NULL);
+    xaccTransSetDateEnteredSecs(gnc_trans, mktime(localtime(&current_time)));
+
+    /* Currency.  We take simply the default currency of the gnucash account */
+    xaccTransSetCurrency(gnc_trans, xaccAccountGetCommodity(gnc_acc));
+
+    /* Number.  We use the "customer reference", if there is one. */
+    custref = AB_Transaction_GetCustomerReference(ab_trans);
+    if (custref && *custref
+        && g_ascii_strncasecmp(custref, "NONREF", 6) != 0)
+        xaccTransSetNum(gnc_trans, custref);
+
+    /* Description */
+    description = gnc_ab_description_to_gnc(ab_trans);
+    xaccTransSetDescription(gnc_trans, description);
+    g_free(description);
+
+    /* Notes. */
+    /* xaccTransSetNotes(gnc_trans, g_notes); */
+    /* But Nobody ever uses the Notes field? */
+
+    /* Add one split */
+    split = xaccMallocSplit(book);
+    xaccSplitSetParent(split, gnc_trans);
+    xaccSplitSetAccount(split, gnc_acc);
+
+    /* Amount into the split */
+    ab_value = AB_Transaction_GetValue(ab_trans);
+    gnc_amount = double_to_gnc_numeric(
+        ab_value ? AB_Value_GetValueAsDouble(ab_value) : 0.0,
+        xaccAccountGetCommoditySCU(gnc_acc),
+        GNC_RND_ROUND);
+    if (!ab_value)
+        g_warning("transaction_cb: Oops, value was NULL.  Using 0");
+    xaccSplitSetBaseValue(split, gnc_amount, xaccAccountGetCommodity(gnc_acc));
+
+    /* Memo in the Split. */
+    memo = gnc_ab_memo_to_gnc(ab_trans);
+    xaccSplitSetMemo(split, memo);
+    g_free(memo);
+
+    return gnc_trans;
+}
+
+/**
+ * Call gnc_import_select_account() on the online id constructed using
+ * the information in @a acc_info.
+ *
+ * @param acc_info AB_IMEXPORTER_ACCOUNTINFO
+ * @return A GnuCash account, or NULL otherwise
+ */
+static Account *
+gnc_ab_accinfo_to_gnc_acc(AB_IMEXPORTER_ACCOUNTINFO *acc_info)
+{
+    gchar *online_id;
+    Account *gnc_acc;
+
+    g_return_val_if_fail(acc_info, NULL);
+
+    online_id = g_strconcat(AB_ImExporterAccountInfo_GetBankCode(acc_info),
+                            AB_ImExporterAccountInfo_GetAccountNumber(acc_info),
+                            (gchar*)NULL);
+    gnc_acc = gnc_import_select_account(
+        NULL, online_id, 1, AB_ImExporterAccountInfo_GetAccountName(acc_info),
+        NULL, ACCT_TYPE_NONE, NULL, NULL);
+    if (!gnc_acc) {
+        g_warning("gnc_ab_accinfo_to_gnc_acc: Could not determine source account"
+                  " for online_id %s", online_id);
+    }
+    g_free(online_id);
+
+    return gnc_acc;
+}
+
+static const AB_TRANSACTION *
+txn_transaction_cb(const AB_TRANSACTION *element, gpointer user_data)
+{
+    GncABImExContextImport *data = user_data;
+    Transaction *gnc_trans;
+
+    g_return_val_if_fail(element && data, NULL);
+
+    /* Create a GnuCash transaction from ab_trans */
+    gnc_trans = gnc_ab_trans_to_gnc(element, data->gnc_acc);
+
+    /* Instead of xaccTransCommitEdit(gnc_trans)  */
+    gnc_gen_trans_list_add_trans(data->generic_importer, gnc_trans);
+
+    if (data->execute_txns && data->ab_acc) {
+        AB_TRANSACTION *ab_trans = AB_Transaction_dup(element);
+        AB_JOB *job;
+
+        /* NEW: The imported transaction has been imported into gnucash.
+         * Now also add it as a job to aqbanking */
+        AB_Transaction_SetLocalBankCode(
+            ab_trans, AB_Account_GetBankCode(data->ab_acc));
+        AB_Transaction_SetLocalAccountNumber(
+            ab_trans, AB_Account_GetAccountNumber(data->ab_acc));
+        AB_Transaction_SetLocalCountry(ab_trans, "DE");
+
+        job = gnc_ab_get_trans_job(data->ab_acc, ab_trans, SINGLE_DEBITNOTE);
+
+        /* Check whether we really got a job */
+        if (!job) {
+            /* Oops, no job, probably not supported by bank */
+            if (gnc_verify_dialog(
+                    NULL, FALSE, "%s",
+                    _("The backend found an error during the preparation "
+                      "of the job. It is not possible to execute this job. \n"
+                      "\n"
+                      "Most probable the bank does not support your chosen "
+                      "job or your Online Banking account does not have the permission "
+                      "to execute this job. More error messages might be "
+                      "visible on your console log.\n"
+                      "\n"
+                      "Do you want to enter the job again?"))) {
+                gnc_error_dialog(NULL, "Sorry, not implemented yet.");
+            }
+            /* else */
+        }
+        AB_Job_List2_PushBack(data->job_list, job);
+
+        AB_Transaction_free(ab_trans);
+    }
+
+    return NULL;
+}
+
+static AB_IMEXPORTER_ACCOUNTINFO *
+txn_accountinfo_cb(AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
+{
+    GncABImExContextImport *data = user_data;
+    Account *gnc_acc;
+
+    g_return_val_if_fail(element && data, NULL);
+
+    if (data->awaiting & IGNORE_TRANSACTIONS)
+        /* Ignore them */
+        return NULL;
+
+    if (!AB_ImExporterAccountInfo_GetFirstTransaction(element))
+        /* No transaction found */
+        return NULL;
+    else
+        data->awaiting |= FOUND_TRANSACTIONS;
+
+    if (!(data->awaiting & AWAIT_TRANSACTIONS)) {
+        if (gnc_verify_dialog(data->parent, TRUE, "%s",
+                              _("The bank has sent transaction information "
+                                "in its response."
+                                "\n"
+                                "Do you want to import it?"))) {
+            data->awaiting |= AWAIT_TRANSACTIONS;
+        } else {
+            data->awaiting |= IGNORE_TRANSACTIONS;
+            return NULL;
+        }
+    }
+
+    /* Lookup the corresponding gnucash account */
+    gnc_acc = gnc_ab_accinfo_to_gnc_acc(element);
+    if (!gnc_acc) return NULL;
+    data->gnc_acc = gnc_acc;
+
+    if (data->execute_txns) {
+        /* Retrieve the aqbanking account that belongs to this gnucash
+         * account */
+        data->ab_acc = gnc_ab_get_ab_account(data->api, gnc_acc);
+        if (!data->ab_acc) {
+            gnc_error_dialog(NULL, "%s",
+                             _("No Online Banking account found for this "
+                               "gnucash account. These transactions will "
+                               "not be executed by Online Banking."));
+        }
+    } else {
+        data->ab_acc = NULL;
+    }
+
+    if (!data->generic_importer)
+        data->generic_importer = gnc_gen_trans_list_new(data->parent, NULL,
+                                                        TRUE, 14);
+
+    /* Iterate through all transactions */
+    AB_ImExporterAccountInfo_TransactionsForEach(element, txn_transaction_cb,
+                                                 data);
+
+    return NULL;
+}
+
+static AB_IMEXPORTER_ACCOUNTINFO *
+bal_accountinfo_cb(AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
+{
+    GncABImExContextImport *data = user_data;
+    Account *gnc_acc;
+    AB_ACCOUNT_STATUS *item, *best = NULL;
+    const GWEN_TIME *best_time;
+    const AB_BALANCE *booked_bal, *noted_bal;
+    const AB_VALUE *booked_val = NULL, *noted_val = NULL;
+    gdouble booked_value, noted_value;
+    gnc_numeric value;
+    time_t booked_tt = 0;
+    GtkWidget *dialog;
+    gboolean show_recn_window = FALSE;
+
+    g_return_val_if_fail(element && data, NULL);
+
+    if (data->awaiting & IGNORE_BALANCES)
+        /* Ignore them */
+        return NULL;
+
+    if (!AB_ImExporterAccountInfo_GetFirstAccountStatus(element))
+        /* No balance found */
+        return NULL;
+    else
+        data->awaiting |= FOUND_BALANCES;
+
+    if (!(data->awaiting & AWAIT_BALANCES)) {
+        if (gnc_verify_dialog(data->parent, TRUE, "%s",
+                              _("The bank has sent balance information "
+                                "in its response."
+                                "\n"
+                                "Do you want to import it?"))) {
+            data->awaiting |= AWAIT_BALANCES;
+        } else {
+            data->awaiting |= IGNORE_BALANCES;
+            return NULL;
+        }
+    }
+
+    /* Lookup the corresponding gnucash account */
+    gnc_acc = gnc_ab_accinfo_to_gnc_acc(element);
+    if (!gnc_acc) return NULL;
+    data->gnc_acc = gnc_acc;
+
+    /* Lookup the most recent ACCOUNT_STATUS available */
+    item = AB_ImExporterAccountInfo_GetFirstAccountStatus(element);
+    while (item) {
+        const GWEN_TIME *item_time = AB_AccountStatus_GetTime(item);
+        if (!best || GWEN_Time_Diff(best_time, item_time) < 0.0) {
+            best = item;
+            best_time = item_time;
+        }
+        item = AB_ImExporterAccountInfo_GetNextAccountStatus(element);
+    }
+
+    /* Lookup booked balance and time */
+    booked_bal = AB_AccountStatus_GetBookedBalance(best);
+    if (booked_bal) {
+        const GWEN_TIME *ti = AB_Balance_GetTime(booked_bal);
+        if (ti) {
+            booked_tt =  GWEN_Time_toTime_t(ti);
+        } else {
+            /* No time found? Use today because the HBCI query asked for today's
+             * balance. */
+            booked_tt = gnc_timet_get_day_start(time(NULL));
+        }
+        booked_val = AB_Balance_GetValue(booked_bal);
+        if (booked_val) {
+            booked_value = AB_Value_GetValueAsDouble(booked_val);
+        } else {
+            g_warning("bal_accountinfo_cb: booked_val == NULL.  Assuming 0");
+            booked_value = 0.0;
+        }
+    } else {
+        g_warning("bal_accountinfo_cb: booked_bal == NULL.  Assuming 0");
+        booked_tt = 0;
+        booked_value = 0.0;
+    }
+
+    /* Lookup noted balance */
+    noted_bal = AB_AccountStatus_GetNotedBalance(best);
+    if (noted_bal) {
+        noted_val = AB_Balance_GetValue(noted_bal);
+        if (noted_val)
+            noted_value = AB_Value_GetValueAsDouble(noted_val);
+        else {
+            g_warning("bal_accountinfo_cb: noted_val == NULL.  Assuming 0");
+            noted_value = 0.0;
+        }
+    } else {
+        g_warning("bal_accountinfo_cb: noted_bal == NULL.  Assuming 0");
+        noted_value = 0.0;
+    }
+
+    value = double_to_gnc_numeric(booked_value,
+                                  xaccAccountGetCommoditySCU(gnc_acc),
+                                  GNC_RND_ROUND);
+    if (noted_value == 0.0 && booked_value == 0.0) {
+        dialog = gtk_message_dialog_new(
+            GTK_WINDOW(data->parent),
+            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+            GTK_MESSAGE_INFO,
+            GTK_BUTTONS_OK,
+            "%s",
+            /* Translators: Strings from this file are needed only in
+             * countries that have one of aqbanking's Online Banking
+             * techniques available. This is 'OFX DirectConnect'
+             * (U.S. and others), 'HBCI' (in Germany), or 'YellowNet'
+             * (Switzerland). If none of these techniques are available
+             * in your country, you may safely ignore strings from the
+             * import-export/hbci subdirectory. */
+            _("The downloaded Online Banking Balance was zero.\n\n"
+              "Either this is the correct balance, or your bank does not "
+              "support Balance download in this Online Banking version. "
+              "In the latter case you should choose a different "
+              "Online Banking version number in the Online Banking "
+              "(AqBanking or HBCI) Setup. After that, try again to "
+              "download the Online Banking Balance."));
+        gtk_dialog_run(GTK_DIALOG(dialog));
+        gtk_widget_destroy(dialog);
+
+    } else {
+        gnc_numeric reconc_balance = xaccAccountGetReconciledBalance(gnc_acc);
+
+        gchar *booked_str = gnc_AB_VALUE_to_readable_string(booked_val);
+        gchar *message1 = g_strdup_printf(
+            _("Result of Online Banking job: \n"
+              "Account booked balance is %s"),
+            booked_str);
+        gchar *message2 =
+            (noted_value == 0.0) ?
+            g_strdup("") :
+            g_strdup_printf(_("For your information: This account also "
+                              "has a noted balance of %s\n"),
+                            gnc_AB_VALUE_to_readable_string(noted_val));
+
+        if (gnc_numeric_equal(value, reconc_balance)) {
+            const gchar *message3 =
+                _("The booked balance is identical to the current "
+                  "reconciled balance of the account.");
+            dialog = gtk_message_dialog_new(
+                GTK_WINDOW(data->parent),
+                GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                GTK_MESSAGE_INFO,
+                GTK_BUTTONS_OK,
+                "%s\n%s\n%s",
+                message1, message2, message3);
+            gtk_dialog_run(GTK_DIALOG(dialog));
+            gtk_widget_destroy(GTK_WIDGET(dialog));
+
+        } else {
+            const char *message3 = _("Reconcile account now?");
+
+            show_recn_window = gnc_verify_dialog(data->parent,TRUE, "%s\n%s\n%s",
+                                                 message1, message2, message3);
+        }
+        g_free(booked_str);
+        g_free(message1);
+        g_free(message2);
+    }
+
+    /* Show reconciliation window */
+    if (show_recn_window)
+        recnWindowWithBalance(data->parent, gnc_acc, value, booked_tt);
+
+    return NULL;
+}
+
+GncABImExContextImport *
+gnc_ab_import_context(AB_IMEXPORTER_CONTEXT *context,
+                      guint awaiting, gboolean execute_txns,
+                      AB_BANKING *api, GtkWidget *parent)
+{
+    GncABImExContextImport *data = g_new(GncABImExContextImport, 1);
+
+    g_return_val_if_fail(context, NULL);
+    /* Do not await and ignore at the same time */
+    g_return_val_if_fail(!(awaiting & AWAIT_BALANCES)
+                         || !(awaiting & IGNORE_BALANCES),
+                         NULL);
+    g_return_val_if_fail(!(awaiting & AWAIT_TRANSACTIONS)
+                         || !(awaiting & IGNORE_TRANSACTIONS),
+                         NULL);
+    /* execute_txns must be FALSE if txns are not awaited */
+    g_return_val_if_fail(awaiting & AWAIT_TRANSACTIONS || !execute_txns, NULL);
+    /* An api is needed for the jobs */
+    g_return_val_if_fail(!execute_txns || api, NULL);
+
+    data->awaiting = awaiting;
+    data->txn_found = FALSE;
+    data->execute_txns = execute_txns;
+    data->api = api;
+    data->parent = parent;
+    data->job_list = NULL;
+    data->generic_importer = NULL;
+
+    /* Import transactions */
+    if (!(awaiting & IGNORE_TRANSACTIONS))
+        AB_ImExporterContext_AccountInfoForEach(context, txn_accountinfo_cb,
+                                                data);
+
+    /* Check balances */
+    if (!(awaiting & IGNORE_BALANCES))
+        AB_ImExporterContext_AccountInfoForEach(context, bal_accountinfo_cb,
+                                                data);
+
+    return data;
+}
+
+guint
+gnc_ab_ieci_get_found(GncABImExContextImport *ieci)
+{
+    g_return_val_if_fail(ieci, 0);
+
+    return ieci->awaiting;
+}
+
+AB_JOB_LIST2 *
+gnc_ab_ieci_get_job_list(GncABImExContextImport *ieci)
+{
+    g_return_val_if_fail(ieci, NULL);
+
+    return ieci->job_list;
+}
+
+gboolean
+gnc_ab_ieci_run_matcher(GncABImExContextImport *ieci)
+{
+    g_return_val_if_fail(ieci, FALSE);
+
+    return gnc_gen_trans_list_run(ieci->generic_importer);
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-utils.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-utils.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-ab-utils.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,226 @@
+/*
+ * gnc-ab-utils.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-ab-utils.h
+ * @brief AqBanking utility functions
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_AB_UTILS_H
+#define GNC_AB_UTILS_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <aqbanking/banking.h>
+
+#include "Account.h"
+
+G_BEGIN_DECLS
+
+#define GCONF_SECTION_AQBANKING "dialogs/import/hbci"
+#define KEY_FORMAT_SWIFT940 "format_swift_mt940"
+#define KEY_FORMAT_SWIFT942 "format_swift_mt942"
+#define KEY_FORMAT_DTAUS "format_dtaus"
+
+typedef struct _GncABImExContextImport GncABImExContextImport;
+
+#define AWAIT_BALANCES      1 << 1
+#define FOUND_BALANCES      1 << 2
+#define IGNORE_BALANCES     1 << 3
+#define AWAIT_TRANSACTIONS  1 << 4
+#define FOUND_TRANSACTIONS  1 << 5
+#define IGNORE_TRANSACTIONS 1 << 6
+
+/**
+ * Initialize the gwenhywfar library by calling GWEN_Init() and setting up
+ * gwenhywfar logging.
+ */
+void gnc_GWEN_Init(void);
+
+/**
+ * Finalize the gwenhywfar library.
+ */
+void gnc_GWEN_Fini(void);
+
+/**
+ * If there is a cached AB_BANKING object, return it initialized.  Otherwise,
+ * create a new AB_BANKING, let it load its environment from its default
+ * configuration and cache it.
+ *
+ * @return The AB_BANKING object
+ */
+AB_BANKING *gnc_AB_BANKING_new(void);
+
+/**
+ * Delete the AB_BANKING @a api.  If this is also the one that was cached by
+ * gnc_AB_BANKING_new(), then all references are deleted, too.
+ *
+ * @param api AB_BANKING or NULL for the cached AB_BANKING object
+ */
+void gnc_AB_BANKING_delete(AB_BANKING *api);
+
+/**
+ * Finish the AB_BANKING @a api.  If this is also the one that was cached by
+ * gnc_AB_BANKING_new(), then finish only if the decremented reference count
+ * reaches zero.  After this call, you may only call gnc_AB_BANKING_new() to get
+ * the api again in a properly initialized state.
+ *
+ * @param api AB_BANKING object
+ * @return Zero on success
+ */
+gint gnc_AB_BANKING_fini(AB_BANKING *api);
+
+/**
+ * Get the corresponding AqBanking account to the GnuCash account @a gnc_acc.
+ * Of course this only works after the GnuCash account has been set up for
+ * AqBanking use, i.e. the kvp_frame "hbci/..." has been filled with
+ * information.
+ *
+ * @param api The AB_BANKING to get the AB_ACCOUNT from
+ * @param gnc_acc The GnuCash account to query for AB_ACCOUNT reference data
+ * @return The AB_ACCOUNT found or NULL otherwise
+ */
+AB_ACCOUNT *gnc_ab_get_ab_account(const AB_BANKING *api, Account *gnc_acc);
+
+/**
+ * Print the value of @a value with two decimal places and @a value's
+ * currency appended, or 0.0 otherwise
+ *
+ * @param value AB_VALUE or NULL
+ * @return A newly allocated string
+ */
+gchar *gnc_AB_VALUE_to_readable_string(const AB_VALUE *value);
+
+/**
+ * Retrieve the merged "remote name" fields from a transaction.  The returned
+ * string must be g_free'd by the caller.  If there was no "remote name" field,
+ * NULL (!) is returned.
+ *
+ * @param ab_trans AqBanking transaction
+ * @return A newly allocated string or NULL otherwise
+ */
+gchar *gnc_ab_get_remote_name(const AB_TRANSACTION *ab_trans);
+
+/**
+ * Retrieve the merged purpose fields from a transaction.  The returned string
+ * must be g_free'd by the caller.  If there was no purpose, an empty (but
+ * allocated) string is returned.
+ *
+ * @param ab_trans AqBanking transaction
+ * @return A newly allocated string, may be ""
+ */
+gchar *gnc_ab_get_purpose(const AB_TRANSACTION *ab_trans);
+
+/**
+ * Create the appropriate description field for a GnuCash Transaction by the
+ * information given in the AB_TRANSACTION @a ab_trans.  The returned string
+ * must be g_free'd by the caller.
+ *
+ * @param ab_trans AqBanking transaction
+ * @return A newly allocated string, may be ""
+ */
+gchar *gnc_ab_description_to_gnc(const AB_TRANSACTION *ab_trans);
+
+/**
+ * Create the appropriate memo field for a GnuCash Split by the information
+ * given in the AB_TRANSACTION @a ab_trans.  The returned string must be
+ * g_free'd by the caller.
+ *
+ * @param ab_trans AqBanking transaction
+ * @return A newly allocated string, may be ""
+ */
+gchar *gnc_ab_memo_to_gnc(const AB_TRANSACTION *ab_trans);
+
+/**
+ * Create an unbalanced and dirty GnuCash transaction with a split to @a gnc_acc
+ * from the information available in the AqBanking transaction @a ab_trans.
+ *
+ * @param ab_trans AqBanking transaction
+ * @param gnc_acc Account of to use for the split
+ * @return A dirty GnuCash transaction or NULL otherwise
+ */
+Transaction *gnc_ab_trans_to_gnc(const AB_TRANSACTION *ab_trans, Account *gnc_acc);
+
+/**
+ * Import balances and transactions found in a AB_IMEXPORTER_CONTEXT into
+ * GnuCash.  By using @a awaiting the caller can specify what the user will
+ * expect to receive.  By using @a execute_txns, transactions in @a context can
+ * be used to generate corresponding AqBanking jobs, e.g. after a file import.
+ *
+ * @param context AB_IMEXPORTER_CONTEXT to import
+ *
+ * @param awaiting Information the caller expects to receive or wants to ignore,
+ * bitmask of AWAIT_* or IGNORE_* values
+ *
+ * @param execute_txns If @a awaiting contains AWAIT_TRANSACTIONS, whether to
+ * create an aqbanking job for each of the transactions found
+ *
+ * @param api If @a execute_txns is TRUE, the AB_BANKING to get
+ * AB_ACCOUNTs from
+ *
+ * @param parent Widget to set new dialogs transient for, may be NULL
+ *
+ * @return A new GncABImExContextImport object which must be freed with
+ * g_free(), or NULL otherwise.  If execute_txns is TRUE, additionally
+ * gnc_ab_ieci_get_job_list() must be called and the result freed with
+ * AB_Job_List2_FreeAll()
+ */
+GncABImExContextImport *gnc_ab_import_context(
+    AB_IMEXPORTER_CONTEXT *context, guint awaiting, gboolean execute_txns,
+    AB_BANKING *api, GtkWidget *parent);
+
+/**
+ * Extract awaiting from @a data.
+ *
+ * @param ieci The return value of gnc_ab_import_context()
+ * @return The initial awaiting bitmask plus IGNORE_* for unexpected and then
+ * ignored items, and FOUND_* for non-empty items
+ */
+guint gnc_ab_ieci_get_found(GncABImExContextImport *ieci);
+
+/**
+ * Extract the job list from @a data.
+ *
+ * @param ieci The return value of gnc_ab_import_context()
+ * @return The list of jobs, freeable with AB_Job_List2_FreeAll()
+ */
+AB_JOB_LIST2 *gnc_ab_ieci_get_job_list(GncABImExContextImport *ieci);
+
+/**
+ * Run the generic transaction matcher dialog.
+ *
+ * @param ieci The return value of gnc_ab_import_context()
+ * @return The return value of gnc_gen_trans_list_run().
+ */
+gboolean gnc_ab_ieci_run_matcher(GncABImExContextImport *ieci);
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* GNC_AB_UTILS_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-file-aqb-import.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-file-aqb-import.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-file-aqb-import.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,209 @@
+/*
+ * gnc-file-aqb-import.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-file-aqb-import.c
+ * @brief DTAUS import module code
+ * @author Copyright (C) 2002 Benoit Grégoire <bock at step.polymtl.ca>
+ * @author Copyright (C) 2003 Jan-Pascal van Best <janpascal at vanbest.org>
+ * @author Copyright (C) 2006 Florian Steinel
+ * @author Copyright (C) 2006 Christian Stimming
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <gwenhywfar/io_file.h>
+#include <gwenhywfar/io_buffered.h>
+#include <gwenhywfar/iomanager.h>
+
+#include "dialog-ab-trans.h"
+#include "gnc-ab-utils.h"
+#include "gnc-file.h"
+#include "gnc-file-aqb-import.h"
+#include "gnc-gwen-gui.h"
+#include "gnc-ui.h"
+#include "gnc-ui-util.h"
+#include "import-account-matcher.h"
+#include "import-main-matcher.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_IMPORT;
+
+void
+gnc_file_aqbanking_import(const gchar *aqbanking_importername,
+                          const gchar *aqbanking_profilename,
+                          gboolean execute_transactions)
+{
+    gchar *default_dir;
+    gchar *selected_filename = NULL;
+    gint dtaus_fd = -1;
+    AB_BANKING *api = NULL;
+    gboolean online = FALSE;
+    GncGWENGui *gui = NULL;
+    AB_IMEXPORTER *importer;
+    GWEN_DB_NODE *db_profiles = NULL;
+    GWEN_DB_NODE *db_profile;
+    AB_IMEXPORTER_CONTEXT *context = NULL;
+    GWEN_IO_LAYER *io, *buffio;
+    GncABImExContextImport *ieci = NULL;
+    AB_JOB_LIST2 *job_list = NULL;
+
+    /* Select a file */
+    default_dir = gnc_get_default_directory(GCONF_SECTION_AQBANKING);
+    selected_filename = gnc_file_dialog(_("Select a file to import"),
+                                        NULL, default_dir,
+                                        GNC_FILE_DIALOG_IMPORT);
+    g_free(default_dir);
+
+    if (!selected_filename)
+        goto cleanup;
+    DEBUG("filename: %s", selected_filename);
+
+    /* Remember the directory as the default */
+    default_dir = g_path_get_dirname(selected_filename);
+    gnc_set_default_directory(GCONF_SECTION_AQBANKING, default_dir);
+    g_free(default_dir);
+
+    dtaus_fd = g_open(selected_filename, O_RDONLY, 0);
+    if (dtaus_fd == -1) {
+      DEBUG("Could not open file %s", selected_filename);
+      goto cleanup;
+    }
+
+    /* Get the API */
+    api = gnc_AB_BANKING_new();
+    if (!api) {
+        g_warning("gnc_file_aqbanking_import: Couldn't get AqBanking API");
+        goto cleanup;
+    }
+    if (AB_Banking_OnlineInit(api) != 0) {
+        g_warning("gnc_file_aqbanking_import: "
+                  "Couldn't initialize AqBanking API");
+        goto cleanup;
+    }
+    online = TRUE;
+
+    /* Get a GUI object */
+    gui = gnc_GWEN_Gui_get(NULL);
+    if (!gui) {
+        g_warning("gnc_ab_getbalance: Couldn't initialize Gwenhywfar GUI");
+        goto cleanup;
+    }
+
+    /* Get import module */
+    importer = AB_Banking_GetImExporter(api, aqbanking_importername);
+    if (!importer) {
+        g_warning("Import module %s not found", aqbanking_importername);
+        gnc_error_dialog(NULL, "%s",
+                         _("Import module for DTAUS import not found."));
+        goto cleanup;
+    }
+
+    /* Load the import profile */
+    db_profiles = AB_Banking_GetImExporterProfiles(api, aqbanking_importername);
+
+    /* Select profile */
+    db_profile = GWEN_DB_GetFirstGroup(db_profiles);
+    while (db_profile) {
+        const gchar *name;
+
+        name = GWEN_DB_GetCharValue(db_profile, "name", 0, 0);
+        g_return_if_fail(name);
+        if (g_ascii_strcasecmp(name, aqbanking_profilename)==0)
+            break;
+        db_profile = GWEN_DB_GetNextGroup(db_profile);
+    }
+    if (!db_profile) {
+        g_warning("Profile \"%s\" for importer \"%s\" not found",
+                  aqbanking_profilename, aqbanking_importername);
+        /* For debugging: Print those available names that have been found */
+        db_profile = GWEN_DB_GetFirstGroup(db_profiles);
+        while (db_profile) {
+            const char *name = GWEN_DB_GetCharValue(db_profile, "name", 0, 0);
+            g_warning("Only found profile \"%s\"\n", name ? name : "(null)");
+            db_profile = GWEN_DB_GetNextGroup(db_profile);
+        }
+        goto cleanup;
+    }
+
+    /* Create a context to store the results */
+    context = AB_ImExporterContext_new();
+
+    /* Wrap file in buffered gwen io */
+    io = GWEN_Io_LayerFile_new(dtaus_fd, -1);
+    dtaus_fd = -1;
+    buffio = GWEN_Io_LayerBuffered_new(io);
+    if (GWEN_Io_Manager_RegisterLayer(buffio)) {
+        g_warning("gnc_file_aqbanking_import: Failed to wrap file");
+        goto cleanup;
+    }
+
+    /* Run the import */
+    if (AB_ImExporter_Import(importer, context, buffio, db_profile, 0)) {
+        g_warning("gnc_file_aqbanking_import: Error on import");
+        goto cleanup;
+    }
+
+    /* Close the file */
+    GWEN_Io_Layer_free(buffio);
+
+    /* Import the results */
+    ieci = gnc_ab_import_context(context, AWAIT_TRANSACTIONS,
+                                 execute_transactions,
+                                 execute_transactions ? api : NULL,
+                                 NULL);
+
+    /* Extract the list of jobs */
+    job_list = gnc_ab_ieci_get_job_list(ieci);
+
+    if (execute_transactions) {
+        if (gnc_ab_ieci_run_matcher(ieci)) {
+            /* FIXME */
+            /* gnc_hbci_multijob_execute(NULL, api, job_list, gui); */
+        }
+    }
+
+cleanup:
+    if (job_list)
+        AB_Job_List2_FreeAll(job_list);
+    if (ieci)
+        g_free(ieci);
+    if (context)
+        AB_ImExporterContext_free(context);
+    if (db_profiles)
+        GWEN_DB_Group_free(db_profiles);
+    if (gui)
+        gnc_GWEN_Gui_release(gui);
+    if (online)
+        AB_Banking_OnlineFini(api);
+    if (api)
+        gnc_AB_BANKING_fini(api);
+    if (dtaus_fd != -1)
+        close(dtaus_fd);
+    if (selected_filename)
+        g_free(selected_filename);
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-file-aqb-import.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-file-aqb-import.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-file-aqb-import.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,69 @@
+/*
+ * gnc-file-aqb-import.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-file-aqb-import.h
+ * @brief DTAUS import module interface
+ * @author Copyright (C) 2002 Benoit Grégoire <bock at step.polymtl.ca>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_FILE_AQB_IMPORT_H
+#define GNC_FILE_AQB_IMPORT_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ * This routine will pop up a standard file selection dialog asking the user to
+ * pick a file to import.  This file will be opened and read.  Its contents will
+ * be imported into the current book, using the import matcher from
+ * import-main-matcher.h.
+ *
+ * @param aqbanking_importername The aqbanking importer module that should be
+ * used.  Possible values: "dtaus", "csv", "swift", or more.
+ *
+ * @param aqbanking_formatname In aqbanking, each importer has one or more data
+ * formats available which define the actual data fields that should be used.
+ * In aqbanking, such a different format is called a "profile".  Possible values
+ * for swift: "swift-mt940" or "swift-mt942", but for all others: "default", or
+ * more precisely: Look into $datadir/aqbanking/imexporters and look into the
+ * "name" field of the foo.conf files.
+ *
+ * @param exec_as_aqbanking_jobs If TRUE, additionally queue the imported
+ * transactions as online jobs over aqbanking/HBCI.  If FALSE, just import the
+ * transactions and that's it.
+ */
+void gnc_file_aqbanking_import (const gchar *aqbanking_importername,
+                                const gchar *aqbanking_formatname,
+                                gboolean exec_as_aqbanking_jobs);
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* GNC_FILE_AQB_IMPORT_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-gwen-gui.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-gwen-gui.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-gwen-gui.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,1336 @@
+/*
+ * gnc-gwen-gui.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-gwen-gui.c
+ * @brief GUI callbacks for AqBanking
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2006 David Hampton <hampton at employees.org>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <ctype.h>
+#include <glib/gi18n.h>
+#include <gwenhywfar/gui_be.h>
+#include <gwenhywfar/inherit.h>
+
+#include "dialog-utils.h"
+#include "gnc-ab-utils.h"
+#include "gnc-component-manager.h"
+#include "gnc-gconf-utils.h"
+#include "gnc-gwen-gui.h"
+#include "gnc-session.h"
+#include "gnc-ui.h"
+#include "md5.h"
+#include "qof.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+/* A unique full-blown GUI, featuring  */
+static GncGWENGui *full_gui = NULL;
+
+/* A unique Gwenhywfar GUI for hooking our logging into the gwenhywfar logging
+ * framework */
+static GWEN_GUI *log_gwen_gui = NULL;
+
+/* A mapping from gwenhywfar log levels to glib ones */
+static GLogLevelFlags log_levels[] = {
+    G_LOG_LEVEL_ERROR,     /* GWEN_LoggerLevel_Emergency */
+    G_LOG_LEVEL_ERROR,     /* GWEN_LoggerLevel_Alert */
+    G_LOG_LEVEL_CRITICAL,  /* GWEN_LoggerLevel_Critical */
+    G_LOG_LEVEL_CRITICAL,  /* GWEN_LoggerLevel_Error */
+    G_LOG_LEVEL_WARNING,   /* GWEN_LoggerLevel_Warning */
+    G_LOG_LEVEL_MESSAGE,   /* GWEN_LoggerLevel_Notice */
+    G_LOG_LEVEL_INFO,      /* GWEN_LoggerLevel_Info */
+    G_LOG_LEVEL_DEBUG,     /* GWEN_LoggerLevel_Debug */
+    G_LOG_LEVEL_DEBUG      /* GWEN_LoggerLevel_Verbous */
+};
+static guint8 n_log_levels = G_N_ELEMENTS(log_levels);
+
+/* Macros to determine the GncGWENGui* from a GWEN_GUI* */
+GWEN_INHERIT(GWEN_GUI, GncGWENGui)
+#define SETDATA_GUI(gwen_gui, gui) GWEN_INHERIT_SETDATA(GWEN_GUI, GncGWENGui, \
+                                                        (gwen_gui), (gui), NULL)
+#define GETDATA_GUI(gwen_gui) GWEN_INHERIT_GETDATA(GWEN_GUI, GncGWENGui, (gwen_gui))
+
+#define GWEN_GUI_CM_CLASS "dialog-hbcilog"
+#define GCONF_SECTION_CONNECTION GCONF_SECTION_AQBANKING "/connection_dialog"
+#define KEY_CLOSE_ON_FINISH "close_on_finish"
+#define KEY_REMEMBER_PIN "remember_pin"
+
+#define OTHER_ENTRIES_ROW_OFFSET 3
+
+typedef struct _Progress Progress;
+typedef enum _GuiState GuiState;
+
+static void register_callbacks(GncGWENGui *gui);
+static void unregister_callbacks(GncGWENGui *gui);
+static void setup_dialog(GncGWENGui *gui);
+static void enable_password_cache(GncGWENGui *gui, gboolean enabled);
+static void reset_dialog(GncGWENGui *gui);
+static void set_runing(GncGWENGui *gui);
+static void set_finished(GncGWENGui *gui);
+static void set_aborted(GncGWENGui *gui);
+static void show_dialog(GncGWENGui *gui, gboolean clear_log);
+static void hide_dialog(GncGWENGui *gui);
+static gboolean show_progress_cb(gpointer user_data);
+static void show_progress(GncGWENGui *gui, Progress *progress);
+static void hide_progress(GncGWENGui *gui, Progress *progress);
+static void free_progress(Progress *progress, gpointer unused);
+static gboolean keep_alive(GncGWENGui *gui);
+static void cm_close_handler(gpointer user_data);
+static void erase_password(gchar *password);
+static gchar *strip_html(gchar *text);
+static void get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
+                      const gchar *text, gchar **input, gint min_len,
+                      gint max_len);
+static gint messagebox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
+                          const gchar *text, const gchar *b1,const gchar *b2,
+                          const gchar *b3, guint32 guiid);
+static gint inputbox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
+                        const gchar *text, gchar *buffer, gint min_len,
+                        gint max_len, guint32 guiid);
+static guint32 showbox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
+                          const gchar *text, guint32 guiid);
+static void hidebox_cb(GWEN_GUI *gwen_gui, guint32 id);
+static guint32 progress_start_cb(GWEN_GUI *gwen_gui, guint32 progressFlags,
+                                 const gchar *title, const gchar *text,
+                                 guint64 total, guint32 guiid);
+static gint progress_advance_cb(GWEN_GUI *gwen_gui, guint32 id,
+                                guint64 new_progress);
+static gint progress_log_cb(GWEN_GUI *gwen_gui, guint32 id,
+                            GWEN_LOGGER_LEVEL level, const gchar *text);
+static gint progress_end_cb(GWEN_GUI *gwen_gui, guint32 id);
+static gint getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
+                           const gchar *title, const gchar *text, gchar *buffer,
+                           gint min_len, gint max_len, guint32 guiid);
+static gint setpasswordstatus_cb(GWEN_GUI *gwen_gui, const gchar *token,
+                                 const gchar *pin,
+                                 GWEN_GUI_PASSWORD_STATUS status, guint32 guiid);
+static gint loghook_cb(GWEN_GUI *gwen_gui, const gchar *log_domain,
+                       GWEN_LOGGER_LEVEL priority, const gchar *text);
+static gint checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
+                         GWEN_IO_LAYER *io, guint32 guiid);
+
+gboolean ggg_delete_event_cb(GtkWidget *widget, GdkEvent *event,
+                             gpointer user_data);
+void ggg_abort_clicked_cb(GtkButton *button, gpointer user_data);
+void ggg_close_clicked_cb(GtkButton *button, gpointer user_data);
+
+enum _GuiState {
+  INIT,
+  RUNNING,
+  FINISHED,
+  ABORTED,
+  HIDDEN
+};
+
+struct _GncGWENGui {
+    GWEN_GUI *gwen_gui;
+    GtkWidget *parent;
+    GtkWidget *dialog;
+
+    /* Progress bars */
+    GtkWidget *entries_table;
+    GtkWidget *top_entry;
+    GtkWidget *top_progress;
+    GtkWidget *second_entry;
+    GtkWidget *other_entries_box;
+
+    /* Stack of nested Progresses */
+    GList *progresses;
+
+    /* Number of steps in top-level progress or -1 */
+    guint64 max_actions;
+    guint64 current_action;
+
+    /* Log window */
+    GtkWidget *log_text;
+
+    /* Buttons */
+    GtkWidget *abort_button;
+    GtkWidget *close_button;
+    GtkWidget *close_checkbutton;
+
+    /* Flags to keep track on whether an HBCI action is running or not */
+    gboolean keep_alive;
+    GuiState state;
+
+    /* Password caching */
+    gboolean cache_passwords;
+    GHashTable *passwords;
+
+    /* Certificates handling */
+    GHashTable *accepted_certs;
+    GWEN_GUI_CHECKCERT_FN builtin_checkcert;
+
+    /* Dialogs */
+    guint32 showbox_id;
+    GHashTable *showbox_hash;
+    GtkWidget *showbox_last;
+
+    /* Cache the lowest loglevel, corresponding to the most serious warning */
+    GWEN_LOGGER_LEVEL min_loglevel;
+};
+
+struct _Progress {
+    GncGWENGui *gui;
+
+    /* Title of the process */
+    gchar *title;
+
+    /* Event source id for showing delayed */
+    guint source;
+};
+
+void
+gnc_GWEN_Gui_log_init(void)
+{
+    if (!log_gwen_gui) {
+        log_gwen_gui = GWEN_Gui_new();
+
+        /* Always use our own logging */
+        GWEN_Gui_SetLogHookFn(log_gwen_gui, loghook_cb);
+
+        /* Keep a reference so that the GWEN_GUI survives a GUI switch */
+        GWEN_Gui_Attach(log_gwen_gui);
+    }
+    GWEN_Gui_SetGui(log_gwen_gui);
+}
+
+GncGWENGui *
+gnc_GWEN_Gui_get(GtkWidget *parent)
+{
+    GncGWENGui *gui;
+
+    ENTER("parent=%p", parent);
+
+    if (full_gui) {
+        if (full_gui->state == INIT || full_gui->state == RUNNING) {
+            LEAVE("full_gui in use, state=%d", full_gui->state);
+            return NULL;
+        }
+
+        gui = full_gui;
+        gui->parent = parent;
+        reset_dialog(gui);
+        register_callbacks(gui);
+
+        LEAVE("gui=%p", gui);
+        return gui;
+    }
+
+    gui = g_new0(GncGWENGui, 1);
+    gui->parent = parent;
+    setup_dialog(gui);
+    register_callbacks(gui);
+
+    full_gui = gui;
+
+    LEAVE("new gui=%p", gui);
+    return gui;
+}
+
+void
+gnc_GWEN_Gui_release(GncGWENGui *gui)
+{
+    g_return_if_fail(gui && gui == full_gui);
+
+    /* Currently a no-op */
+    ENTER("gui=%p", gui);
+    LEAVE(" ");
+}
+
+void
+gnc_GWEN_Gui_shutdown(void)
+{
+    GncGWENGui *gui = full_gui;
+
+    ENTER(" ");
+
+    if (log_gwen_gui) {
+        GWEN_Gui_free(log_gwen_gui);
+        log_gwen_gui = NULL;
+    }
+    GWEN_Gui_SetGui(NULL);
+
+    if (!gui)
+        return;
+
+    gui->parent = NULL;
+    reset_dialog(gui);
+    if (gui->passwords)
+        g_hash_table_destroy(gui->passwords);
+    if (gui->showbox_hash)
+        g_hash_table_destroy(gui->showbox_hash);
+    if (gui->accepted_certs)
+        g_hash_table_destroy(gui->accepted_certs);
+    gtk_widget_destroy(gui->dialog);
+    g_free(gui);
+
+    full_gui = NULL;
+
+    LEAVE(" ");
+}
+
+static void
+register_callbacks(GncGWENGui *gui)
+{
+    GWEN_GUI *gwen_gui;
+
+    g_return_if_fail(gui && !gui->gwen_gui);
+
+    ENTER("gui=%p", gui);
+
+    gui->gwen_gui = gwen_gui = GWEN_Gui_new();
+
+    GWEN_Gui_SetMessageBoxFn(gwen_gui, messagebox_cb);
+    GWEN_Gui_SetInputBoxFn(gwen_gui, inputbox_cb);
+    GWEN_Gui_SetShowBoxFn(gwen_gui, showbox_cb);
+    GWEN_Gui_SetHideBoxFn(gwen_gui, hidebox_cb);
+    GWEN_Gui_SetProgressStartFn(gwen_gui, progress_start_cb);
+    GWEN_Gui_SetProgressAdvanceFn(gwen_gui, progress_advance_cb);
+    GWEN_Gui_SetProgressLogFn(gwen_gui, progress_log_cb);
+    GWEN_Gui_SetProgressEndFn(gwen_gui, progress_end_cb);
+    GWEN_Gui_SetGetPasswordFn(gwen_gui, getpassword_cb);
+    GWEN_Gui_SetSetPasswordStatusFn(gwen_gui, setpasswordstatus_cb);
+    GWEN_Gui_SetLogHookFn(gwen_gui, loghook_cb);
+    gui->builtin_checkcert = GWEN_Gui_SetCheckCertFn(gwen_gui, checkcert_cb);
+
+    GWEN_Gui_SetGui(gwen_gui);
+    SETDATA_GUI(gwen_gui, gui);
+
+    LEAVE(" ");
+}
+
+static void
+unregister_callbacks(GncGWENGui *gui)
+{
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p", gui);
+
+    if (!gui->gwen_gui) {
+        LEAVE("already unregistered");
+        return;
+    }
+
+    /* Switch to log_gwen_gui and free gui->gwen_gui */
+    gnc_GWEN_Gui_log_init();
+
+    gui->gwen_gui = NULL;
+
+    LEAVE(" ");
+}
+
+static void
+setup_dialog(GncGWENGui *gui)
+{
+    GladeXML *xml;
+    gint component_id;
+
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p", gui);
+
+    xml = gnc_glade_xml_new("aqbanking.glade", "Connection Dialog");
+
+    gui->dialog = glade_xml_get_widget(xml, "Connection Dialog");
+    g_object_set_data_full(G_OBJECT(gui->dialog), "xml", xml, g_object_unref);
+    glade_xml_signal_autoconnect_full(xml, gnc_glade_autoconnect_full_func, gui);
+    gui->entries_table = glade_xml_get_widget(xml, "entries_table");
+    gui->top_entry = glade_xml_get_widget(xml, "top_entry");
+    gui->top_progress = glade_xml_get_widget(xml, "top_progress");
+    gui->second_entry = glade_xml_get_widget(xml, "second_entry");
+    gui->other_entries_box = NULL;
+    gui->progresses = NULL;
+    gui->log_text = glade_xml_get_widget(xml, "log_text");
+    gui->abort_button = glade_xml_get_widget(xml, "abort_button");
+    gui->close_button = glade_xml_get_widget(xml, "close_button");
+    gui->close_checkbutton = glade_xml_get_widget(xml, "close_checkbutton");
+    gui->accepted_certs = NULL;
+    gui->showbox_hash = NULL;
+    gui->showbox_id = 1;
+
+    gtk_toggle_button_set_active(
+        GTK_TOGGLE_BUTTON(gui->close_checkbutton),
+        gnc_gconf_get_bool(GCONF_SECTION_AQBANKING, KEY_CLOSE_ON_FINISH, NULL));
+
+    component_id = gnc_register_gui_component(GWEN_GUI_CM_CLASS, NULL,
+                                              cm_close_handler, gui);
+    gnc_gui_component_set_session(component_id, gnc_get_current_session());
+
+    reset_dialog(gui);
+
+    LEAVE(" ");
+}
+
+static void
+enable_password_cache(GncGWENGui *gui, gboolean enabled)
+{
+    g_return_if_fail(gui);
+
+    if (enabled && !gui->passwords) {
+        /* Remember passwords in memory, mapping tokens to passwords */
+        gui->passwords = g_hash_table_new_full(
+            g_str_hash, g_str_equal, (GDestroyNotify) g_free,
+            (GDestroyNotify) erase_password);
+    } else if (!enabled && gui->passwords) {
+        /* Erase and free remembered passwords from memory */
+        g_hash_table_destroy(gui->passwords);
+        gui->passwords = NULL;
+    }
+    gui->cache_passwords = enabled;
+}
+
+static void
+reset_dialog(GncGWENGui *gui)
+{
+    gboolean cache_passwords;
+
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p", gui);
+
+    gtk_entry_set_text(GTK_ENTRY(gui->top_entry), "");
+    gtk_entry_set_text(GTK_ENTRY(gui->second_entry), "");
+    g_list_foreach(gui->progresses, (GFunc) free_progress, NULL);
+    g_list_free(gui->progresses);
+    gui->progresses = NULL;
+
+    if (gui->other_entries_box) {
+        gtk_table_resize(GTK_TABLE(gui->entries_table),
+                         OTHER_ENTRIES_ROW_OFFSET, 2);
+        gtk_widget_destroy(gui->other_entries_box);
+        gui->other_entries_box = NULL;
+    }
+    if (gui->showbox_hash)
+        g_hash_table_destroy(gui->showbox_hash);
+    gui->showbox_last = NULL;
+    gui->showbox_hash = g_hash_table_new_full(
+        NULL, NULL, NULL, (GDestroyNotify) gtk_widget_destroy);
+
+    if (gui->parent)
+        gtk_window_set_transient_for(GTK_WINDOW(gui->dialog),
+                                     GTK_WINDOW(gui->parent));
+    gnc_restore_window_size(GCONF_SECTION_CONNECTION, GTK_WINDOW(gui->dialog));
+
+    gui->keep_alive = TRUE;
+    gui->state = INIT;
+    gui->min_loglevel = GWEN_LoggerLevel_Verbous;
+
+    cache_passwords = gnc_gconf_get_bool(GCONF_SECTION_AQBANKING,
+                                         KEY_REMEMBER_PIN, NULL);
+    enable_password_cache(gui, cache_passwords);
+
+    if (!gui->accepted_certs)
+        gui->accepted_certs = g_hash_table_new_full(
+            g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
+
+    LEAVE(" ");
+}
+
+static void
+set_running(GncGWENGui *gui)
+{
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p", gui);
+
+    gui->state = RUNNING;
+    gtk_widget_set_sensitive(gui->abort_button, TRUE);
+    gtk_widget_set_sensitive(gui->close_button, FALSE);
+    gui->keep_alive = TRUE;
+
+    LEAVE(" ");
+}
+
+static void
+set_finished(GncGWENGui *gui)
+{
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p", gui);
+
+    /* Do not serve as GUI anymore */
+    gui->state = FINISHED;
+    unregister_callbacks(gui);
+
+    gtk_widget_set_sensitive(gui->abort_button, FALSE);
+    gtk_widget_set_sensitive(gui->close_button, TRUE);
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->close_checkbutton)))
+        hide_dialog(gui);
+
+    LEAVE(" ");
+}
+
+static void
+set_aborted(GncGWENGui *gui)
+{
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p", gui);
+
+    /* Do not serve as GUI anymore */
+    gui->state = ABORTED;
+    unregister_callbacks(gui);
+
+    gtk_widget_set_sensitive(gui->abort_button, FALSE);
+    gtk_widget_set_sensitive(gui->close_button, TRUE);
+    gui->keep_alive = FALSE;
+
+    LEAVE(" ");
+}
+
+static void
+show_dialog(GncGWENGui *gui, gboolean clear_log)
+{
+    gboolean cache_pin;
+
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p, clear_log=%d", gui, clear_log);
+
+    gtk_widget_show(gui->dialog);
+
+    /* Clear the log window */
+    if (clear_log) {
+        gtk_text_buffer_set_text(
+            gtk_text_view_get_buffer(GTK_TEXT_VIEW(gui->log_text)), "", 0);
+    }
+
+    LEAVE(" ");
+}
+
+static void
+hide_dialog(GncGWENGui *gui)
+{
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p", gui);
+
+    /* Hide the dialog */
+    gtk_widget_hide(gui->dialog);
+
+    /* Remember whether the dialog is to be closed when finished */
+    gnc_gconf_set_bool(
+        GCONF_SECTION_AQBANKING, KEY_CLOSE_ON_FINISH,
+        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->close_checkbutton)),
+        NULL);
+
+    /* Remember size and position of the dialog */
+    gnc_save_window_size(GCONF_SECTION_CONNECTION, GTK_WINDOW(gui->dialog));
+
+    /* Do not serve as GUI anymore */
+    gui->state = HIDDEN;
+    unregister_callbacks(gui);
+
+    LEAVE(" ");
+}
+
+static gboolean
+show_progress_cb(gpointer user_data)
+{
+    Progress *progress = user_data;
+    GncGWENGui *gui;
+    GList *item;
+
+    g_return_val_if_fail(progress, FALSE);
+
+    ENTER("progress=%p", progress);
+
+    show_progress(progress->gui, progress);
+
+    LEAVE(" ");
+    return FALSE;
+}
+
+/**
+ * Show all processes down to and including @a progress.
+ */
+static void
+show_progress(GncGWENGui *gui, Progress *progress)
+{
+    GList *item;
+    Progress *current;
+
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p, progress=%p", gui, progress);
+
+    for (item = g_list_last(gui->progresses); item; item = item->prev) {
+        current = (Progress*) item->data;
+
+        if (!current->source
+            && current != progress)
+            /* Already showed */
+            continue;
+
+        /* Show it */
+        if (!item->next) {
+            /* Top-level progress */
+            show_dialog(gui, TRUE);
+            gtk_entry_set_text(GTK_ENTRY(gui->top_entry), current->title);
+        } else if (!item->next->next) {
+            /* Second-level progress */
+            gtk_entry_set_text(GTK_ENTRY(gui->second_entry), current->title);
+        } else {
+            /* Other progress */
+            GtkWidget *entry = gtk_entry_new();
+            GtkWidget *box = gui->other_entries_box;
+            gboolean new_box = box == NULL;
+
+            gtk_entry_set_text(GTK_ENTRY(entry), current->title);
+            if (new_box)
+                gui->other_entries_box = box = gtk_vbox_new(TRUE, 6);
+            gtk_box_pack_start_defaults(GTK_BOX(box), entry);
+            gtk_widget_show(entry);
+            if (new_box) {
+                gtk_table_resize(GTK_TABLE(gui->entries_table),
+                                 OTHER_ENTRIES_ROW_OFFSET + 1, 2);
+                gtk_table_attach_defaults(
+                    GTK_TABLE(gui->entries_table), box, 1, 2,
+                    OTHER_ENTRIES_ROW_OFFSET, OTHER_ENTRIES_ROW_OFFSET + 1);
+                gtk_widget_show(box);
+            }
+        }
+
+        if (current->source) {
+            /* Stop delayed call */
+            g_source_remove(current->source);
+            current->source = 0;
+        }
+
+        if (current == progress)
+            break;
+    }
+
+    LEAVE(" ");
+}
+
+/**
+ * Hide all processes up to and including @a progress.
+ */
+static void
+hide_progress(GncGWENGui *gui, Progress *progress)
+{
+    GList *item;
+    Progress *current;
+
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p, progress=%p", gui, progress);
+
+    for (item = gui->progresses; item; item = item->next) {
+        current = (Progress*) item->data;
+
+        if (current->source) {
+            /* Not yet showed */
+            g_source_remove(current->source);
+            current->source = 0;
+            if (current == progress)
+                break;
+            else
+                continue;
+        }
+
+        /* Hide it */
+        if (!item->next) {
+            /* Top-level progress */
+            gtk_entry_set_text(GTK_ENTRY(gui->second_entry), "");
+        } else if (!item->next->next) {
+            /* Second-level progress */
+            gtk_entry_set_text(GTK_ENTRY(gui->second_entry), "");
+        } else {
+            /* Other progress */
+            GtkWidget *box = gui->other_entries_box;
+            GList *entries;
+
+            g_return_if_fail(box);
+            entries = gtk_container_get_children(GTK_CONTAINER(box));
+            g_return_if_fail(entries);
+            if (entries->next) {
+                /* Another progress is still to be showed */
+                gtk_widget_destroy(GTK_WIDGET(g_list_last(entries)->data));
+            } else {
+                /* Last other progress to be hided */
+                gtk_table_resize(GTK_TABLE(gui->entries_table),
+                                 OTHER_ENTRIES_ROW_OFFSET, 2);
+                gtk_widget_destroy(box);
+                gui->other_entries_box = NULL;
+            }
+            g_list_free(entries);
+        }
+
+        if (current == progress)
+            break;
+    }
+
+    LEAVE(" ");
+}
+
+static void
+free_progress(Progress *progress, gpointer unused)
+{
+    if (progress->source)
+        g_source_remove(progress->source);
+    g_free(progress->title);
+    g_free(progress);
+}
+
+static gboolean
+keep_alive(GncGWENGui *gui)
+{
+    g_return_val_if_fail(gui, FALSE);
+
+    ENTER("gui=%p", gui);
+
+    /* Let the widgets be redrawn */
+    while (g_main_context_iteration(NULL, FALSE));
+
+    LEAVE("alive=%d", gui->keep_alive);
+    return gui->keep_alive;
+}
+
+static void
+cm_close_handler(gpointer user_data)
+{
+    GncGWENGui *gui = user_data;
+
+    g_return_if_fail(gui);
+
+    ENTER("gui=%p", gui);
+
+    /* FIXME */
+    set_aborted(gui);
+
+    LEAVE(" ");
+}
+
+static void
+erase_password(gchar *password)
+{
+    g_return_if_fail(password);
+
+    ENTER(" ");
+
+    memset(password, 0, strlen(password));
+    g_free(password);
+
+    LEAVE(" ");
+}
+
+/**
+ * Find first <[Hh][Tt][Mm][Ll]> and cut off the string there.
+ */
+static gchar *
+strip_html(gchar *text)
+{
+    gchar *p, *q;
+
+    if (!text)
+        return NULL;
+
+    p = text;
+    while (strchr(p, '<')) {
+        q = p + 1;
+        if (*q && toupper(*q++) == 'H'
+            && *q && toupper(*q++) == 'T'
+            && *q && toupper(*q++) == 'M'
+            && *q && toupper(*q) == 'L') {
+            *p = '\0';
+            return text;
+        }
+        p++;
+    }
+    return text;
+}
+
+static void
+get_input(GncGWENGui *gui, guint32 flags, const gchar *title, const gchar *text,
+          gchar **input, gint min_len, gint max_len)
+{
+    GladeXML *xml;
+    GtkWidget *dialog;
+    GtkWidget *heading_label;
+    GtkWidget *input_entry;
+    GtkWidget *confirm_entry;
+    GtkWidget *confirm_label;
+    GtkWidget *remember_pin_checkbutton;
+    const gchar *internal_input, *internal_confirmed;
+    gboolean confirm = (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) != 0;
+    gboolean hidden = (flags & GWEN_GUI_INPUT_FLAGS_SHOW) == 0;
+    gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0;
+    gint retval;
+
+    g_return_if_fail(input);
+    g_return_if_fail(max_len >= min_len && max_len > 0);
+
+    ENTER(" ");
+
+    /* Set up dialog */
+    xml = gnc_glade_xml_new("aqbanking.glade", "Password Dialog");
+    dialog = glade_xml_get_widget(xml, "Password Dialog");
+    g_object_set_data_full(G_OBJECT(dialog), "xml", xml, g_object_unref);
+
+    heading_label = glade_xml_get_widget(xml, "heading_label");
+    input_entry = glade_xml_get_widget(xml, "input_entry");
+    confirm_entry = glade_xml_get_widget(xml, "confirm_entry");
+    confirm_label = glade_xml_get_widget(xml, "confirm_label");
+    remember_pin_checkbutton = glade_xml_get_widget(xml, "remember_pin");
+    if (is_tan) {
+        gtk_widget_hide(remember_pin_checkbutton);
+    } else {
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remember_pin_checkbutton),
+                                     gui->cache_passwords);
+    }
+
+    if (gui->parent)
+        gtk_window_set_transient_for(GTK_WINDOW(dialog),
+                                     GTK_WINDOW(gui->parent));
+    if (title)
+        gtk_window_set_title(GTK_WINDOW(dialog), title);
+
+    if (text) {
+        gchar *raw_text = strip_html(g_strdup(text));
+        gtk_label_set_text(GTK_LABEL(heading_label), raw_text);
+        g_free(raw_text);
+    }
+
+    if (*input) {
+        gtk_entry_set_text(GTK_ENTRY(input_entry), *input);
+        erase_password(*input);
+        *input = NULL;
+    }
+
+    if (confirm) {
+        gtk_entry_set_activates_default(GTK_ENTRY(input_entry), FALSE);
+        gtk_entry_set_activates_default(GTK_ENTRY(confirm_entry), TRUE);
+        gtk_entry_set_max_length(GTK_ENTRY(input_entry), max_len);
+        gtk_entry_set_max_length(GTK_ENTRY(confirm_entry), max_len);
+    } else {
+        gtk_entry_set_activates_default(GTK_ENTRY(input_entry), TRUE);
+        gtk_entry_set_max_length(GTK_ENTRY(input_entry), max_len);
+        gtk_widget_hide(confirm_entry);
+        gtk_widget_hide(confirm_label);
+    }
+    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
+
+    /* Ask the user until he enters a valid input or cancels */
+    while (TRUE) {
+        gboolean remember_pin;
+
+        if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
+            break;
+
+        if (!is_tan) {
+            /* Enable or disable the password cache */
+            remember_pin = gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(remember_pin_checkbutton));
+            enable_password_cache(gui, remember_pin);
+            gnc_gconf_set_bool(GCONF_SECTION_AQBANKING, KEY_REMEMBER_PIN,
+                               remember_pin, NULL);
+        }
+
+        internal_input = gtk_entry_get_text(GTK_ENTRY(input_entry));
+        if (strlen(internal_input) < min_len) {
+            gboolean retval;
+            gchar *msg = g_strdup_printf(
+                _("The PIN needs to be at least %d characters \n"
+                  "long. Do you want to try again?"), min_len);
+            retval = gnc_verify_dialog(gui->parent, TRUE, "%s", msg);
+            g_free(msg);
+            if (!retval)
+                break;
+            continue;
+        }
+
+        if (!confirm) {
+            *input = g_strdup(internal_input);
+            break;
+        }
+
+        internal_confirmed = gtk_entry_get_text(GTK_ENTRY(confirm_entry));
+        if (strcmp(internal_input, internal_confirmed) == 0) {
+            *input = g_strdup(internal_input);
+            break;
+        }
+    }
+
+    /* This trashes passwords in the entries' memory as well */
+    gtk_widget_destroy(dialog);
+
+    LEAVE("input %s", *input ? "non-NULL" : "NULL");
+}
+
+static gint
+messagebox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
+              const gchar *text, const gchar *b1,const gchar *b2,
+              const gchar *b3, guint32 guiid)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    GtkWidget *dialog;
+    GtkWidget *vbox;
+    GtkWidget *label;
+    gchar *raw_text;
+    gint result;
+
+    ENTER("gui=%p, flags=%d, title=%s, b1=%s, b2=%s, b3=%s", gui, flags,
+          title ? title : "(null)", b1 ? b1 : "(null)", b2 ? b2 : "(null)",
+          b3 ? b3 : "(null)");
+
+    dialog = gtk_dialog_new_with_buttons(
+        title, gui->parent ? GTK_WINDOW(gui->parent) : NULL,
+        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+        b1, 1, b2, 2, b3, 3, (gchar*) NULL);
+
+    raw_text = strip_html(g_strdup(text));
+    label = gtk_label_new(raw_text);
+    g_free(raw_text);
+    gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+    vbox = gtk_vbox_new(TRUE, 0);
+    gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+    gtk_container_add(GTK_CONTAINER(vbox), label);
+    gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), vbox);
+    gtk_widget_show_all(dialog);
+
+    result = gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+
+    if (result<1 || result>3) {
+        g_warning("messagebox_cb: Bad result %d", result);
+        result = 0;
+    }
+
+    LEAVE("result=%d", result);
+    return result;
+}
+
+static gint
+inputbox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
+            const gchar *text, gchar *buffer, gint min_len, gint max_len,
+            guint32 guiid)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    gchar *input = NULL;
+
+    g_return_val_if_fail(gui, -1);
+
+    ENTER("gui=%p, flags=%d", gui, flags);
+
+    get_input(gui, flags, title, text, &input, min_len, max_len);
+
+    if (input) {
+        /* Copy the input to the result buffer */
+        strncpy(buffer, input, max_len);
+        buffer[max_len-1] = '\0';
+    }
+
+    LEAVE(" ");
+    return input ? 0 : -1;
+}
+
+static guint32
+showbox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
+           const gchar *text, guint32 guiid)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    GtkWidget *dialog;
+    guint32 showbox_id;
+
+    g_return_val_if_fail(gui, -1);
+
+    ENTER("gui=%p, flags=%d, title=%s", gui, flags, title ? title : "(null)");
+
+    dialog = gtk_message_dialog_new(
+        gui->parent ? GTK_WINDOW(gui->parent) : NULL, 0, GTK_MESSAGE_INFO,
+        GTK_BUTTONS_OK, "%s", text);
+
+    if (title)
+        gtk_window_set_title(GTK_WINDOW(dialog), title);
+
+    g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_hide), NULL);
+    gtk_widget_show_all(dialog);
+
+    showbox_id = gui->showbox_id++;
+    g_hash_table_insert(gui->showbox_hash, GUINT_TO_POINTER(showbox_id),
+                        dialog);
+    gui->showbox_last = dialog;
+
+    /* Give it a change to be showed */
+    if (!keep_alive(gui))
+        showbox_id = 0;
+
+    LEAVE("id=%" G_GUINT32_FORMAT, showbox_id);
+    return showbox_id;
+}
+
+static void
+hidebox_cb(GWEN_GUI *gwen_gui, guint32 id)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    GtkWidget *dialog;
+
+    g_return_if_fail(gui && gui->showbox_hash);
+
+    ENTER("gui=%p, id=%d", gui, id);
+
+    if (id == 0) {
+        if (gui->showbox_last) {
+            g_hash_table_remove(gui->showbox_hash,
+                                GUINT_TO_POINTER(gui->showbox_id));
+            gui->showbox_last = NULL;
+        } else {
+            g_warning("hidebox_cb: Last showed message box already destroyed");
+        }
+    } else {
+        gpointer p_var;
+        p_var = g_hash_table_lookup(gui->showbox_hash, GUINT_TO_POINTER(id));
+        if (p_var) {
+            g_hash_table_remove(gui->showbox_hash, GUINT_TO_POINTER(id));
+            if (p_var == gui->showbox_last)
+                gui->showbox_last = NULL;
+        } else {
+            g_warning("hidebox_cb: Message box %d could not been found", id);
+        }
+    }
+
+    LEAVE(" ");
+}
+
+static guint32
+progress_start_cb(GWEN_GUI *gwen_gui, guint32 progressFlags, const gchar *title,
+                  const gchar *text, guint64 total, guint32 guiid)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    Progress *progress;
+
+    g_return_val_if_fail(gui, -1);
+
+    ENTER("gui=%p, flags=%d, title=%s, total=%" G_GUINT64_FORMAT, gui,
+          progressFlags, title ? title : "(null)", total);
+
+    if (!gui->progresses) {
+        /* Top-level progress */
+        if (progressFlags & GWEN_GUI_PROGRESS_SHOW_PROGRESS) {
+            gtk_widget_set_sensitive(gui->top_progress, TRUE);
+            gtk_progress_bar_set_fraction(
+                GTK_PROGRESS_BAR(gui->top_progress), 0.0);
+            gui->max_actions = total;
+        } else {
+            gtk_widget_set_sensitive(gui->top_progress, FALSE);
+            gui->max_actions = -1;
+        }
+        set_running(gui);
+    }
+
+    /* Put progress onto the stack */
+    progress = g_new0(Progress, 1);
+    progress->gui = gui;
+    progress->title = title ? g_strdup(title) : "";
+    gui->progresses = g_list_prepend(gui->progresses, progress);
+
+    if (progressFlags & GWEN_GUI_PROGRESS_DELAY) {
+        /* Show progress later */
+        progress->source = g_timeout_add(GWEN_GUI_DELAY_SECS * 1000,
+                                         (GSourceFunc) show_progress_cb,
+                                         progress);
+    } else {
+        /* Show it now */
+        progress->source = 0;
+        show_progress(gui, progress);
+    }
+
+    LEAVE(" ");
+    return g_list_length(gui->progresses);
+}
+
+static gint
+progress_advance_cb(GWEN_GUI *gwen_gui, guint32 id, guint64 progress)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+
+    g_return_val_if_fail(gui, -1);
+
+    ENTER("gui=%p, progress=%" G_GUINT64_FORMAT, gui, progress);
+
+    if (id == 1                                  /* top-level progress */
+        && gui->max_actions > 0                  /* progressbar active */
+        && progress != GWEN_GUI_PROGRESS_NONE) { /* progressbar update needed */
+        if (progress == GWEN_GUI_PROGRESS_ONE)
+            gui->current_action++;
+        else
+            gui->current_action = progress;
+
+        gtk_progress_bar_set_fraction(
+            GTK_PROGRESS_BAR(gui->top_progress),
+            ((gdouble) gui->current_action) / ((gdouble) gui->max_actions));
+    }
+
+    LEAVE(" ");
+    return !keep_alive(gui);
+}
+
+static gint
+progress_log_cb(GWEN_GUI *gwen_gui, guint32 id, GWEN_LOGGER_LEVEL level,
+                const gchar *text)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    GtkTextBuffer *tb;
+    GtkTextView *tv;
+
+    g_return_val_if_fail(gui, -1);
+
+    ENTER("gui=%p, text=%s", gui, text ? text : "(null)");
+
+    tv = GTK_TEXT_VIEW(gui->log_text);
+    tb = gtk_text_view_get_buffer(tv);
+    gtk_text_buffer_insert_at_cursor(tb, text, -1);
+    gtk_text_buffer_insert_at_cursor(tb, "\n", -1);
+
+    /* Scroll to the end of the buffer */
+    gtk_text_view_scroll_to_mark(tv, gtk_text_buffer_get_insert(tb),
+                                 0.0, FALSE, 0.0, 0.0);
+
+    /* Cache loglevel */
+    if (level < gui->min_loglevel)
+        gui->min_loglevel = level;
+
+    LEAVE(" ");
+    return !keep_alive(gui);
+}
+
+static gint
+progress_end_cb(GWEN_GUI *gwen_gui, guint32 id)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    Progress *progress;
+
+    g_return_val_if_fail(gui, -1);
+    g_return_val_if_fail(id == g_list_length(gui->progresses), -1);
+
+    ENTER("gui=%p, id=%d", gui, id);
+
+    if (gui->state != RUNNING) {
+        /* Ignore finishes of progresses we do not track */
+        LEAVE("not running anymore");
+        return 0;
+    }
+
+    /* Hide progress */
+    progress = (Progress*) gui->progresses->data;
+    hide_progress(gui, progress);
+
+    /* Remove progress from stack and free memory */
+    gui->progresses = g_list_delete_link(gui->progresses, gui->progresses);
+    free_progress(progress, NULL);
+
+    if (!gui->progresses) {
+        /* top-level progress finished */
+        set_finished(gui);
+    }
+
+    LEAVE(" ");
+    return 0;
+}
+
+static gint
+getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
+               const gchar *title, const gchar *text, gchar *buffer,
+               gint min_len, gint max_len, guint32 guiid)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    gchar *password = NULL;
+    gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0;
+
+    g_return_val_if_fail(gui, -1);
+
+    ENTER("gui=%p, flags=%d, token=%s", gui, flags, token ? token : "(null");
+
+    /* Check remembered passwords, excluding TANs */
+    if (!is_tan && gui->cache_passwords && gui->passwords && token) {
+        if (flags & GWEN_GUI_INPUT_FLAGS_RETRY) {
+            /* If remembered, remove password from memory */
+            g_hash_table_remove(gui->passwords, token);
+        } else {
+            gpointer p_var;
+            if (g_hash_table_lookup_extended(gui->passwords, token, NULL,
+                                             &p_var)) {
+                /* Copy the password to the result buffer */
+                password = p_var;
+                strncpy(buffer, password, max_len);
+                buffer[max_len-1] = '\0';
+
+                LEAVE("chose remembered password");
+                return 0;
+            }
+        }
+    }
+
+    get_input(gui, flags, title, text, &password, min_len, max_len);
+
+    if (password) {
+        /* Copy the password to the result buffer */
+        strncpy(buffer, password, max_len);
+        buffer[max_len-1] = '\0';
+
+        if (!is_tan && token) {
+            if (gui->cache_passwords && gui->passwords) {
+                /* Remember password */
+                DEBUG("Remember password, token=%s", token);
+                g_hash_table_insert(gui->passwords, g_strdup(token), password);
+            } else {
+                /* Remove the password from memory */
+                DEBUG("Forget password, token=%s", token);
+                erase_password(password);
+            }
+        }
+    }
+
+    LEAVE(" ");
+    return password ? 0 : -1;
+}
+
+static gint
+setpasswordstatus_cb(GWEN_GUI *gwen_gui, const gchar *token, const gchar *pin,
+                     GWEN_GUI_PASSWORD_STATUS status, guint32 guiid)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+
+    g_return_val_if_fail(gui, -1);
+
+    ENTER("gui=%p, token=%s, status=%d", gui, token ? token : "(null)", status);
+
+    if (gui->passwords && status != GWEN_Gui_PasswordStatus_Ok) {
+        /* If remembered, remove password from memory */
+        g_hash_table_remove(gui->passwords, token);
+    }
+
+    LEAVE(" ");
+    return 0;
+}
+
+static gint
+loghook_cb(GWEN_GUI *gwen_gui, const gchar *log_domain,
+           GWEN_LOGGER_LEVEL priority, const gchar *text)
+{
+    if (G_LIKELY(priority < n_log_levels))
+        g_log(log_domain, log_levels[priority], "%s", text);
+
+    return 1;
+}
+
+static gint
+checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
+             GWEN_IO_LAYER *io, guint32 guiid)
+{
+    GncGWENGui *gui = GETDATA_GUI(gwen_gui);
+    const gchar *hash, *status;
+    struct md5_ctx md5_context;
+    gchar cert_hash[16];
+    gint retval;
+
+    g_return_val_if_fail(gui && gui->accepted_certs, -1);
+
+    ENTER("gui=%p, cert=%p", gui, cert);
+
+    hash = GWEN_SslCertDescr_GetFingerPrint(cert);
+    status = GWEN_SslCertDescr_GetStatusText(cert);
+
+    /* Operate on an md5sum of the pair of hash and status */
+    md5_init_ctx(&md5_context);
+    md5_process_bytes(hash, strlen(hash), &md5_context);
+    md5_process_bytes(status, strlen(status), &md5_context);
+    md5_finish_ctx(&md5_context, cert_hash);
+
+    if (g_hash_table_lookup(gui->accepted_certs, cert_hash)) {
+        /* Certificate has been accepted before */
+        LEAVE("Automatically accepting certificate");
+        return 0;
+    }
+
+    retval = gui->builtin_checkcert(gwen_gui, cert, io, guiid);
+    if (retval == 0) {
+        /* Certificate has been accepted */
+        g_hash_table_insert(gui->accepted_certs, g_strdup(cert_hash), cert_hash);
+    }
+
+    LEAVE("retval=%d", retval);
+    return retval;
+}
+
+gboolean
+ggg_delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data){
+    GncGWENGui *gui = user_data;
+
+    g_return_val_if_fail(gui, FALSE);
+
+    ENTER("gui=%p, state=%d", gui, gui->state);
+
+    if (gui->state == RUNNING) {
+        const char *still_running_msg =
+            _("The Online Banking job is still running; are you "
+              "sure you want to cancel?");
+        if (!gnc_verify_dialog(gui->dialog, FALSE, "%s", still_running_msg))
+            return FALSE;
+
+        set_aborted(gui);
+    }
+
+    hide_dialog(gui);
+
+    LEAVE(" ");
+    return TRUE;
+}
+
+void
+ggg_abort_clicked_cb(GtkButton *button, gpointer user_data)
+{
+    GncGWENGui *gui = user_data;
+
+    g_return_if_fail(gui && gui->state == RUNNING);
+
+    ENTER("gui=%p", gui);
+
+    set_aborted(gui);
+
+    LEAVE(" ");
+}
+
+void
+ggg_close_clicked_cb(GtkButton *button, gpointer user_data)
+{
+    GncGWENGui *gui = user_data;
+
+    g_return_if_fail(gui);
+    g_return_if_fail(gui->state == FINISHED || gui->state == ABORTED);
+
+    ENTER("gui=%p", gui);
+
+    hide_dialog(gui);
+
+    LEAVE(" ");
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-gwen-gui.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-gwen-gui.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-gwen-gui.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,80 @@
+/*
+ * gnc-gwen-gui.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-gwen-gui.h
+ * @brief GUI callbacks for AqBanking
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_GWEN_GUI_H
+#define GNC_GWEN_GUI_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GncGWENGui GncGWENGui;
+
+/**
+ * Hook our logging into the gwenhywfar logging framework by creating a
+ * minimalistic GWEN_GUI with only a callback for Gwen_Gui_LogHook().  This
+ * function can be called more than once, it will unref and replace the
+ * currently set GWEN_GUI though.
+ */
+void gnc_GWEN_Gui_log_init(void);
+
+/**
+ * When called for the first time, create a unique GncGWENGui object featuring a
+ * GWEN_GUI with all necessary callbacks, which can serve as a user interface
+ * for AqBanking jobs.  On later calls, return the object only when it is not
+ * active and save to use.  Typically, you only need to call
+ * gnc_GWEN_Gui_release() once your job has finished.
+ *
+ * @param parent Widget to set new dialogs transient for, may be NULL
+ * @return The unique GncGWENGui object or NULL otherwise
+ */
+GncGWENGui *gnc_GWEN_Gui_get(GtkWidget *parent);
+
+/**
+ * Currently a no-op.  The GncGWENGui will not be freed and it is considered
+ * finished once the first tracked progress has ended.
+ *
+ * @param gui The GncGwenGUI returned by gnc_GWEN_Gui_get()
+ */
+void gnc_GWEN_Gui_release(GncGWENGui *gui);
+
+/**
+ * Free all memory related to both the full-blown and minimalistic GUI objects.
+ */
+void gnc_GWEN_Gui_shutdown(void);
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* GNC_GWEN_GUI_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking-ui.xml
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking-ui.xml	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking-ui.xml	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,34 @@
+<ui>
+  <menubar>
+    <menu name="File" action="FileAction">
+      <menu name="FileImport" action="FileImportAction">
+        <placeholder name="FileImportPlaceholder">
+           <menuitem name="FileMt940Import"     action="Mt940ImportAction"/>
+           <menuitem name="FileMt942Import"     action="Mt942ImportAction"/>
+           <menuitem name="FileDtausImport"     action="DtausImportAction"/>
+           <menuitem name="FileDtausImportsend" action="DtausImportSendAction"/>
+           <!-- When CsvImport works:
+           <menuitem name="FileCsvImport"       action="CsvImportAction"/>
+           <menuitem name="FileCsvImportsend"   action="CsvImportSendAction"/>
+           -->
+        </placeholder>
+      </menu>
+    </menu>
+    <menu name="Actions" action="ActionsAction">
+      <placeholder name="ActionsPlaceholder">
+        <menu name="OnlineActions" action="OnlineActionsAction">
+          <menuitem name="ABGetBalance"         action="ABGetBalanceAction"/>
+          <menuitem name="ABGetTrans"           action="ABGetTransAction"/>
+          <menuitem name="ABIssueTrans"         action="ABIssueTransAction"/>
+          <menuitem name="ABIssueIntTrans"      action="ABIssueIntTransAction"/>
+          <menuitem name="ABIssueDirectDebit"   action="ABIssueDirectDebitAction"/>
+        </menu>
+      </placeholder>
+    </menu>
+    <menu name="Tools" action="ToolsAction">
+      <placeholder name="ToolsPlaceholder">
+        <menuitem name="ABSetup"                action="ABSetupAction"/>
+     </placeholder>
+    </menu>
+  </menubar>
+</ui>

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,472 @@
+/*
+ * gnc-plugin-aqbanking.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gnc-plugin-aqbanking.c
+ * @brief Plugin registration of the AqBanking module
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2003 David Hampton <hampton at employees.org>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "Account.h"
+#include "dialog-ab-trans.h"
+#include "druid-ab-initial.h"
+#include "gnc-ab-getbalance.h"
+#include "gnc-ab-gettrans.h"
+#include "gnc-ab-transfer.h"
+#include "gnc-ab-utils.h"
+#include "gnc-file-aqb-import.h"
+#include "gnc-gconf-utils.h"
+#include "gnc-plugin-aqbanking.h"
+#include "gnc-plugin-manager.h"
+#include "gnc-plugin-page-account-tree.h"
+#include "gnc-plugin-page-register.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = G_LOG_DOMAIN;
+
+static void gnc_plugin_aqbanking_class_init(GncPluginAqBankingClass *klass);
+static void gnc_plugin_aqbanking_init(GncPluginAqBanking *plugin);
+static void gnc_plugin_aqbanking_add_to_window(GncPlugin *plugin, GncMainWindow *window, GQuark type);
+static void gnc_plugin_aqbanking_remove_from_window(GncPlugin *plugin, GncMainWindow *window, GQuark type);
+
+/* Object callbacks */
+static void gnc_plugin_ab_main_window_page_added(GncMainWindow *window, GncPluginPage *page, gpointer user_data);
+static void gnc_plugin_ab_main_window_page_changed(GncMainWindow *window, GncPluginPage *page, gpointer user_data);
+static void gnc_plugin_ab_account_selected(GncPluginPage *plugin_page, Account *account, gpointer user_data);
+
+/* Auxiliary functions */
+static Account *main_window_to_account(GncMainWindow *window);
+
+/* Command callbacks */
+static void gnc_plugin_ab_cmd_setup(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_get_balance(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_get_transactions(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_issue_transaction(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_issue_inttransaction(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_issue_direct_debit(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_mt940_import(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_mt942_import(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_dtaus_import(GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_ab_cmd_dtaus_importsend(GtkAction *action, GncMainWindowActionData *data);
+
+#define PLUGIN_ACTIONS_NAME "gnc-plugin-aqbanking-actions"
+#define PLUGIN_UI_FILENAME  "gnc-plugin-aqbanking-ui.xml"
+
+static GtkActionEntry gnc_plugin_actions [] = {
+    /* Menus */
+    { "OnlineActionsAction", NULL, N_("_Online Actions"), NULL, NULL, NULL },
+
+    /* Menu Items */
+    { "ABSetupAction", NULL, N_("_Online Banking Setup..."), NULL,
+      N_("Initial setup of Online Banking access (HBCI, or OFX DirectConnect, using AqBanking)"),
+      G_CALLBACK(gnc_plugin_ab_cmd_setup) },
+    { "ABGetBalanceAction", NULL, N_("Get _Balance"), NULL,
+      N_("Get the account balance online through Online Banking"),
+      G_CALLBACK(gnc_plugin_ab_cmd_get_balance) },
+    { "ABGetTransAction", NULL, N_("Get _Transactions..."), NULL,
+      N_("Get the transactions online through Online Banking"),
+      G_CALLBACK(gnc_plugin_ab_cmd_get_transactions) },
+    { "ABIssueTransAction", NULL, N_("_Issue Transaction..."), NULL,
+      N_("Issue a new transaction online through Online Banking"),
+      G_CALLBACK(gnc_plugin_ab_cmd_issue_transaction) },
+    { "ABIssueIntTransAction", NULL, N_("I_nternal Transaction..."), NULL,
+      N_("Issue a new bank-internal transaction online through Online Banking"),
+      G_CALLBACK(gnc_plugin_ab_cmd_issue_inttransaction) },
+    { "ABIssueDirectDebitAction", NULL, N_("_Direct Debit..."), NULL,
+      N_("Issue a new direct debit note online through Online Banking"),
+      G_CALLBACK(gnc_plugin_ab_cmd_issue_direct_debit) },
+
+    /* File -> Import menu item */
+    { "Mt940ImportAction", GTK_STOCK_CONVERT, N_("Import _MT940"), NULL,
+      N_("Import a MT940 file into GnuCash"),
+      G_CALLBACK(gnc_plugin_ab_cmd_mt940_import) },
+    { "Mt942ImportAction", GTK_STOCK_CONVERT, N_("Import MT94_2"), NULL,
+      N_("Import a MT942 file into GnuCash"),
+      G_CALLBACK(gnc_plugin_ab_cmd_mt942_import) },
+    { "DtausImportAction", GTK_STOCK_CONVERT, N_("Import _DTAUS"), NULL,
+      N_("Import a DTAUS file into GnuCash"),
+      G_CALLBACK(gnc_plugin_ab_cmd_dtaus_import) },
+/* #ifdef CSV_IMPORT_FUNCTIONAL */
+/*     { "CsvImportAction", GTK_STOCK_CONVERT, N_("Import _CSV"), NULL, */
+/*       N_("Import a CSV file into GnuCash"), */
+/*       G_CALLBACK(gnc_plugin_ab_cmd_csv_import) }, */
+/*     { "CsvImportSendAction", GTK_STOCK_CONVERT, N_("Import CSV and s_end..."), NULL, */
+/*       N_("Import a CSV file into GnuCash and send the transfers online through Online Banking"), */
+/*       G_CALLBACK(gnc_plugin_ab_cmd_csv_importsend) }, */
+/* #endif */
+    { "DtausImportSendAction", GTK_STOCK_CONVERT, N_("Import DTAUS and _send..."), NULL,
+      N_("Import a DTAUS file into GnuCash and send the transfers online through Online Banking"),
+      G_CALLBACK(gnc_plugin_ab_cmd_dtaus_importsend) },
+};
+static guint gnc_plugin_n_actions = G_N_ELEMENTS(gnc_plugin_actions);
+
+static const gchar *need_account_actions[] = {
+    "ABGetBalanceAction",
+    "ABGetTransAction",
+    "ABIssueTransAction",
+    "ABIssueIntTransAction",
+    "ABIssueDirectDebitAction",
+    NULL
+};
+
+/************************************************************
+ *                   Object Implementation                  *
+ ************************************************************/
+
+G_DEFINE_TYPE(GncPluginAqBanking, gnc_plugin_aqbanking, GNC_TYPE_PLUGIN)
+
+GncPlugin *
+gnc_plugin_aqbanking_new(void)
+{
+    return GNC_PLUGIN(g_object_new(GNC_TYPE_PLUGIN_AQBANKING, (gchar*) NULL));
+}
+
+static void
+gnc_plugin_aqbanking_class_init(GncPluginAqBankingClass *klass)
+{
+    GncPluginClass *plugin_class = GNC_PLUGIN_CLASS(klass);
+
+    /* plugin info */
+    plugin_class->plugin_name  = GNC_PLUGIN_AQBANKING_NAME;
+
+    /* widget addition/removal */
+    plugin_class->actions_name       = PLUGIN_ACTIONS_NAME;
+    plugin_class->actions            = gnc_plugin_actions;
+    plugin_class->n_actions          = gnc_plugin_n_actions;
+    plugin_class->ui_filename        = PLUGIN_UI_FILENAME;
+    plugin_class->add_to_window      = gnc_plugin_aqbanking_add_to_window;
+    plugin_class->remove_from_window = gnc_plugin_aqbanking_remove_from_window;
+}
+
+static void
+gnc_plugin_aqbanking_init(GncPluginAqBanking *plugin)
+{
+}
+
+/**
+ * Called when this plugin is added to a main window.  Connect a few callbacks
+ * here to track page changes.
+ */
+static void
+gnc_plugin_aqbanking_add_to_window(GncPlugin *plugin, GncMainWindow *window,
+                                   GQuark type)
+{
+    g_signal_connect(window, "page_added",
+                     G_CALLBACK(gnc_plugin_ab_main_window_page_added),
+                     plugin);
+    g_signal_connect(window, "page_changed",
+                     G_CALLBACK(gnc_plugin_ab_main_window_page_changed),
+                     plugin);
+}
+
+static void
+gnc_plugin_aqbanking_remove_from_window(GncPlugin *plugin, GncMainWindow *window,
+                                        GQuark type)
+{
+    g_signal_handlers_disconnect_by_func(
+        window, G_CALLBACK(gnc_plugin_ab_main_window_page_changed), plugin);
+    g_signal_handlers_disconnect_by_func(
+        window, G_CALLBACK(gnc_plugin_ab_main_window_page_added), plugin);
+}
+
+/************************************************************
+ *                     Object Callbacks                     *
+ ************************************************************/
+
+/**
+ * A new page has been added to a main window.  Connect a signal to it so that
+ * we can track when accounts are selected.
+ */
+static void
+gnc_plugin_ab_main_window_page_added(GncMainWindow *window, GncPluginPage *page,
+                                     gpointer user_data)
+{
+    const gchar *page_name;
+
+    ENTER("main window %p, page %p", window, page);
+    if (!GNC_IS_PLUGIN_PAGE(page)) {
+        LEAVE("no plugin_page");
+        return;
+    }
+
+    page_name = gnc_plugin_page_get_plugin_name(page);
+    if (!page_name) {
+        LEAVE("no page_name of plugin_page");
+        return;
+    }
+
+    if (strcmp(page_name, GNC_PLUGIN_PAGE_ACCOUNT_TREE_NAME) == 0) {
+        DEBUG("account tree page, adding signal");
+        g_signal_connect(page, "account_selected",
+                         G_CALLBACK(gnc_plugin_ab_account_selected), NULL);
+    }
+    LEAVE(" ");
+}
+
+/**
+ * Whenever the current page has changed, update the aqbanking menus based upon
+ * the page that is currently selected.
+ */
+static void
+gnc_plugin_ab_main_window_page_changed(GncMainWindow *window,
+                                       GncPluginPage *page, gpointer user_data)
+{
+}
+
+/**
+ * An account had been (de)selected in an "account tree" page.  Update the hbci
+ * menus appropriately.
+ */
+static void
+gnc_plugin_ab_account_selected(GncPluginPage *plugin_page, Account *account,
+                               gpointer user_data)
+{
+    GtkActionGroup *action_group;
+    GncMainWindow  *window;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE(plugin_page));
+    window = GNC_MAIN_WINDOW(plugin_page->window);
+    g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
+    action_group = gnc_main_window_get_action_group(window, PLUGIN_ACTIONS_NAME);
+    g_return_if_fail(GTK_IS_ACTION_GROUP(action_group));
+    gnc_plugin_update_actions(action_group, need_account_actions,
+                              "sensitive", account != NULL);
+
+}
+
+/************************************************************
+ *                    Auxiliary Functions                   *
+ ************************************************************/
+
+/**
+ * Given a pointer to a main window, try and extract an Account from it.  If the
+ * current page is an "account tree" page, get the account corresponding to the
+ * selected account.  (What if multiple accounts are selected?)  If the current
+ * page is a "register" page, get the head account for the register. (Returns
+ * NULL for a general ledger or search register.)
+ *
+ * @param window A pointer to a GncMainWindow object.
+ * @return A pointer to an account, if one can be determined from the current
+ * page. NULL otherwise.
+ */
+static Account *
+main_window_to_account(GncMainWindow *window)
+{
+    GncPluginPage  *page;
+    const gchar    *page_name;
+    Account        *account = NULL;
+    const gchar    *account_name;
+
+    ENTER("main window %p", window);
+    if (!GNC_IS_MAIN_WINDOW(window)) {
+        LEAVE("no main_window");
+        return NULL;
+    }
+
+    page = gnc_main_window_get_current_page(window);
+    if (!GNC_IS_PLUGIN_PAGE(page)) {
+        LEAVE("no plugin_page");
+        return NULL;
+    }
+    page_name = gnc_plugin_page_get_plugin_name(page);
+    if (!page_name) {
+        LEAVE("no page_name of plugin_page");
+        return NULL;
+    }
+
+    if (strcmp(page_name, GNC_PLUGIN_PAGE_REGISTER_NAME) == 0) {
+        DEBUG("register page");
+        account = gnc_plugin_page_register_get_account(
+            GNC_PLUGIN_PAGE_REGISTER(page));
+    } else if (strcmp(page_name, GNC_PLUGIN_PAGE_ACCOUNT_TREE_NAME) == 0) {
+        DEBUG("account tree page");
+        account = gnc_plugin_page_account_tree_get_current_account(
+            GNC_PLUGIN_PAGE_ACCOUNT_TREE(page));
+    } else {
+        account = NULL;
+    }
+    account_name = account ? xaccAccountGetName(account) : NULL;
+    LEAVE("account %s(%p)", account_name ? account_name : "(null)", account);
+    return account;
+}
+
+/************************************************************
+ *                    Command Callbacks                     *
+ ************************************************************/
+
+static void
+gnc_plugin_ab_cmd_setup(GtkAction *action, GncMainWindowActionData *data)
+{
+    ENTER("action %p, main window data %p", action, data);
+    gnc_ab_initial_druid();
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_ab_cmd_get_balance(GtkAction *action, GncMainWindowActionData *data)
+{
+    Account *account;
+
+    ENTER("action %p, main window data %p", action, data);
+    account = main_window_to_account(data->window);
+    if (account == NULL) {
+        g_message("No AqBanking account selected");
+        LEAVE("no account");
+        return;
+    }
+
+    gnc_ab_getbalance(GTK_WIDGET(data->window), account);
+
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_ab_cmd_get_transactions(GtkAction *action,
+                                   GncMainWindowActionData *data)
+{
+    Account *account;
+
+    ENTER("action %p, main window data %p", action, data);
+    account = main_window_to_account(data->window);
+    if (account == NULL) {
+        g_message("No AqBanking account selected");
+        LEAVE("no account");
+        return;
+    }
+
+    gnc_ab_gettrans(GTK_WIDGET(data->window), account);
+
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_ab_cmd_issue_transaction(GtkAction *action,
+                                    GncMainWindowActionData *data)
+{
+    Account *account;
+
+    ENTER("action %p, main window data %p", action, data);
+    account = main_window_to_account(data->window);
+    if (account == NULL) {
+        g_message("No AqBanking account selected");
+        LEAVE("no account");
+        return;
+    }
+
+    gnc_ab_maketrans(GTK_WIDGET(data->window), account, SINGLE_TRANSFER);
+
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_ab_cmd_issue_inttransaction(GtkAction *action,
+                                       GncMainWindowActionData *data)
+{
+    Account *account;
+
+    ENTER("action %p, main window data %p", action, data);
+    account = main_window_to_account(data->window);
+    if (account == NULL) {
+        g_message("No AqBanking account selected");
+        LEAVE("no account");
+        return;
+    }
+
+    gnc_ab_maketrans(GTK_WIDGET(data->window), account,
+                     SINGLE_INTERNAL_TRANSFER);
+
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_ab_cmd_issue_direct_debit(GtkAction *action,
+                                     GncMainWindowActionData *data)
+{
+    Account *account;
+
+    ENTER("action %p, main window data %p", action, data);
+    account = main_window_to_account(data->window);
+    if (account == NULL) {
+        g_message("No AqBanking account selected");
+        LEAVE("no account");
+        return;
+    }
+
+    gnc_ab_maketrans(GTK_WIDGET(data->window), account, SINGLE_DEBITNOTE);
+
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_ab_cmd_mt940_import(GtkAction *action, GncMainWindowActionData *data)
+{
+    gchar *format = gnc_gconf_get_string(GCONF_SECTION_AQBANKING,
+                                         KEY_FORMAT_SWIFT940, NULL);
+    gnc_file_aqbanking_import("swift", format ? format : "swift-mt940", FALSE);
+    g_free(format);
+}
+
+static void
+gnc_plugin_ab_cmd_mt942_import(GtkAction *action, GncMainWindowActionData *data)
+{
+    gchar *format = gnc_gconf_get_string(GCONF_SECTION_AQBANKING,
+                                         KEY_FORMAT_SWIFT942, NULL);
+    gnc_file_aqbanking_import("swift", format ? format : "swift-mt942", FALSE);
+    g_free(format);
+}
+
+static void
+gnc_plugin_ab_cmd_dtaus_import(GtkAction *action, GncMainWindowActionData *data)
+{
+    gchar *format = gnc_gconf_get_string(GCONF_SECTION_AQBANKING,
+                                         KEY_FORMAT_DTAUS, NULL);
+    gnc_file_aqbanking_import("dtaus", format ? format : "default", FALSE);
+    g_free(format);
+}
+
+static void
+gnc_plugin_ab_cmd_dtaus_importsend(GtkAction *action,
+                                   GncMainWindowActionData *data)
+{
+    gchar *format = gnc_gconf_get_string(GCONF_SECTION_AQBANKING,
+                                         KEY_FORMAT_DTAUS, NULL);
+    gnc_file_aqbanking_import("dtaus", format ? format : "default", TRUE);
+    g_free(format);
+}
+
+/************************************************************
+ *                    Plugin Bootstrapping                  *
+ ************************************************************/
+
+void
+gnc_plugin_aqbanking_create_plugin(void)
+{
+    GncPlugin *plugin = gnc_plugin_aqbanking_new();
+
+    gnc_plugin_manager_add_plugin(gnc_plugin_manager_get(), plugin);
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking.h
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking.h	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gnc-plugin-aqbanking.h	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,83 @@
+/*
+ * gnc-plugin-aqbanking.h --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @addtogroup Import_Export
+ * @{
+ * @addtogroup AqBanking
+ * @{
+ * @file gnc-plugin-aqbanking.h
+ * @brief Plugin registration of the AqBanking module
+ * @author Copyright (C) 2003 David Hampton <hampton at employees.org>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#ifndef GNC_PLUGIN_AQBANKING_H
+#define GNC_PLUGIN_AQBANKING_H
+
+#include <glib.h>
+
+#include "gnc-plugin.h"
+
+G_BEGIN_DECLS
+
+/* type macros */
+#define GNC_TYPE_PLUGIN_AQBANKING            (gnc_plugin_aqbanking_get_type())
+#define GNC_PLUGIN_AQBANKING(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), GNC_TYPE_PLUGIN_AQBANKING, GncPluginAqBanking))
+#define GNC_PLUGIN_AQBANKING_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), GNC_TYPE_PLUGIN_AQBANKING, GncPluginAqBankingClass))
+#define GNC_IS_PLUGIN_AQBANKING(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNC_TYPE_PLUGIN_AQBANKING))
+#define GNC_IS_PLUGIN_AQBANKING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNC_TYPE_PLUGIN_AQBANKING))
+#define GNC_PLUGIN_AQBANKING_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GNC_TYPE_PLUGIN_AQBANKING, GncPluginAqBankingClass))
+
+#define GNC_PLUGIN_AQBANKING_NAME "gnc-plugin-aqbanking"
+
+/* typedefs & structures */
+typedef struct {
+    GncPlugin gnc_plugin;
+} GncPluginAqBanking;
+
+typedef struct {
+    GncPluginClass gnc_plugin;
+} GncPluginAqBankingClass;
+
+/* function prototypes */
+
+/**
+ * @return The glib runtime type of an aqbanking plugin page
+ **/
+GType gnc_plugin_aqbanking_get_type(void);
+
+/**
+ * @return A new GncPluginAqBanking object
+ */
+GncPlugin* gnc_plugin_aqbanking_new(void);
+
+/**
+ * Create a new GncPluginAqBanking object and register it.
+ */
+void gnc_plugin_aqbanking_create_plugin(void);
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* GNC_PLUGIN_AQBANKING_H */

Added: gnucash/branches/2.2/src/import-export/aqbanking/gncmod-aqbanking.c
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/gncmod-aqbanking.c	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/gncmod-aqbanking.c	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,91 @@
+/*
+ * gncmod-aqbanking.c --
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ */
+
+/**
+ * @internal
+ * @file gncmod-aqbanking.c
+ * @brief Module definition/initialization for AqBanking support
+ * @author Copyright (C) 2002 Christian Stimming <stimming at tuhh.de>
+ * @author Copyright (C) 2008 Andreas Koehler <andi5.py at gmx.net>
+ */
+
+#include "config.h"
+
+#include "gnc-ab-utils.h"
+#include "gnc-module.h"
+#include "gnc-module-api.h"
+#include "gnc-plugin-aqbanking.h"
+#include "dialog-preferences.h"
+
+GNC_MODULE_API_DECL(libgncmod_aqbanking)
+
+/* version of the gnc module system interface we require */
+gint libgncmod_aqbanking_gnc_module_system_interface = 0;
+
+/* module versioning uses libtool semantics. */
+gint libgncmod_aqbanking_gnc_module_current  = 0;
+gint libgncmod_aqbanking_gnc_module_revision = 0;
+gint libgncmod_aqbanking_gnc_module_age      = 0;
+
+gchar *
+libgncmod_aqbanking_gnc_module_path(void)
+{
+    return g_strdup("gnucash/import-export/aqbanking");
+}
+
+gchar *
+libgncmod_aqbanking_gnc_module_description(void) {
+    return g_strdup("Support for Online Banking protocols");
+}
+
+gint
+libgncmod_aqbanking_gnc_module_init(gint refcount)
+{
+    /* Load modules we depend on */
+    if(!gnc_module_load("gnucash/engine", 0)
+       || !gnc_module_load("gnucash/app-utils", 0)
+       || !gnc_module_load("gnucash/gnome-utils", 0)
+       || !gnc_module_load("gnucash/import-export", 0)) {
+        return FALSE;
+    }
+
+    /* Add menu items with C callbacks */
+    gnc_plugin_aqbanking_create_plugin();
+
+    gnc_preferences_add_to_page("aqbanking.glade", "aqbanking_prefs",
+                                "Online Banking");
+
+    /* Initialize gwen library */
+    gnc_GWEN_Init();
+
+    return 1;
+}
+
+gint
+libgncmod_aqbanking_gnc_module_end(gint refcount) {
+    /* Delete the shared AB_BANKING object */
+    gnc_AB_BANKING_delete(NULL);
+
+    /* Finalize gwen library */
+    gnc_GWEN_Fini();
+
+    return 1;
+}

Added: gnucash/branches/2.2/src/import-export/aqbanking/schemas/Makefile.am
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/schemas/Makefile.am	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/schemas/Makefile.am	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,21 @@
+schemadir   = @GCONF_SCHEMA_FILE_DIR@
+schemas_in_files = \
+  apps_gnucash_dialog_hbci.schemas.in
+schema_DATA = $(schemas_in_files:.schemas.in=.schemas)
+
+ at INTLTOOL_SCHEMAS_RULE@
+
+EXTRA_DIST = $(schemas_in_files)
+
+CLEANFILES = $(schema_DATA)
+
+install-data-local:
+if GCONF_SCHEMAS_INSTALL
+	-mkdir -p $(DESTDIR)$(GCONF_SCHEMA_CONFIG_SOURCE_DIRONLY)
+	GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(schema_DATA)
+endif
+
+uninstall-local:
+if GCONF_SCHEMAS_INSTALL
+	GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-uninstall-rule $(schema_DATA)
+endif

Added: gnucash/branches/2.2/src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in
===================================================================
--- gnucash/branches/2.2/src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in	                        (rev 0)
+++ gnucash/branches/2.2/src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in	2008-07-22 22:32:29 UTC (rev 17378)
@@ -0,0 +1,143 @@
+<?xml version="1.0"?>
+<gconfschemafile>
+  <schemalist>
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/position</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/connection_dialog/window_position</applyto>
+      <owner>gnucash</owner>
+      <type>list</type>
+      <list_type>int</list_type>
+      <locale name="C">
+        <short>Window position</short>
+        <long>
+	  The X,Y coordinates of the top left corner of the dialog
+	  when it was last closed.
+	</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/geometry</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/connection_dialog/window_geometry</applyto>
+      <owner>gnucash</owner>
+      <type>list</type>
+      <list_type>int</list_type>
+      <locale name="C">
+        <short>Window geometry</short>
+        <long>
+	  The width and size of the dialog when it was last closed.
+	</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/close_on_finish</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/close_on_finish</applyto>
+      <owner>gnucash</owner>
+      <type>bool</type>
+      <default>True</default>
+      <locale name="C">
+        <short>Close dialog when finished</short>
+        <long>
+	  If active, the window will be closed automatically when you
+	  finish the HBCI/AqBanking import process. Otherwise it will
+	  stay open.
+	</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/remember_pin</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/remember_pin</applyto>
+      <owner>gnucash</owner>
+      <type>bool</type>
+      <default>False</default>
+      <locale name="C">
+        <short>Remember the PIN in memory</short>
+        <long>If active, the PIN for HBCI/AqBanking actions will be
+        remembered in memory during a session. Otherwise it will have
+        to be entered again each time during a session when it is
+        needed.</long>
+      </locale>
+    </schema>
+
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/verbose_debug</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/verbose_debug</applyto>
+      <owner>gnucash</owner>
+      <type>bool</type>
+      <default>False</default>
+      <locale name="C">
+        <short>Verbose HBCI debug messages</short>
+        <long>Enables verbose debug messages for HBCI/AqBanking Online Banking.</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/format_dtaus</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/format_dtaus</applyto>
+      <owner>gnucash</owner>
+      <type>string</type>
+      <default>default</default>
+      <locale name="C">
+        <short>DTAUS import data format</short>
+        <long>
+	  This setting specifies the data format when importing DTAUS
+	  files.  The AqBanking library offers various import formats
+	  (called "profiles") of which you can choose one here.
+	</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/format_csv</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/format_csv</applyto>
+      <owner>gnucash</owner>
+      <type>string</type>
+      <default>default</default>
+      <locale name="C">
+        <short>CSV import data format</short>
+        <long>
+	  This setting specifies the data format when importing CSV
+	  files.  The AqBanking library offers various import formats
+	  (called "profiles") of which you can choose one here.
+	</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/format_swift_mt940</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/format_swift_mt940</applyto>
+      <owner>gnucash</owner>
+      <type>string</type>
+      <default>swift-mt940</default>
+      <locale name="C">
+        <short>SWIFT MT940 import data format</short>
+        <long>
+	  This setting specifies the data format when importing SWIFT
+	  MT940 files.  The AqBanking library offers various import
+	  formats (called "profiles") of which you can choose one here.
+	</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnucash/dialogs/import/hbci/format_swift_mt942</key>
+      <applyto>/apps/gnucash/dialogs/import/hbci/format_swift_mt942</applyto>
+      <owner>gnucash</owner>
+      <type>string</type>
+      <default>swift-mt942</default>
+      <locale name="C">
+        <short>SWIFT MT942 import data format</short>
+        <long>
+	  This setting specifies the data format when importing SWIFT
+	  MT942 files.  The AqBanking library offers various import
+	  formats (called "profiles") of which you can choose one here.
+	</long>
+      </locale>
+    </schema>
+
+  </schemalist>
+</gconfschemafile>

Modified: gnucash/branches/2.2/src/import-export/hbci/Makefile.am
===================================================================
--- gnucash/branches/2.2/src/import-export/hbci/Makefile.am	2008-07-22 22:32:15 UTC (rev 17377)
+++ gnucash/branches/2.2/src/import-export/hbci/Makefile.am	2008-07-22 22:32:29 UTC (rev 17378)
@@ -56,7 +56,7 @@
   ${GLADE_LIBS} \
   ${QOF_LIBS} \
   ${GLIB_LIBS} \
-  ${HBCI_LIBS}
+  ${AQBANKING_LIBS}
 
 AM_CFLAGS = \
   -I${top_srcdir}/src \
@@ -77,7 +77,7 @@
   ${GLADE_CFLAGS} \
   ${QOF_CFLAGS} \
   ${GLIB_CFLAGS} \
-  ${HBCI_CFLAGS}
+  ${AQBANKING_CFLAGS}
 
 #gladedir = $(GNC_GLADE_DIR)
 #glade_DATA = 



More information about the gnucash-changes mailing list