26 #include <glib/gi18n.h>
30 #include "dialog-transfer.h"
31 #include "dialog-utils.h"
32 #include "gnc-amount-edit.h"
33 #include "gnc-component-manager.h"
34 #include "gnc-date-edit.h"
40 #include "guile-util.h"
41 #include "window-autoclear.h"
43 #define WINDOW_AUTOCLEAR_CM_CLASS "window-autoclear"
57 GtkWidget *cancel_button;
58 GtkLabel *status_label;
62 void gnc_autoclear_window_ok_cb (GtkWidget *widget,
64 void gnc_autoclear_window_cancel_cb (GtkWidget *widget,
76 if (autoClearData == NULL)
79 if (autoClearData->window == NULL)
82 gtk_window_present(GTK_WINDOW(autoClearData->window));
86 gnc_autoclear_make_window_name(
Account *account)
92 title = g_strconcat(fullname,
" - ", _(
"Auto-clear"), NULL);
100 ght_gnc_numeric_equal(gconstpointer v1, gconstpointer v2)
107 ght_gnc_numeric_hash(gconstpointer v1)
111 return g_str_hash(&d1);
117 GList *reachable_list;
120 static void sack_foreach_func(gpointer key, gpointer value, gpointer user_data)
125 gnc_numeric reachable_value = gnc_numeric_add_fixed(thisvalue, data->split_value);
126 data->reachable_list = g_list_append(data->reachable_list, g_memdup(&reachable_value,
sizeof(
gnc_numeric)));
131 gnc_autoclear_window_ok_cb (GtkWidget *widget,
134 GList *node, *nc_list = 0, *toclear_list = 0;
138 gtk_label_set_text(data->status_label, _(
"Searching for splits to clear ..."));
141 toclear_value = gnc_amount_edit_get_amount(data->end_value);
155 nc_list = g_list_append(nc_list, split);
157 toclear_value = gnc_numeric_sub_fixed(toclear_value, value);
162 PINFO(
"Available splits:\n");
163 for (node = nc_list; node; node = node->next)
175 PINFO(
"Knapsacking ...\n");
176 sack = g_hash_table_new_full (ght_gnc_numeric_hash, ght_gnc_numeric_equal, g_free, NULL);
177 for (node = nc_list; node; node = node->next)
184 data->split_value = split_value;
185 data->reachable_list = 0;
190 g_hash_table_foreach (sack, sack_foreach_func, data);
193 data->reachable_list = g_list_append(data->reachable_list, g_memdup(&split_value,
sizeof(
gnc_numeric)));
196 for (node = data->reachable_list; node; node = node->next)
199 Split *toinsert_split = split;
204 if (g_hash_table_lookup_extended(sack, reachable_value, NULL, NULL))
207 toinsert_split = NULL;
210 g_hash_table_insert (sack, reachable_value, toinsert_split);
213 g_list_free(data->reachable_list);
217 PINFO(
"Rebuilding solution ...\n");
220 gpointer psplit = NULL;
223 if (g_hash_table_lookup_extended(sack, &toclear_value, NULL, &psplit))
229 toclear_list = g_list_prepend(toclear_list, split);
230 toclear_value = gnc_numeric_sub_fixed(toclear_value,
232 PINFO(
" Cleared: %s -> %s\n",
239 PINFO(
" Solution not unique.\n");
240 gtk_label_set_text(data->status_label, _(
"Cannot uniquely clear splits. Found multiple possibilities."));
246 PINFO(
" No solution found.\n");
247 gtk_label_set_text(data->status_label, _(
"The selected amount cannot be cleared."));
251 g_hash_table_destroy (sack);
254 PINFO(
"Clearing splits:\n");
255 for (node = toclear_list; node; node = node->next)
257 Split *split = node->data;
268 if (toclear_list == 0)
272 g_list_free(nc_list);
273 g_list_free(toclear_list);
276 gtk_widget_destroy(data->window);
281 gnc_autoclear_window_cancel_cb (GtkWidget *widget,
285 gtk_widget_destroy(data->window);
298 autoClearWindow (GtkWidget *parent,
Account *account)
307 data->account = account;
310 builder = gtk_builder_new();
311 gnc_builder_add_from_file (builder,
"window-autoclear.glade",
"Auto-clear Start Dialog");
312 data->window = GTK_WIDGET(gtk_builder_get_object (builder,
"Auto-clear Start Dialog"));
313 title = gnc_autoclear_make_window_name (account);
314 gtk_window_set_title(GTK_WINDOW(data->window), title);
318 data->end_value = GNC_AMOUNT_EDIT(gnc_amount_edit_new());
319 g_signal_connect(GTK_WIDGET(data->end_value),
"activate",
320 G_CALLBACK(gnc_autoclear_window_ok_cb), data);
322 box = GTK_BOX(gtk_builder_get_object (builder,
"end_value_box"));
323 gtk_box_pack_start(box, GTK_WIDGET(data->end_value), TRUE, TRUE, 0);
325 label = GTK_LABEL(gtk_builder_get_object (builder,
"end_label"));
326 gtk_label_set_mnemonic_widget(label, GTK_WIDGET(data->end_value));
327 gtk_widget_grab_focus(GTK_WIDGET(data->end_value));
329 data->status_label = GTK_LABEL(gtk_builder_get_object (builder,
"status_label"));
332 gtk_window_set_transient_for (GTK_WINDOW (data->window), GTK_WINDOW (parent));
334 gtk_builder_connect_signals(builder, data);
335 g_object_unref(G_OBJECT(builder));
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
SplitList * xaccAccountGetSplitList(const Account *acc)
Dialog for create/edit an account.
#define PINFO(format, args...)
int xaccAccountGetCommoditySCU(const Account *acc)
char xaccSplitGetReconcile(const Split *split)
gboolean gnc_numeric_zero_p(gnc_numeric a)
void xaccSplitSetReconcile(Split *split, char recn)
gchar * gnc_numeric_to_string(gnc_numeric n)
Functions for adding content to a window.
gdouble gnc_numeric_to_double(gnc_numeric n)
convert single-entry accounts to clean double-entry
gchar * gnc_account_get_full_name(const Account *account)
Functions providing a register page for the GnuCash UI.
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Gnome specific utility functions.
Additional event handling code.
const gchar * QofLogModule
gnc_numeric xaccSplitGetAmount(const Split *split)