1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2014 Maxime DOYEN
4 * This file is part of HomeBank.
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "ui-dialogs.h"
23 #include "list_operation.h"
26 /* = = = = = = = = = = */
27 /* = = = = = = = = = = = = = = = = = = = = */
28 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
29 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
31 /****************************************************************************/
33 /****************************************************************************/
42 /* our global datas */
43 extern struct HomeBank
*GLOBALS
;
44 extern struct Preferences
*PREFS
;
48 /* = = = = = = = = = = = = = = = = = = = = */
51 gint
ui_dialog_msg_question(GtkWindow
*parent
, gchar
*title
, gchar
*message_format
, ...)
58 dialog
= gtk_message_dialog_new (GTK_WINDOW(parent
),
59 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
68 va_start (args
, message_format
);
69 msg
= g_strdup_vprintf (message_format
, args
);
72 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog
), "%s", msg
);
77 gtk_dialog_set_default_response(GTK_DIALOG (dialog
), GTK_RESPONSE_NO
);
79 retval
= gtk_dialog_run (GTK_DIALOG (dialog
));
81 gtk_widget_destroy (dialog
);
87 ** open a info/error dialog for user information purpose
89 void ui_dialog_msg_infoerror(GtkWindow
*parent
, GtkMessageType type
, gchar
*title
, gchar
*message_format
, ...)
96 dialog
= gtk_message_dialog_new (GTK_WINDOW(parent
),
97 GTK_DIALOG_DESTROY_WITH_PARENT
,
106 va_start (args
, message_format
);
107 msg
= g_strdup_vprintf (message_format
, args
);
110 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog
), "%s", msg
);
115 gtk_dialog_run (GTK_DIALOG (dialog
));
116 gtk_widget_destroy (dialog
);
120 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
123 static void ui_file_chooser_add_filter(GtkFileChooser
*chooser
, gchar
*name
, gchar
*pattern
)
125 GtkFileFilter
*filter
= gtk_file_filter_new ();
126 gtk_file_filter_set_name (filter
, name
);
127 gtk_file_filter_add_pattern (filter
, pattern
);
128 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser
), filter
);
132 gboolean
ui_file_chooser_qif(GtkWindow
*parent
, gchar
**storage_ptr
)
137 DB( g_print("(homebank) chooser save qif\n") );
139 chooser
= gtk_file_chooser_dialog_new (
142 GTK_FILE_CHOOSER_ACTION_SAVE
,
143 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
144 GTK_STOCK_SAVE
, GTK_RESPONSE_ACCEPT
,
147 //todo: change this ?
148 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser
), PREFS
->path_export
);
149 ui_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser
), _("QIF files"), "*.[Qq][Ii][Ff]");
150 ui_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser
), _("All files"), "*");
153 if (gtk_dialog_run (GTK_DIALOG (chooser
)) == GTK_RESPONSE_ACCEPT
)
155 gchar
*tmpfilename
= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser
));
157 *storage_ptr
= hb_filename_new_with_extention(tmpfilename
, "qif");
162 gtk_widget_destroy (chooser
);
170 ** open a file chooser dialog and store filename to GLOBALS if OK
172 gboolean
ui_file_chooser_csv(GtkWindow
*parent
, GtkFileChooserAction action
, gchar
**storage_ptr
, gchar
*name
)
180 DB( g_print("(hombank) csvfile chooser csv %d\n", action
) );
182 if( action
== GTK_FILE_CHOOSER_ACTION_OPEN
)
184 title
= _("Import from CSV");
185 button
= GTK_STOCK_OPEN
;
186 path
= PREFS
->path_import
;
190 title
= _("Export as CSV");
191 button
= GTK_STOCK_SAVE
;
192 path
= PREFS
->path_export
;
195 chooser
= gtk_file_chooser_dialog_new (title
,
197 action
, //GTK_FILE_CHOOSER_ACTION_OPEN,
198 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
199 button
, GTK_RESPONSE_ACCEPT
,
202 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser
), path
);
205 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(chooser
), name
);
207 ui_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser
), _("CSV files"), "*.[Cc][Ss][Vv]");
208 ui_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser
), _("All files"), "*");
211 if (gtk_dialog_run (GTK_DIALOG (chooser
)) == GTK_RESPONSE_ACCEPT
)
213 gchar
*tmpfilename
= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser
));
215 if( action
== GTK_FILE_CHOOSER_ACTION_SAVE
)
217 *storage_ptr
= hb_filename_new_with_extention(tmpfilename
, "csv");
222 *storage_ptr
= tmpfilename
;
227 gtk_widget_destroy (chooser
);
233 ** open a file chooser dialog and store filename to GLOBALS if OK
235 gboolean
ui_file_chooser_xhb(GtkFileChooserAction action
, gchar
**storage_ptr
)
242 DB( g_print("(ui-dialog) file chooser xhb %d\n", action
) );
244 if( action
== GTK_FILE_CHOOSER_ACTION_OPEN
)
246 title
= _("Open homebank file");
247 button
= GTK_STOCK_OPEN
;
251 title
= _("Save homebank file as");
252 button
= GTK_STOCK_SAVE
;
255 chooser
= gtk_file_chooser_dialog_new (title
,
256 GTK_WINDOW(GLOBALS
->mainwindow
),
257 action
, //GTK_FILE_CHOOSER_ACTION_OPEN,
258 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
259 button
, GTK_RESPONSE_ACCEPT
,
262 ui_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser
), _("HomeBank files"), "*.[Xx][Hh][Bb]");
263 ui_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser
), _("All files"), "*");
265 if( action
== GTK_FILE_CHOOSER_ACTION_OPEN
)
267 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser
), PREFS
->path_hbfile
);
271 gchar
*basename
, *dirname
;
273 basename
= g_path_get_basename(GLOBALS
->xhb_filepath
);
274 dirname
= g_path_get_dirname (GLOBALS
->xhb_filepath
);
275 //gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(chooser), GLOBALS->xhb_filepath);
277 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser
), dirname
);
278 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(chooser
), basename
);
285 if (gtk_dialog_run (GTK_DIALOG (chooser
)) == GTK_RESPONSE_ACCEPT
)
287 *storage_ptr
= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser
));
291 gtk_widget_destroy (chooser
);
299 gboolean
ui_file_chooser_folder(GtkWindow
*parent
, gchar
*title
, gchar
**storage_ptr
)
304 DB( g_print("(ui-dialog) folder chooser\n") );
306 chooser
= gtk_file_chooser_dialog_new (title
,
308 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
309 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
310 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
313 DB( g_print(" - set folder %s\n", *storage_ptr
) );
315 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(chooser
), *storage_ptr
);
318 if (gtk_dialog_run (GTK_DIALOG (chooser
)) == GTK_RESPONSE_ACCEPT
)
322 //nb: filename must be freed with g_free
323 filename
= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser
));
325 DB( g_print("- folder %s\n", filename
) );
327 //todo: dangerous to do this here, review please !
328 g_free(*storage_ptr
);
329 *storage_ptr
= filename
;
331 DB( g_print("- folder stored: %s\n", *storage_ptr
) );
337 gtk_widget_destroy (chooser
);
345 ** request the user to save last change
347 gboolean
ui_dialog_msg_savechanges(GtkWidget
*widget
, gpointer user_data
)
349 gboolean retval
= TRUE
;
350 GtkWidget
*dialog
= NULL
;
353 if(GLOBALS
->changes_count
)
357 dialog
= gtk_message_dialog_new
359 GTK_WINDOW(GLOBALS
->mainwindow
),
360 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
364 _("Do you want to save the changes\nin the current file ?")
367 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog
),
368 _("If you do not save, some changes will be\ndefinitively lost: %d."),
369 GLOBALS
->changes_count
372 gtk_dialog_add_buttons (GTK_DIALOG(dialog
),
373 _("Do _not save"), 0,
378 gtk_dialog_set_default_response(GTK_DIALOG( dialog
), 2);
380 result
= gtk_dialog_run( GTK_DIALOG( dialog
) );
381 gtk_widget_destroy( dialog
);
383 if(result
== 1 || result
== GTK_RESPONSE_DELETE_EVENT
)
391 DB( g_print(" + should quick save %s\n", GLOBALS
->xhb_filepath
) );
392 homebank_save_xml(GLOBALS
->xhb_filepath
);
413 static void ui_dialog_transaction_xfer_select_child_cb(GtkWidget
*radiobutton
, gpointer user_data
)
415 struct xfer_data
*data
;
416 GtkTreeSelection
*selection
;
417 gboolean btnew
, sensitive
;
421 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(radiobutton
), GTK_TYPE_WINDOW
)), "inst_data");
423 DB( g_print("(import) account type toggle\n") );
425 btnew
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->radio
[0]));
426 gtk_widget_set_sensitive(data
->treeview
, btnew
^1);
428 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->treeview
));
429 count
= gtk_tree_selection_count_selected_rows(selection
);
432 sensitive
= (btnew
|| count
> 0) ? TRUE
: FALSE
;
434 DB( g_print("test count %d btnew %d sensitive %d\n", count
, btnew
, sensitive
) );
437 gtk_dialog_set_response_sensitive(GTK_DIALOG(data
->window
), GTK_RESPONSE_ACCEPT
, sensitive
);
441 static void ui_dialog_transaction_xfer_select_child_selection_cb(GtkTreeSelection
*treeselection
, gpointer user_data
)
443 ui_dialog_transaction_xfer_select_child_cb(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), NULL
);
447 Transaction
*ui_dialog_transaction_xfer_select_child(GList
*matchlist
)
449 struct xfer_data data
;
450 GtkWidget
*window
, *content
, *mainvbox
, *vbox
, *sw
, *label
;
451 GtkTreeModel
*newmodel
;
453 Transaction
*retval
= NULL
;
455 window
= gtk_dialog_new_with_buttons (NULL
,
456 //GTK_WINDOW (parentwindow),
465 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)&data
);
466 data
.window
= window
;
468 //gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE);
469 gtk_window_set_default_size (GTK_WINDOW (window
), 400, -1);
471 content
= gtk_dialog_get_content_area(GTK_DIALOG (window
));
472 mainvbox
= gtk_vbox_new (FALSE
, 0);
473 gtk_box_pack_start (GTK_BOX (content
), mainvbox
, TRUE
, TRUE
, 0);
474 gtk_container_set_border_width (GTK_CONTAINER (mainvbox
), HB_BOX_SPACING
);
476 gtk_window_set_title (GTK_WINDOW (window
), _("Select among possible transactions..."));
478 label
= make_label(_(
479 "HomeBank has found some transaction that may be " \
480 "the associated transaction for the internal transfer."), 0.0, 0.5
482 gimp_label_set_attributes (GTK_LABEL (label
),
483 PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
,
485 gtk_box_pack_start (GTK_BOX (mainvbox
), label
, FALSE
, FALSE
, HB_BOX_SPACING
);
488 vbox
= gtk_hbox_new (FALSE
, HB_BOX_SPACING
);
489 gtk_box_pack_start (GTK_BOX (mainvbox
), vbox
, FALSE
, TRUE
, HB_BOX_SPACING
);
491 label
= make_label(_("Select an action:"), 0.0, 0.5);
492 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
493 gtk_box_pack_start (GTK_BOX (vbox
), label
, FALSE
, FALSE
, 0);
496 data
.radio
[0] = gtk_radio_button_new_with_label (NULL
, _("create a new transaction"));
497 gtk_box_pack_start (GTK_BOX (vbox
), data
.radio
[0], FALSE
, FALSE
, 0);
499 data
.radio
[1] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (data
.radio
[0]), _("select an existing transaction"));
500 gtk_box_pack_start (GTK_BOX (vbox
), data
.radio
[1], FALSE
, FALSE
, 0);
502 sw
= gtk_scrolled_window_new (NULL
, NULL
);
503 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw
), GTK_SHADOW_ETCHED_IN
);
504 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
506 data
.treeview
= create_list_transaction(TRN_LIST_TYPE_BOOK
, PREFS
->lst_ope_columns
);
507 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
.treeview
)), GTK_SELECTION_SINGLE
);
508 gtk_container_add (GTK_CONTAINER (sw
), data
.treeview
);
509 gtk_box_pack_start (GTK_BOX (mainvbox
), sw
, TRUE
, TRUE
, 0);
511 g_signal_connect (data
.radio
[0], "toggled", G_CALLBACK (ui_dialog_transaction_xfer_select_child_cb
), NULL
);
512 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
.treeview
)), "changed", G_CALLBACK (ui_dialog_transaction_xfer_select_child_selection_cb
), NULL
);
515 newmodel
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
.treeview
));
520 gtk_list_store_clear (GTK_LIST_STORE(newmodel
));
523 GList
*tmplist
= g_list_first(matchlist
);
524 while (tmplist
!= NULL
)
526 Transaction
*tmp
= tmplist
->data
;
528 /* append to our treeview */
529 gtk_list_store_append (GTK_LIST_STORE(newmodel
), &newiter
);
531 gtk_list_store_set (GTK_LIST_STORE(newmodel
), &newiter
,
532 LST_DSPOPE_DATAS
, tmp
,
535 //DB( g_print(" - fill: %s %.2f %x\n", item->wording, item->amount, (unsigned int)item->same) );
537 tmplist
= g_list_next(tmplist
);
541 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
.radio
[1]), TRUE
);
544 gtk_widget_show_all(mainvbox
);
547 gint result
= gtk_dialog_run (GTK_DIALOG (window
));
549 if(result
== GTK_RESPONSE_ACCEPT
)
553 bnew
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
.radio
[0]));
556 GtkTreeSelection
*selection
;
560 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
.treeview
));
561 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
563 gtk_tree_model_get(model
, &iter
, LST_DSPOPE_DATAS
, &retval
, -1);
569 // cleanup and destroy
570 gtk_widget_destroy (window
);