r17080 - gnucash/branches/aqbanking3 - Add first sketch of aqbanking import-export module.
Andreas Köhler
andi5 at cvs.gnucash.org
Sat Apr 12 16:16:35 EDT 2008
Author: andi5
Date: 2008-04-12 16:16:35 -0400 (Sat, 12 Apr 2008)
New Revision: 17080
Trac: http://svn.gnucash.org/trac/changeset/17080
Added:
gnucash/branches/aqbanking3/src/import-export/aqbanking/
gnucash/branches/aqbanking3/src/import-export/aqbanking/Makefile.am
gnucash/branches/aqbanking3/src/import-export/aqbanking/aqbanking.glade
gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-daterange.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-daterange.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/druid-ab-initial.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/druid-ab-initial.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-kvp.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-kvp.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-utils.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-utils.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-gwen-gui.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-gwen-gui.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking-ui.xml
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gncmod-aqbanking.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/schemas/
gnucash/branches/aqbanking3/src/import-export/aqbanking/schemas/Makefile.am
gnucash/branches/aqbanking3/src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in
Modified:
gnucash/branches/aqbanking3/configure.in
gnucash/branches/aqbanking3/src/bin/gnucash-bin.c
gnucash/branches/aqbanking3/src/import-export/Makefile.am
gnucash/branches/aqbanking3/src/import-export/hbci/Makefile.am
Log:
Add first sketch of aqbanking import-export module.
Use import-export/hbci for AqBanking < 3 and import-export/aqbanking for
AqBanking >= 3. Currently the initial setup, fetching an account
balance and transactions should basically work.
Modified: gnucash/branches/aqbanking3/configure.in
===================================================================
--- gnucash/branches/aqbanking3/configure.in 2008-04-12 19:28:06 UTC (rev 17079)
+++ gnucash/branches/aqbanking3/configure.in 2008-04-12 20:16:35 UTC (rev 17080)
@@ -831,38 +831,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(HBCI, 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
@@ -1508,6 +1516,8 @@
src/import-export/ofx/test/Makefile
src/import-export/csv/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
@@ -1575,8 +1585,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/aqbanking3/src/bin/gnucash-bin.c
===================================================================
--- gnucash/branches/aqbanking3/src/bin/gnucash-bin.c 2008-04-12 19:28:06 UTC (rev 17079)
+++ gnucash/branches/aqbanking3/src/bin/gnucash-bin.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -340,6 +340,7 @@
{ "gnucash/import-export/ofx", 0, TRUE },
{ "gnucash/import-export/csv", 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/aqbanking3/src/import-export/Makefile.am
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/Makefile.am 2008-04-12 19:28:06 UTC (rev 17079)
+++ gnucash/branches/aqbanking3/src/import-export/Makefile.am 2008-04-12 20:16:35 UTC (rev 17080)
@@ -1,7 +1,7 @@
SUBDIRS = . schemas qif qif-import \
- ${OFX_DIR} ${HBCI_DIR} log-replay test csv
+ ${OFX_DIR} ${AQBANKING_DIR} log-replay test csv
DIST_SUBDIRS = schemas qif qif-import qif-io-core \
- ofx hbci log-replay test csv
+ ofx aqbanking hbci log-replay test csv
pkglib_LTLIBRARIES=libgncmod-generic-import.la
Added: gnucash/branches/aqbanking3/src/import-export/aqbanking/Makefile.am
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/Makefile.am (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/Makefile.am 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,70 @@
+SUBDIRS = . schemas
+
+pkglib_LTLIBRARIES = libgncmod-aqbanking.la
+
+libgncmod_aqbanking_la_SOURCES = \
+ dialog-daterange.c \
+ druid-ab-initial.c \
+ gnc-ab-getbalance.c \
+ gnc-ab-gettrans.c \
+ gnc-ab-kvp.c \
+ gnc-ab-utils.c \
+ gnc-gwen-gui.c \
+ gnc-plugin-aqbanking.c \
+ gncmod-aqbanking.c
+
+noinst_HEADERS = \
+ dialog-daterange.h \
+ druid-ab-initial.h \
+ gnc-ab-getbalance.h \
+ gnc-ab-gettrans.h \
+ gnc-ab-kvp.h \
+ gnc-ab-utils.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/aqbanking3/src/import-export/aqbanking/aqbanking.glade
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/aqbanking.glade (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/aqbanking.glade 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,1488 @@
+<?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>
+ <property name="urgency_hint">False</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 ("Ini-Letter").
+
+This information will be needed in the following. Press "Forward" 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 "Cancel" 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 "AqBanking Setup Wizard". 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 "Forward" 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 "Apply" 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="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="urgency_hint">False</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"><b>Progress</b></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"><b>Log Messages</b></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="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox4">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">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"><b>From</b></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"><b>To</b></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="visible">True</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="urgency_hint">False</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="urgency_hint">False</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">2</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>
+ </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>
+ <property name="urgency_hint">False</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"><b>Online Banking</b></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/aqbanking3/src/import-export/aqbanking/dialog-daterange.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-daterange.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-daterange.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/aqbanking/dialog-daterange.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-daterange.h (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-daterange.h 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/aqbanking/druid-ab-initial.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/druid-ab-initial.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/druid-ab-initial.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,777 @@
+/*
+ * 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 */
+ 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);
+
+ /* 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->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);
+
+ /* renderer = gtk_cell_renderer_toggle_new(); */
+ 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/aqbanking3/src/import-export/aqbanking/druid-ab-initial.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/druid-ab-initial.h (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/druid-ab-initial.h 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,251 @@
+/*
+ * 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"
+#include "RecnWindow.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;
+ AB_IMEXPORTER_ACCOUNTINFO *acc_info = NULL;
+ AB_ACCOUNT_STATUS *status = NULL;
+ 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_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;
+ }
+
+ /* Lookup account in context */
+ acc_info = AB_ImExporterContext_FindAccountInfo(
+ context, gnc_ab_get_account_bankcode(gnc_acc),
+ gnc_ab_get_account_accountid(gnc_acc));
+ if (!acc_info) {
+ g_warning("gnc_ab_getbalance: No accountinfo result for this account");
+ goto cleanup;
+ }
+
+ /* Lookup newest data */
+ status = gnc_ab_get_best_accountstatus(acc_info);
+ if (!status) {
+ g_warning("gnc_ab_getbalance: No accountstatus result for this account");
+ goto cleanup;
+ }
+
+ /* Lookup booked balance and time */
+ booked_bal = AB_AccountStatus_GetBookedBalance(status);
+ 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("gnc_ab_getbalance: booked_val == NULL. Assuming 0");
+ booked_value = 0.0;
+ }
+ } else {
+ g_warning("gnc_ab_getbalance: booked_bal == NULL. Assuming 0");
+ booked_tt = 0;
+ booked_value = 0.0;
+ }
+
+ /* Lookup noted balance */
+ noted_bal = AB_AccountStatus_GetNotedBalance(status);
+ if (noted_bal) {
+ noted_val = AB_Balance_GetValue(noted_bal);
+ if (noted_val)
+ noted_value = AB_Value_GetValueAsDouble(noted_val);
+ else {
+ g_warning("gnc_ab_getbalance: noted_val == NULL. Assuming 0");
+ noted_value = 0.0;
+ }
+ } else {
+ g_warning("gnc_ab_getbalance: 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(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(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(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(parent, gnc_acc, value, booked_tt);
+
+cleanup:
+ 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/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.h (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.h 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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
+ * @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/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,320 @@
+/*
+ * 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"
+#include "import-utilities.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);
+static const AB_TRANSACTION *transaction_cb(const AB_TRANSACTION *ab_trans, gpointer user_data);
+
+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;
+}
+
+/**
+ * Callback function for AB_ImExporterAccountInfo_TransactionsForEach(). The
+ * conversion from AqBanking to GnuCash transaction is done here, once for each
+ * AB_TRANSACTION.
+ */
+static const AB_TRANSACTION *
+transaction_cb(const AB_TRANSACTION *ab_trans, gpointer user_data)
+{
+ TransListData *data = user_data;
+ 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 && data, NULL);
+
+ gnc_acc = data->gnc_acc;
+ book = gnc_account_get_book(gnc_acc);
+
+ /* Create new GnuCash transaction for the given AqBanking one */
+ 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(¤t_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);
+
+ /* Instead of xaccTransCommitEdit(gnc_trans) */
+ gnc_gen_trans_list_add_trans(data->importer_generic, gnc_trans);
+
+ return NULL;
+}
+
+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;
+ AB_IMEXPORTER_ACCOUNTINFO *acc_info = 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;
+ }
+
+ /* Lookup account in context */
+ acc_info = AB_ImExporterContext_FindAccountInfo(
+ context, gnc_ab_get_account_bankcode(gnc_acc),
+ gnc_ab_get_account_accountid(gnc_acc));
+ if (!acc_info) {
+ g_warning("gnc_ab_gettrans: No accountinfo result for this account");
+ goto cleanup;
+ }
+
+ if (AB_ImExporterAccountInfo_GetFirstTransaction(acc_info)) {
+ /* Import transactions */
+
+ TransListData data;
+ data.importer_generic = gnc_gen_trans_list_new(parent, NULL, TRUE, 14);
+ data.gnc_acc = gnc_acc;
+
+ AB_ImExporterAccountInfo_TransactionsForEach(acc_info, transaction_cb,
+ &data);
+ } else {
+ /* 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 (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/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.h (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.h 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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
+ * @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/aqbanking3/src/import-export/aqbanking/gnc-ab-kvp.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-kvp.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-kvp.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,145 @@
+/*
+ * 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"
+
+/* 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);
+
+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);
+}
+
+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;
+}
Added: gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-kvp.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-kvp.h (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-kvp.h 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,124 @@
+/*
+ * 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
+ * @{ */
+
+/**
+ * Returns 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
+ */
+G_CONST_RETURN 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);
+
+/**
+ * Returns 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
+ */
+G_CONST_RETURN 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);
+
+/**
+ * Returns 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);
+
+/**
+ * Returns 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);
+
+/** @} */
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* GNC_AB_KVP_H */
Added: gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-utils.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-utils.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-utils.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,329 @@
+/*
+ * 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 "gnc-ab-kvp.h"
+#include "gnc-ab-utils.h"
+#include "gnc-glib-utils.h"
+#include "gnc-gwen-gui.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);
+
+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;
+}
+
+AB_ACCOUNT_STATUS *
+gnc_ab_get_best_accountstatus(AB_IMEXPORTER_ACCOUNTINFO *acc_info)
+{
+ AB_ACCOUNT_STATUS *item, *best = NULL;
+ const GWEN_TIME *best_time;
+
+ g_return_val_if_fail(acc_info, NULL);
+
+ item = AB_ImExporterAccountInfo_GetFirstAccountStatus(acc_info);
+ 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(acc_info);
+ }
+ return best;
+}
Added: gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-utils.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-utils.h (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-utils.h 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,161 @@
+/*
+ * 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_HBCI_UTILS_H
+#define GNC_HBCI_UTILS_H
+
+#include <glib.h>
+#include <aqbanking/banking.h>
+
+#include "Account.h"
+
+G_BEGIN_DECLS
+
+#define GCONF_SECTION_AQBANKING "dialogs/import/hbci"
+
+/**
+ * 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);
+
+/**
+ * Lookup the most recent ACCOUNT_STATUS available in an ACCOUNTINFO as
+ * extracted from an IMEXPORTER_CONTEXT. This can be used to determine the
+ * reported account balance most up-to-date.
+ *
+ * @param acc_info ACCOUNTINFO
+ * @return An AB_ACCOUNT_STATUS internal to @a acc_info, or NULL otherwise
+ */
+AB_ACCOUNT_STATUS *gnc_ab_get_best_accountstatus(
+ AB_IMEXPORTER_ACCOUNTINFO *acc_info);
+
+G_END_DECLS
+
+/** @} */
+/** @} */
+
+#endif /* GNC_AB_UTILS_H */
Added: gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-gwen-gui.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-gwen-gui.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-gwen-gui.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,1243 @@
+/*
+ * 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 "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 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);
+
+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;
+
+ /* Dialogs */
+ int 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);
+ 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);
+
+ 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->showbox_hash = NULL;
+ gui->showbox_id = 1;
+ 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");
+
+ 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
+reset_dialog(GncGWENGui *gui)
+{
+ 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;
+
+ gui->cache_passwords = gnc_gconf_get_bool(GCONF_SECTION_AQBANKING,
+ KEY_REMEMBER_PIN, NULL);
+ if (gui->cache_passwords && !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 (!gui->cache_passwords && gui->passwords) {
+ /* Erase and free remembered passwords from memory */
+ g_hash_table_destroy(gui->passwords);
+ gui->passwords = 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;
+ const gchar *internal_input, *internal_confirmed;
+ gboolean confirm = (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) != 0;
+ gboolean hidden = (flags & GWEN_GUI_INPUT_FLAGS_SHOW) == 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");
+
+ 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) {
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
+ break;
+
+ 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, 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;
+
+ 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);
+
+ g_hash_table_insert(gui->showbox_hash, GUINT_TO_POINTER(gui->showbox_id),
+ dialog);
+ gui->showbox_id++;
+ gui->showbox_last = dialog;
+
+ LEAVE(" ");
+ return 0;
+}
+
+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;
+
+ g_return_val_if_fail(gui, -1);
+
+ ENTER("gui=%p, flags=%d, token=%s", gui, flags, token ? token : "(null");
+
+ /* Check remembered passwords */
+ if (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 (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], text);
+
+ return 1;
+}
+
+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, 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/aqbanking3/src/import-export/aqbanking/gnc-gwen-gui.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-gwen-gui.h (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-gwen-gui.h 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking-ui.xml
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking-ui.xml (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking-ui.xml 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -0,0 +1,389 @@
+/*
+ * 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 "druid-ab-initial.h"
+#include "gnc-ab-getbalance.h"
+#include "gnc-ab-gettrans.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);
+
+#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)
+{
+ /* FIXME */
+}
+
+static void
+gnc_plugin_ab_cmd_issue_inttransaction (GtkAction *action,
+ GncMainWindowActionData *data)
+{
+ /* FIXME */
+}
+
+static void
+gnc_plugin_ab_cmd_issue_direct_debit (GtkAction *action,
+ GncMainWindowActionData *data)
+{
+ /* FIXME */
+}
+
+/************************************************************
+ * 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/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking.h (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-plugin-aqbanking.h 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/aqbanking/gncmod-aqbanking.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gncmod-aqbanking.c (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gncmod-aqbanking.c 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/aqbanking/schemas/Makefile.am
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/schemas/Makefile.am (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/schemas/Makefile.am 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in (rev 0)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/schemas/apps_gnucash_dialog_hbci.schemas.in 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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/aqbanking3/src/import-export/hbci/Makefile.am
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/hbci/Makefile.am 2008-04-12 19:28:06 UTC (rev 17079)
+++ gnucash/branches/aqbanking3/src/import-export/hbci/Makefile.am 2008-04-12 20:16:35 UTC (rev 17080)
@@ -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