add gitignore
[chaz/homebank] / src / ui-dialogs.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2014 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20 #include "homebank.h"
21
22 #include "ui-dialogs.h"
23 #include "list_operation.h"
24
25
26 /* = = = = = = = = = = */
27 /* = = = = = = = = = = = = = = = = = = = = */
28 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
29 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
30
31 /****************************************************************************/
32 /* Debug macros */
33 /****************************************************************************/
34 #define MYDEBUG 0
35
36 #if MYDEBUG
37 #define DB(x) (x);
38 #else
39 #define DB(x);
40 #endif
41
42 /* our global datas */
43 extern struct HomeBank *GLOBALS;
44 extern struct Preferences *PREFS;
45
46
47
48 /* = = = = = = = = = = = = = = = = = = = = */
49 /* Message dialog */
50
51 gint ui_dialog_msg_question(GtkWindow *parent, gchar *title, gchar *message_format, ...)
52 {
53 GtkWidget *dialog;
54 gchar* msg = NULL;
55 va_list args;
56 gint retval;
57
58 dialog = gtk_message_dialog_new (GTK_WINDOW(parent),
59 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
60 GTK_MESSAGE_QUESTION,
61 GTK_BUTTONS_YES_NO,
62 "%s",
63 title
64 );
65
66 if (message_format)
67 {
68 va_start (args, message_format);
69 msg = g_strdup_vprintf (message_format, args);
70 va_end (args);
71
72 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", msg);
73
74 g_free (msg);
75 }
76
77 gtk_dialog_set_default_response(GTK_DIALOG (dialog), GTK_RESPONSE_NO);
78
79 retval = gtk_dialog_run (GTK_DIALOG (dialog));
80
81 gtk_widget_destroy (dialog);
82
83 return retval;
84 }
85
86 /*
87 ** open a info/error dialog for user information purpose
88 */
89 void ui_dialog_msg_infoerror(GtkWindow *parent, GtkMessageType type, gchar *title, gchar *message_format, ...)
90 {
91 GtkWidget *dialog;
92 gchar* msg = NULL;
93 va_list args;
94
95
96 dialog = gtk_message_dialog_new (GTK_WINDOW(parent),
97 GTK_DIALOG_DESTROY_WITH_PARENT,
98 type,
99 GTK_BUTTONS_CLOSE,
100 "%s",
101 title
102 );
103
104 if (message_format)
105 {
106 va_start (args, message_format);
107 msg = g_strdup_vprintf (message_format, args);
108 va_end (args);
109
110 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", msg);
111
112 g_free (msg);
113 }
114
115 gtk_dialog_run (GTK_DIALOG (dialog));
116 gtk_widget_destroy (dialog);
117 }
118
119
120 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
121
122
123 static void ui_file_chooser_add_filter(GtkFileChooser *chooser, gchar *name, gchar *pattern)
124 {
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);
129 }
130
131
132 gboolean ui_file_chooser_qif(GtkWindow *parent, gchar **storage_ptr)
133 {
134 GtkWidget *chooser;
135 gboolean retval;
136
137 DB( g_print("(homebank) chooser save qif\n") );
138
139 chooser = gtk_file_chooser_dialog_new (
140 _("Export as QIF"),
141 GTK_WINDOW(parent),
142 GTK_FILE_CHOOSER_ACTION_SAVE,
143 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
144 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
145 NULL);
146
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"), "*");
151
152 retval = FALSE;
153 if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
154 {
155 gchar *tmpfilename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
156
157 *storage_ptr = hb_filename_new_with_extention(tmpfilename, "qif");
158 g_free(tmpfilename);
159 retval = TRUE;
160 }
161
162 gtk_widget_destroy (chooser);
163
164 return retval;
165 }
166
167
168
169 /*
170 ** open a file chooser dialog and store filename to GLOBALS if OK
171 */
172 gboolean ui_file_chooser_csv(GtkWindow *parent, GtkFileChooserAction action, gchar **storage_ptr, gchar *name)
173 {
174 GtkWidget *chooser;
175 gchar *title;
176 gchar *button;
177 gboolean retval;
178 gchar *path;
179
180 DB( g_print("(hombank) csvfile chooser csv %d\n", action) );
181
182 if( action == GTK_FILE_CHOOSER_ACTION_OPEN )
183 {
184 title = _("Import from CSV");
185 button = GTK_STOCK_OPEN;
186 path = PREFS->path_import;
187 }
188 else
189 {
190 title = _("Export as CSV");
191 button = GTK_STOCK_SAVE;
192 path = PREFS->path_export;
193 }
194
195 chooser = gtk_file_chooser_dialog_new (title,
196 GTK_WINDOW(parent),
197 action, //GTK_FILE_CHOOSER_ACTION_OPEN,
198 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
199 button, GTK_RESPONSE_ACCEPT,
200 NULL);
201
202 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser), path);
203
204 if(name != NULL)
205 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(chooser), name);
206
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"), "*");
209
210 retval = FALSE;
211 if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
212 {
213 gchar *tmpfilename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
214
215 if( action == GTK_FILE_CHOOSER_ACTION_SAVE )
216 {
217 *storage_ptr = hb_filename_new_with_extention(tmpfilename, "csv");
218 g_free(tmpfilename);
219 }
220 else
221 {
222 *storage_ptr = tmpfilename;
223 }
224 retval = TRUE;
225 }
226
227 gtk_widget_destroy (chooser);
228
229 return retval;
230 }
231
232 /*
233 ** open a file chooser dialog and store filename to GLOBALS if OK
234 */
235 gboolean ui_file_chooser_xhb(GtkFileChooserAction action, gchar **storage_ptr)
236 {
237 GtkWidget *chooser;
238 gchar *title;
239 gchar *button;
240 gboolean retval;
241
242 DB( g_print("(ui-dialog) file chooser xhb %d\n", action) );
243
244 if( action == GTK_FILE_CHOOSER_ACTION_OPEN )
245 {
246 title = _("Open homebank file");
247 button = GTK_STOCK_OPEN;
248 }
249 else
250 {
251 title = _("Save homebank file as");
252 button = GTK_STOCK_SAVE;
253 }
254
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,
260 NULL);
261
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"), "*");
264
265 if( action == GTK_FILE_CHOOSER_ACTION_OPEN )
266 {
267 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser), PREFS->path_hbfile);
268 }
269 else /* save */
270 {
271 gchar *basename, *dirname;
272
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);
276
277 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser), dirname);
278 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(chooser), basename);
279
280 g_free(dirname);
281 g_free(basename);
282 }
283
284 retval = FALSE;
285 if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
286 {
287 *storage_ptr = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
288 retval = TRUE;
289 }
290
291 gtk_widget_destroy (chooser);
292
293 return retval;
294 }
295
296 /*
297 **
298 */
299 gboolean ui_file_chooser_folder(GtkWindow *parent, gchar *title, gchar **storage_ptr)
300 {
301 GtkWidget *chooser;
302 gboolean retval;
303
304 DB( g_print("(ui-dialog) folder chooser\n") );
305
306 chooser = gtk_file_chooser_dialog_new (title,
307 parent,
308 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
309 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
310 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
311 NULL);
312
313 DB( g_print(" - set folder %s\n", *storage_ptr) );
314
315 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(chooser), *storage_ptr);
316
317 retval = FALSE;
318 if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
319 {
320 gchar *filename;
321
322 //nb: filename must be freed with g_free
323 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
324
325 DB( g_print("- folder %s\n", filename) );
326
327 //todo: dangerous to do this here, review please !
328 g_free(*storage_ptr);
329 *storage_ptr = filename;
330
331 DB( g_print("- folder stored: %s\n", *storage_ptr) );
332
333
334 retval = TRUE;
335 }
336
337 gtk_widget_destroy (chooser);
338
339 return retval;
340 }
341
342
343
344 /*
345 ** request the user to save last change
346 */
347 gboolean ui_dialog_msg_savechanges(GtkWidget *widget, gpointer user_data)
348 {
349 gboolean retval = TRUE;
350 GtkWidget *dialog = NULL;
351
352
353 if(GLOBALS->changes_count)
354 {
355 gint result;
356
357 dialog = gtk_message_dialog_new
358 (
359 GTK_WINDOW(GLOBALS->mainwindow),
360 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
361 GTK_MESSAGE_WARNING,
362 //GTK_MESSAGE_INFO,
363 GTK_BUTTONS_NONE,
364 _("Do you want to save the changes\nin the current file ?")
365 );
366
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
370 );
371
372 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
373 _("Do _not save"), 0,
374 GTK_STOCK_CANCEL, 1,
375 GTK_STOCK_SAVE, 2,
376 NULL);
377
378 gtk_dialog_set_default_response(GTK_DIALOG( dialog ), 2);
379
380 result = gtk_dialog_run( GTK_DIALOG( dialog ) );
381 gtk_widget_destroy( dialog );
382
383 if(result == 1 || result == GTK_RESPONSE_DELETE_EVENT)
384 {
385 retval = FALSE;
386 }
387 else
388 {
389 if(result == 2)
390 {
391 DB( g_print(" + should quick save %s\n", GLOBALS->xhb_filepath) );
392 homebank_save_xml(GLOBALS->xhb_filepath);
393 }
394 }
395
396
397
398 }
399 return retval;
400 }
401
402
403
404
405 struct xfer_data
406 {
407 GtkWidget *window;
408 GtkWidget *radio[2];
409 GtkWidget *treeview;
410 };
411
412
413 static void ui_dialog_transaction_xfer_select_child_cb(GtkWidget *radiobutton, gpointer user_data)
414 {
415 struct xfer_data *data;
416 GtkTreeSelection *selection;
417 gboolean btnew, sensitive;
418 gint count;
419
420
421 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(radiobutton), GTK_TYPE_WINDOW)), "inst_data");
422
423 DB( g_print("(import) account type toggle\n") );
424
425 btnew = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->radio[0]));
426 gtk_widget_set_sensitive(data->treeview, btnew^1);
427
428 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->treeview));
429 count = gtk_tree_selection_count_selected_rows(selection);
430
431
432 sensitive = (btnew || count > 0) ? TRUE : FALSE;
433
434 DB( g_print("test count %d btnew %d sensitive %d\n", count, btnew, sensitive) );
435
436
437 gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_ACCEPT, sensitive);
438
439 }
440
441 static void ui_dialog_transaction_xfer_select_child_selection_cb(GtkTreeSelection *treeselection, gpointer user_data)
442 {
443 ui_dialog_transaction_xfer_select_child_cb(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), NULL);
444 }
445
446
447 Transaction *ui_dialog_transaction_xfer_select_child(GList *matchlist)
448 {
449 struct xfer_data data;
450 GtkWidget *window, *content, *mainvbox, *vbox, *sw, *label;
451 GtkTreeModel *newmodel;
452 GtkTreeIter newiter;
453 Transaction *retval = NULL;
454
455 window = gtk_dialog_new_with_buttons (NULL,
456 //GTK_WINDOW (parentwindow),
457 NULL,
458 0,
459 GTK_STOCK_CANCEL,
460 GTK_RESPONSE_REJECT,
461 GTK_STOCK_OK,
462 GTK_RESPONSE_ACCEPT,
463 NULL);
464
465 g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)&data);
466 data.window = window;
467
468 //gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE);
469 gtk_window_set_default_size (GTK_WINDOW (window), 400, -1);
470
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);
475
476 gtk_window_set_title (GTK_WINDOW (window), _("Select among possible transactions..."));
477
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
481 );
482 gimp_label_set_attributes (GTK_LABEL (label),
483 PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
484 -1);
485 gtk_box_pack_start (GTK_BOX (mainvbox), label, FALSE, FALSE, HB_BOX_SPACING);
486
487
488 vbox = gtk_hbox_new (FALSE, HB_BOX_SPACING);
489 gtk_box_pack_start (GTK_BOX (mainvbox), vbox, FALSE, TRUE, HB_BOX_SPACING);
490
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);
494
495
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);
498
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);
501
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);
505
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);
510
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);
513
514 /* populate */
515 newmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(data.treeview));
516
517
518
519
520 gtk_list_store_clear (GTK_LIST_STORE(newmodel));
521
522
523 GList *tmplist = g_list_first(matchlist);
524 while (tmplist != NULL)
525 {
526 Transaction *tmp = tmplist->data;
527
528 /* append to our treeview */
529 gtk_list_store_append (GTK_LIST_STORE(newmodel), &newiter);
530
531 gtk_list_store_set (GTK_LIST_STORE(newmodel), &newiter,
532 LST_DSPOPE_DATAS, tmp,
533 -1);
534
535 //DB( g_print(" - fill: %s %.2f %x\n", item->wording, item->amount, (unsigned int)item->same) );
536
537 tmplist = g_list_next(tmplist);
538 }
539
540 //initialize
541 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data.radio[1]), TRUE);
542
543
544 gtk_widget_show_all(mainvbox);
545
546 //wait for the user
547 gint result = gtk_dialog_run (GTK_DIALOG (window));
548
549 if(result == GTK_RESPONSE_ACCEPT)
550 {
551 gboolean bnew;
552
553 bnew = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data.radio[0]));
554 if( bnew == FALSE)
555 {
556 GtkTreeSelection *selection;
557 GtkTreeModel *model;
558 GtkTreeIter iter;
559
560 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data.treeview));
561 if (gtk_tree_selection_get_selected(selection, &model, &iter))
562 {
563 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &retval, -1);
564 }
565 }
566
567 }
568
569 // cleanup and destroy
570 gtk_widget_destroy (window);
571
572 return retval;
573 }
574
575
576
This page took 0.069689 seconds and 4 git commands to generate.