]> Dogcows Code - chaz/homebank/blob - src/ui-currency.c
Merge branch 'upstream'
[chaz/homebank] / src / ui-currency.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2012 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-currency.h"
23
24
25 #define MYDEBUG 0
26
27 #if MYDEBUG
28 #define DB(x) (x);
29 #else
30 #define DB(x);
31 #endif
32
33 /* our global datas */
34 extern struct HomeBank *GLOBALS;
35 extern struct Preferences *PREFS;
36
37 extern Currency4217 iso4217cur[];
38 extern guint n_iso4217cur;
39
40 static void ui_cur_manage_dialog_update(GtkWidget *treeview, gpointer user_data);
41
42 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
43
44 /**
45 * ui_cur_combobox_get_name:
46 *
47 * get the name of the active curee or -1
48 *
49 * Return value: a new allocated name tobe freed with g_free
50 *
51 */
52 gchar *
53 ui_cur_combobox_get_name(GtkComboBox *entry_box)
54 {
55 gchar *cbname;
56 gchar *name = NULL;
57
58 cbname = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
59
60 if( cbname != NULL)
61 {
62 name = g_strdup(cbname);
63 g_strstrip(name);
64 }
65
66 return name;
67 }
68
69
70 /**
71 * ui_cur_combobox_get_key:
72 *
73 * get the key of the active curee
74 *
75 * Return value: the key or 0
76 *
77 */
78 guint32
79 ui_cur_combobox_get_key(GtkComboBox *entry_box)
80 {
81 GtkTreeModel *model;
82 GtkTreeIter iter;
83 guint32 key = 0;
84
85 if (gtk_combo_box_get_active_iter(entry_box, &iter) == TRUE)
86 {
87 model = gtk_combo_box_get_model(entry_box);
88 gtk_tree_model_get (model, &iter, 1, &key, -1);
89 }
90
91 return key;
92 }
93
94
95 gboolean
96 ui_cur_combobox_set_active(GtkComboBox *entry_box, guint32 key)
97 {
98 GtkTreeModel *model;
99 GtkTreeIter iter;
100 gboolean valid;
101 guint32 cbkey;
102
103 model = gtk_combo_box_get_model(entry_box);
104 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
105 while (valid)
106 {
107 gtk_tree_model_get (model, &iter, 1, &cbkey, -1);
108 if(cbkey == key)
109 break;
110
111 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
112 }
113
114 gtk_combo_box_set_active_iter(entry_box, &iter);
115
116 return FALSE;
117 }
118
119
120
121
122 /**
123 * ui_cur_combobox_add:
124 *
125 * Add a single element (useful for dynamics add)
126 *
127 * Return value: --
128 *
129 */
130 void
131 ui_cur_combobox_add(GtkComboBox *entry_box, Currency *cur)
132 {
133 if( cur->name != NULL )
134 {
135 GtkTreeModel *model;
136 GtkTreeIter iter;
137
138 model = gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box));
139
140 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
141 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, cur->name, 1, cur->key, -1);
142 }
143 }
144
145 static void
146 ui_cur_combobox_populate_ghfunc(gpointer key, gpointer value, struct curPopContext *ctx)
147 {
148 GtkTreeIter iter;
149 Currency *cur = value;
150
151 if( ( cur->key != ctx->except_key ) )
152 {
153 gtk_list_store_append (GTK_LIST_STORE(ctx->model), &iter);
154 gtk_list_store_set (GTK_LIST_STORE(ctx->model), &iter, 0, cur->name, 1, cur->key, -1);
155 }
156 }
157
158 void
159 ui_cur_combobox_populate_except(GtkComboBox *entry_box, GHashTable *hash, guint32 except_key)
160 {
161 GtkTreeModel *model;
162 struct curPopContext ctx;
163
164 DB( g_print ("ui_cur_combobox_populate\n") );
165
166 model = gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box));
167
168 /* keep our model alive and detach from combobox and completion */
169 g_object_ref(model);
170 gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), NULL);
171
172 /* clear and populate */
173 ctx.model = model;
174 ctx.except_key = except_key;
175 gtk_list_store_clear (GTK_LIST_STORE(model));
176 g_hash_table_foreach(hash, (GHFunc)ui_cur_combobox_populate_ghfunc, &ctx);
177
178 /* reatach our model */
179 gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), model);
180 g_object_unref(model);
181
182 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
183
184 }
185
186 /**
187 * ui_cur_combobox_populate:
188 *
189 * Populate the list and completion
190 *
191 * Return value: --
192 *
193 */
194 void
195 ui_cur_combobox_populate(GtkComboBox *entry_box, GHashTable *hash)
196 {
197 ui_cur_combobox_populate_except(entry_box, hash, -1);
198 }
199
200
201 static gint
202 ui_cur_combobox_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
203 {
204 gint ret = 0;
205 gchar *name1, *name2;
206
207 gtk_tree_model_get(model, a, 0, &name1, -1);
208 gtk_tree_model_get(model, b, 0, &name2, -1);
209
210 if (name1 == NULL || name2 == NULL)
211 {
212 if (name1 == NULL && name2 == NULL)
213 goto end;
214
215 ret = (name1 == NULL) ? -1 : 1;
216 }
217 else
218 {
219 ret = g_utf8_collate(name1,name2);
220 }
221
222
223 end:
224
225 g_free(name1);
226 g_free(name2);
227
228 return ret;
229 }
230
231
232 static void
233 ui_cur_combobox_test (GtkCellLayout *cell_layout,
234 GtkCellRenderer *cell,
235 GtkTreeModel *tree_model,
236 GtkTreeIter *iter,
237 gpointer data)
238 {
239 gchar *name;
240
241 gtk_tree_model_get(tree_model, iter,
242 0, &name,
243 -1);
244
245 if( !name )
246 g_object_set(cell, "text", _("(none)"), NULL);
247 else
248 g_object_set(cell, "text", name, NULL);
249
250 }
251
252 /**
253 * ui_cur_combobox_new:
254 *
255 * Create a new curee combobox
256 *
257 * Return value: the new widget
258 *
259 */
260 GtkWidget *
261 ui_cur_combobox_new(GtkWidget *label)
262 {
263 GtkListStore *store;
264 GtkWidget *combobox;
265 GtkCellRenderer *renderer;
266
267 store = gtk_list_store_new (2,
268 G_TYPE_STRING,
269 G_TYPE_INT
270 );
271 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), ui_cur_combobox_compare_func, NULL, NULL);
272
273 // dothe same for combobox
274
275 combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
276
277 gtk_cell_layout_clear(GTK_CELL_LAYOUT (combobox));
278
279 renderer = gtk_cell_renderer_text_new ();
280 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), renderer, TRUE);
281 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, "text", 0, NULL);
282
283 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combobox),
284 renderer,
285 ui_cur_combobox_test,
286 NULL, NULL);
287
288 g_object_unref(store);
289
290 if(label)
291 gtk_label_set_mnemonic_widget (GTK_LABEL(label), combobox);
292
293 gtk_widget_set_size_request (combobox, 10, -1);
294
295 return combobox;
296 }
297
298
299
300 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
301
302
303
304
305 static void
306 ui_cur_listview_toggled_cb (GtkCellRendererToggle *cell,
307 gchar *path_str,
308 gpointer data)
309 {
310 GtkTreeModel *model = (GtkTreeModel *)data;
311 GtkTreeIter iter;
312 GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
313 gboolean fixed;
314
315 /* get toggled iter */
316 gtk_tree_model_get_iter (model, &iter, path);
317 gtk_tree_model_get (model, &iter, LST_DEFCUR_TOGGLE, &fixed, -1);
318
319 /* do something with the value */
320 fixed ^= 1;
321
322 /* set new value */
323 gtk_list_store_set (GTK_LIST_STORE (model), &iter, LST_DEFCUR_TOGGLE, fixed, -1);
324
325 /* clean up */
326 gtk_tree_path_free (path);
327 }
328
329 static gint
330 ui_cur_listview_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
331 {
332 gint result = 0;
333 Currency *entry1, *entry2;
334 gchar *name1, *name2;
335
336 gtk_tree_model_get(model, a, LST_DEFCUR_DATAS, &entry1, -1);
337 gtk_tree_model_get(model, b, LST_DEFCUR_DATAS, &entry2, -1);
338
339 name1 = (entry1->key == GLOBALS->kcur) ? NULL : entry1->iso_code;
340 name2 = (entry2->key == GLOBALS->kcur) ? NULL : entry2->iso_code;
341
342 result = hb_string_compare(name1,name2);
343
344 return result;
345 }
346
347 static void
348 ui_cur_listview_name_cell_data_function (GtkTreeViewColumn *col,
349 GtkCellRenderer *renderer,
350 GtkTreeModel *model,
351 GtkTreeIter *iter,
352 gpointer user_data)
353 {
354 Currency *entry;
355 gchar *string;
356 gint weight;
357
358 gtk_tree_model_get(model, iter, LST_DEFCUR_DATAS, &entry, -1);
359
360 weight = entry->key == GLOBALS->kcur ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
361
362 #if MYDEBUG
363 if( entry->key == GLOBALS->kcur )
364 string = g_strdup_printf ("[%d] %s - %s<span size=\"small\">\n(%s)</span>", entry->key, entry->iso_code, entry->name, _("Base currency"));
365 else
366 string = g_strdup_printf ("[%d] %s - %s", entry->key, entry->iso_code, entry->name);
367 g_object_set(renderer, "weight", weight, "markup", string, NULL);
368 g_free(string);
369 #else
370 if( entry->key == GLOBALS->kcur )
371 string = g_strdup_printf ("%s - %s<span size=\"small\">\n(%s)</span>", entry->iso_code, entry->name, _("Base currency"));
372 else
373 string = g_strdup_printf ("%s - %s", entry->iso_code, entry->name);
374 g_object_set(renderer, "weight", weight, "markup", string, NULL);
375 g_free(string);
376 #endif
377
378 }
379
380
381 static void
382 ui_cur_listview_symbol_cell_data_function (GtkTreeViewColumn *col,
383 GtkCellRenderer *renderer,
384 GtkTreeModel *model,
385 GtkTreeIter *iter,
386 gpointer user_data)
387 {
388 Currency *entry;
389 gint weight;
390
391 gtk_tree_model_get(model, iter, LST_DEFCUR_DATAS, &entry, -1);
392
393 weight = entry->key == GLOBALS->kcur ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
394
395 g_object_set(renderer, "weight", weight, "text", entry->symbol, NULL);
396 }
397
398
399 static void
400 ui_cur_listview_lastmodified_cell_data_function (GtkTreeViewColumn *col,
401 GtkCellRenderer *renderer,
402 GtkTreeModel *model,
403 GtkTreeIter *iter,
404 gpointer user_data)
405 {
406 Currency *entry;
407 gchar buffer[256];
408 GDate date;
409 gint weight;
410
411 gtk_tree_model_get(model, iter, LST_DEFCUR_DATAS, &entry, -1);
412
413 weight = entry->key == GLOBALS->kcur ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
414
415 if(entry->mdate > 0)
416 {
417 g_date_set_julian (&date, entry->mdate);
418 g_date_strftime (buffer, 256-1, PREFS->date_format, &date);
419
420 //g_snprintf(buf, sizeof(buf), "%d", ope->ope_Date);
421
422 g_object_set(renderer, "weight", weight, "text", buffer, NULL);
423 }
424 else
425 g_object_set(renderer, "weight", weight, "text", "-", NULL);
426 }
427
428
429
430 static void
431 ui_cur_listview_rate_cell_data_function (GtkTreeViewColumn *col,
432 GtkCellRenderer *renderer,
433 GtkTreeModel *model,
434 GtkTreeIter *iter,
435 gpointer user_data)
436 {
437 Currency *entry;
438 gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
439
440 gtk_tree_model_get(model, iter, LST_DEFCUR_DATAS, &entry, -1);
441
442 if(entry->key == GLOBALS->kcur)
443 g_object_set(renderer, "text", "-", NULL);
444 else
445 {
446 //g_ascii_formatd(formatd_buf, sizeof (formatd_buf), "%.6f", entry->rate);
447 //g_snprintf(formatd_buf, sizeof (formatd_buf), "%f", entry->rate);
448 hb_str_rate(formatd_buf, sizeof (formatd_buf), entry->rate);
449 g_object_set(renderer, "text", formatd_buf, NULL);
450 }
451
452 }
453
454
455 /* = = = = = = = = = = = = = = = = */
456
457
458 void
459 ui_cur_listview_add(GtkTreeView *treeview, Currency *item)
460 {
461 if( item->name != NULL )
462 {
463 GtkTreeModel *model;
464 GtkTreeIter iter;
465
466 model = gtk_tree_view_get_model(treeview);
467
468 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
469 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
470 LST_DEFCUR_TOGGLE, FALSE,
471 LST_DEFCUR_DATAS, item,
472 -1);
473 }
474 }
475
476 guint32
477 ui_cur_listview_get_selected_key(GtkTreeView *treeview)
478 {
479 GtkTreeSelection *selection;
480 GtkTreeModel *model;
481 GtkTreeIter iter;
482
483 selection = gtk_tree_view_get_selection(treeview);
484 if (gtk_tree_selection_get_selected(selection, &model, &iter))
485 {
486 Currency *item;
487
488 gtk_tree_model_get(model, &iter, LST_DEFCUR_DATAS, &item, -1);
489
490 if( item != NULL )
491 return item->key;
492 }
493 return 0;
494 }
495
496 void
497 ui_cur_listview_remove_selected(GtkTreeView *treeview)
498 {
499 GtkTreeSelection *selection;
500 GtkTreeModel *model;
501 GtkTreeIter iter;
502
503 selection = gtk_tree_view_get_selection(treeview);
504 if (gtk_tree_selection_get_selected(selection, &model, &iter))
505 {
506 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
507 }
508 }
509
510
511 static void ui_cur_listview_populate_ghfunc(gpointer key, gpointer value, GtkTreeModel *model)
512 {
513 GtkTreeIter iter;
514 Currency *item = value;
515
516 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
517 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
518 LST_DEFCUR_TOGGLE , FALSE,
519 LST_DEFCUR_DATAS, item,
520 -1);
521 }
522
523 void ui_cur_listview_populate(GtkWidget *view)
524 {
525 GtkTreeModel *model;
526
527 model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
528
529 gtk_list_store_clear (GTK_LIST_STORE(model));
530
531 g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
532 gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); /* Detach model from view */
533
534 /* populate */
535 g_hash_table_foreach(GLOBALS->h_cur, (GHFunc)ui_cur_listview_populate_ghfunc, model);
536
537 gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); /* Re-attach model to view */
538 g_object_unref(model);
539 }
540
541 /* test */
542 /*
543 static void
544 ui_cur_listivew_rate_edited_func (GtkCellRendererText *cell,
545 const gchar *path_string,
546 const gchar *new_text,
547 gpointer data)
548 {
549 GtkTreeModel *model = (GtkTreeModel *)data;
550 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
551 GtkTreeIter iter;
552
553 g_print("cell edited '%s' path %s\n", new_text, path_string);
554
555
556 gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));
557
558 gtk_tree_model_get_iter (model, &iter, path);
559
560 Currency *item;
561
562 gtk_tree_model_get(model, &iter, LST_DEFCUR_DATAS, &item, -1);
563
564 item->rate = atof(new_text);
565
566 GLOBALS->changes_count++;
567
568
569 gtk_tree_path_free (path);
570 }
571 */
572
573
574 GtkWidget *
575 ui_cur_listview_new(gboolean withtoggle)
576 {
577 GtkListStore *store;
578 GtkWidget *treeview;
579 GtkCellRenderer *renderer;
580 GtkTreeViewColumn *column;
581
582 // create list store
583 store = gtk_list_store_new(
584 NUM_LST_DEFCUR,
585 G_TYPE_BOOLEAN,
586 G_TYPE_POINTER
587 );
588
589 // treeview
590 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
591 g_object_unref(store);
592
593 // column 1: toggle
594 if( withtoggle == TRUE )
595 {
596 renderer = gtk_cell_renderer_toggle_new ();
597 column = gtk_tree_view_column_new_with_attributes (_("Visible"),
598 renderer,
599 "active", LST_DEFCUR_TOGGLE,
600 NULL);
601 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
602
603 g_signal_connect (renderer, "toggled",
604 G_CALLBACK (ui_cur_listview_toggled_cb), store);
605
606 }
607
608 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview), PREFS->grid_lines);
609
610
611 // column 1: name
612 renderer = gtk_cell_renderer_text_new ();
613 column = gtk_tree_view_column_new();
614 gtk_tree_view_column_set_title(column, _("Name"));
615 gtk_tree_view_column_set_alignment (column, 0.5);
616 gtk_tree_view_column_pack_start(column, renderer, TRUE);
617 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cur_listview_name_cell_data_function, GINT_TO_POINTER(LST_DEFCUR_DATAS), NULL);
618 gtk_tree_view_column_set_resizable(column, TRUE);
619 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
620
621 // column 2: code
622 renderer = gtk_cell_renderer_text_new ();
623 g_object_set(renderer, "xalign", 0.5, NULL);
624 column = gtk_tree_view_column_new();
625 gtk_tree_view_column_set_title(column, _("Symbol"));
626 gtk_tree_view_column_set_alignment (column, 0.5);
627 gtk_tree_view_column_pack_start(column, renderer, TRUE);
628 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cur_listview_symbol_cell_data_function, GINT_TO_POINTER(LST_DEFCUR_DATAS), NULL);
629 gtk_tree_view_column_set_resizable(column, TRUE);
630 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
631
632 // column 3: base rate
633 renderer = gtk_cell_renderer_text_new ();
634 //g_object_set (renderer, "editable", TRUE, NULL);
635 g_object_set(renderer, "xalign", 1.0, NULL);
636 column = gtk_tree_view_column_new();
637 gtk_tree_view_column_set_title(column, _("Exchange rate"));
638 gtk_tree_view_column_set_alignment (column, 0.5);
639 gtk_tree_view_column_pack_start(column, renderer, TRUE);
640 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cur_listview_rate_cell_data_function, GINT_TO_POINTER(LST_DEFCUR_DATAS), NULL);
641 gtk_tree_view_column_set_resizable(column, TRUE);
642 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
643
644 //g_signal_connect (renderer, "edited", G_CALLBACK (ui_cur_listivew_rate_edited_func), GTK_TREE_MODEL(store));
645
646 // column 4: last modified
647 renderer = gtk_cell_renderer_text_new ();
648 g_object_set(renderer, "xalign", 0.5, NULL);
649 column = gtk_tree_view_column_new();
650 gtk_tree_view_column_set_title(column, _("Last modfied"));
651 gtk_tree_view_column_set_alignment (column, 0.5);
652 gtk_tree_view_column_pack_start(column, renderer, TRUE);
653 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cur_listview_lastmodified_cell_data_function, GINT_TO_POINTER(LST_DEFCUR_DATAS), NULL);
654 gtk_tree_view_column_set_resizable(column, TRUE);
655 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
656
657
658 // treeview attribute
659 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), 1);
660 //gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), TRUE);
661 //gtk_tree_view_set_reorderable (GTK_TREE_VIEW(view), TRUE);
662 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DEFCUR_DATAS, ui_cur_listview_compare_func, NULL, NULL);
663 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), LST_DEFCUR_DATAS, GTK_SORT_ASCENDING);
664
665 return treeview;
666 }
667
668
669 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
670 /*
671 ** update the number sample label
672 */
673 static void ui_cur_edit_dialog_update_sample(GtkWidget *widget, gpointer user_data)
674 {
675 struct ui_cur_edit_dialog_data *data;
676 Currency cur;
677 gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
678 gchar buf[128];
679
680 DB( g_print("\n[ui-pref] number sample\n") );
681
682 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
683
684 cur.symbol = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_symbol));
685 cur.sym_prefix = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_symisprefix));
686 cur.decimal_char = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_decimalchar));
687 cur.grouping_char = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_groupingchar));
688 cur.frac_digits = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->NB_fracdigits));
689
690 da_cur_initformat (&cur);
691 DB( g_print("fmt: %s\n", cur.format) );
692
693 g_ascii_formatd(formatd_buf, sizeof (formatd_buf), cur.format, HB_NUMBER_SAMPLE);
694
695 hb_str_formatd(buf, 127, formatd_buf, &cur, TRUE);
696 gtk_label_set_text(GTK_LABEL(data->LB_sample), buf);
697
698 }
699
700
701
702 static void ui_cur_edit_dialog_set(GtkWidget *widget, Currency *cur)
703 {
704 struct ui_cur_edit_dialog_data *data;
705 Currency *base;
706 gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
707 gchar label[128];
708
709 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
710
711 g_snprintf(label, 127, "%s - %s", cur->iso_code, cur->name);
712 gtk_label_set_text (GTK_LABEL(data->LB_name), label);
713
714 base = da_cur_get(GLOBALS->kcur);
715
716 g_snprintf(label, 127, "1 %s _=", base->iso_code);
717 gtk_label_set_text_with_mnemonic (GTK_LABEL(data->LB_rate), label);
718 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->NB_rate), cur->rate);
719
720 da_cur_initformat(cur);
721 g_ascii_formatd(formatd_buf, sizeof (formatd_buf), cur->format, HB_NUMBER_SAMPLE);
722 hb_str_formatd(label, 127, formatd_buf, cur, TRUE);
723 gtk_label_set_text (GTK_LABEL(data->LB_sample), label);
724
725 ui_gtk_entry_set_text(data->ST_symbol, cur->symbol);
726 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->CM_symisprefix), cur->sym_prefix);
727 ui_gtk_entry_set_text(data->ST_decimalchar, cur->decimal_char);
728 ui_gtk_entry_set_text(data->ST_groupingchar, cur->grouping_char);
729 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->NB_fracdigits), cur->frac_digits);
730
731 }
732
733
734
735 static void ui_cur_edit_dialog_get(GtkWidget *widget, Currency *cur)
736 {
737 struct ui_cur_edit_dialog_data *data;
738 gdouble rate;
739
740 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
741
742
743 ui_gtk_entry_replace_text(data->ST_symbol, &cur->symbol);
744 cur->sym_prefix = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_symisprefix));
745 ui_gtk_entry_replace_text(data->ST_decimalchar, &cur->decimal_char);
746 ui_gtk_entry_replace_text(data->ST_groupingchar, &cur->grouping_char);
747 cur->frac_digits = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->NB_fracdigits));
748
749 da_cur_initformat(cur);
750
751 rate = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->NB_rate));
752 if(cur->rate != rate)
753 {
754 cur->rate = rate;
755 cur->mdate = GLOBALS->today;
756 }
757
758 }
759
760
761 void ui_cur_edit_dialog_new(GtkWindow *parent, Currency *cur)
762 {
763 struct ui_cur_edit_dialog_data data;
764 GtkWidget *dialog, *content_area, *content_grid, *group_grid;
765 GtkWidget *label, *widget, *expander;
766 gint crow, row;
767
768 dialog = gtk_dialog_new_with_buttons (
769 _("Edit currency"),
770 GTK_WINDOW (parent),
771 0,
772 _("_Cancel"),
773 GTK_RESPONSE_REJECT,
774 _("_OK"),
775 GTK_RESPONSE_ACCEPT,
776 NULL);
777
778 data.window = dialog;
779
780 //store our dialog private data
781 g_object_set_data(G_OBJECT(dialog), "inst_data", (gpointer)&data);
782 DB( g_printf("(ui_cur_select_dialog_new) dialog=%x, inst_data=%x\n", (guint)dialog, (guint)&data) );
783
784
785 content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog)); // return a vbox
786
787 content_grid = gtk_grid_new();
788 gtk_grid_set_row_spacing (GTK_GRID (content_grid), SPACING_LARGE);
789 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
790 gtk_container_set_border_width (GTK_CONTAINER(content_grid), SPACING_MEDIUM);
791 gtk_box_pack_start (GTK_BOX (content_area), content_grid, TRUE, TRUE, 0);
792
793 crow = 0;
794 // group :: Currency
795 group_grid = gtk_grid_new ();
796 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
797 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
798 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
799
800 label = make_label_group(_("Currency"));
801 gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
802
803 row = 1;
804 widget = make_label(NULL, 0, 0.5);
805 data.LB_name = widget;
806 gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 2, 1);
807
808 // group :: exchange
809 group_grid = gtk_grid_new ();
810 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
811 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
812 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
813
814 label = make_label_group(_("Exchange rate"));
815 gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
816
817 row = 1;
818 label = make_label(NULL, 0, 0.5);
819 data.LB_rate = label;
820 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
821 widget = make_exchange_rate(label);
822 data.NB_rate = widget;
823 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
824
825 gtk_widget_set_sensitive(group_grid, (GLOBALS->kcur == cur->key) ? FALSE : TRUE);
826
827 // group :: format
828 group_grid = gtk_grid_new ();
829 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
830 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
831 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
832
833 label = make_label_group(_("Format"));
834 gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
835
836 row++;
837 widget = make_label(NULL, 0, 0.5);
838 data.LB_sample = widget;
839 gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 2, 1);
840
841 row++;
842 expander = gtk_expander_new_with_mnemonic (_("_Customize"));
843 gtk_grid_attach (GTK_GRID (group_grid), expander, 1, row, 2, 1);
844
845 group_grid = gtk_grid_new ();
846 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
847 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
848 gtk_container_add (GTK_CONTAINER (expander), group_grid);
849
850 row = 1;
851 label = make_label_widget(_("_Symbol:"));
852 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
853 widget = make_string_maxlength(label, 3);
854 data.ST_symbol = widget;
855 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
856
857 row++;
858 widget = gtk_check_button_new_with_mnemonic (_("Is pre_fix"));
859 data.CM_symisprefix = widget;
860 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
861
862 row++;
863 label = make_label_widget(_("_Decimal char:"));
864 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
865 widget = make_string_maxlength(label, 1);
866 data.ST_decimalchar = widget;
867 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
868
869 row++;
870 label = make_label_widget(_("_Frac digits:"));
871 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
872 widget = make_numeric(label, 0.0, 6.0);
873 data.NB_fracdigits = widget;
874 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
875
876 row++;
877 label = make_label_widget(_("_Grouping char:"));
878 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
879 widget = make_string_maxlength(label, 1);
880 data.ST_groupingchar = widget;
881 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
882
883
884 //gtk_window_resize(GTK_WINDOW(dialog), 400/PHI, 400);
885
886 ui_cur_edit_dialog_set(dialog, cur);
887
888 gtk_widget_show_all(content_area);
889
890 //signals
891 g_signal_connect (data.ST_symbol , "changed", G_CALLBACK (ui_cur_edit_dialog_update_sample), NULL);
892 g_signal_connect (data.CM_symisprefix, "toggled", G_CALLBACK (ui_cur_edit_dialog_update_sample), NULL);
893 g_signal_connect (data.ST_decimalchar , "changed", G_CALLBACK (ui_cur_edit_dialog_update_sample), NULL);
894 g_signal_connect (data.ST_groupingchar, "changed", G_CALLBACK (ui_cur_edit_dialog_update_sample), NULL);
895 g_signal_connect (data.NB_fracdigits, "value-changed", G_CALLBACK (ui_cur_edit_dialog_update_sample), NULL);
896
897 // wait for the user
898 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
899 if(result == GTK_RESPONSE_ACCEPT)
900 {
901 ui_cur_edit_dialog_get(dialog, cur);
902 }
903
904 // cleanup and destroy
905 gtk_widget_destroy (dialog);
906
907 }
908
909
910 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
911
912 enum {
913 LST_CURSEL_NAME,
914 LST_CURSEL_ISO,
915 LST_CURSEL_FULLNAME,
916 LST_CURSEL_DATA,
917 NUM_LST_CURSEL
918 };
919
920
921 static void ui_cur_select_rowactivated (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer userdata)
922 {
923 struct ui_cur_select_dialog_data *data = userdata;
924
925 gtk_dialog_response(GTK_DIALOG(data->window), GTK_RESPONSE_ACCEPT);
926 }
927
928
929 static GtkTreeModel *ui_cur_select_model_create (void)
930 {
931 guint i = 0;
932 GtkListStore *store;
933 GtkTreeIter iter;
934 Currency4217 *cur;
935 gchar buffer[255];
936
937 /* create list store */
938 store = gtk_list_store_new (NUM_LST_CURSEL,
939 G_TYPE_STRING,
940 G_TYPE_STRING,
941 G_TYPE_STRING,
942 G_TYPE_POINTER,
943 NULL
944 );
945
946 for (i = 0; i< n_iso4217cur; i++)
947 {
948 cur = &iso4217cur[i];
949
950 g_snprintf(buffer, 255-1, "%s - %s", cur->curr_iso_code, cur->name);
951
952 gtk_list_store_append (store, &iter);
953 gtk_list_store_set (store, &iter,
954 LST_CURSEL_NAME, cur->name,
955 LST_CURSEL_ISO, cur->curr_iso_code,
956 LST_CURSEL_FULLNAME, buffer,
957 LST_CURSEL_DATA, cur,
958 -1);
959
960
961 }
962
963 return GTK_TREE_MODEL (store);
964 }
965
966
967 static Currency4217 *ui_cur_select_dialog_get_langue(struct ui_cur_select_dialog_data *data)
968 {
969 GtkTreeSelection *treeselection;
970 gboolean selected;
971 GtkTreeModel *model;
972 GtkTreeIter iter;
973 Currency4217 *curfmt = NULL;
974
975 DB( g_printf("\n(ui_cur_select_dialog_get_langue)\n") );
976
977 treeselection = gtk_tree_view_get_selection (GTK_TREE_VIEW(data->LV_cur));
978 selected = gtk_tree_selection_get_selected(treeselection, &model, &iter);
979 if(selected)
980 {
981 gtk_tree_model_get(model, &iter, LST_CURSEL_DATA, &curfmt, -1);
982
983 DB( g_printf(" - iso is '%s'\n", curfmt->curr_iso_code) );
984 }
985
986 return curfmt;
987 }
988
989
990 static void
991 ui_cur_select_search_changed_cb (GtkWidget *widget, gpointer user_data)
992 {
993 struct ui_cur_select_dialog_data *data = user_data;
994
995 DB( g_print(" search changed\n") );
996
997 gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(data->modelfilter));
998
999 }
1000
1001
1002 static gboolean
1003 ui_cur_select_model_func_visible (GtkTreeModel *model,
1004 GtkTreeIter *iter,
1005 gpointer data)
1006 {
1007 // Visible if row is non-empty and first column is “HI”
1008 gchar *str;
1009 gboolean visible = TRUE;
1010 GtkEntry *entry = data;
1011
1012 if(!GTK_IS_ENTRY(entry))
1013 return TRUE;
1014
1015 gchar *needle = g_ascii_strdown(gtk_entry_get_text(entry), -1);
1016
1017 gtk_tree_model_get (model, iter, LST_CURSEL_FULLNAME, &str, -1);
1018
1019 gchar *haystack = g_ascii_strdown(str, -1);
1020
1021 if (str && g_strrstr (haystack, needle) == NULL)
1022 {
1023 visible = FALSE;
1024 }
1025
1026 DB( g_print("filter: '%s' '%s' %d\n", str, needle, visible) );
1027
1028 g_free(haystack);
1029 g_free(needle);
1030 g_free (str);
1031
1032 return visible;
1033 }
1034
1035
1036 Currency4217 * ui_cur_select_dialog_new(GtkWindow *parent, gint select_mode)
1037 {
1038 struct ui_cur_select_dialog_data data;
1039 GtkWidget *dialog, *content_area, *content_grid, *group_grid;
1040 GtkWidget *scrollwin, *treeview, *widget;
1041 gint crow, row;
1042 Currency4217 *curfmt = NULL;
1043
1044 dialog = gtk_dialog_new_with_buttons (
1045 (select_mode == CUR_SELECT_MODE_BASE) ? _("Select base currency") : _("Select currency"),
1046 GTK_WINDOW (parent),
1047 0,
1048 _("_Cancel"),
1049 GTK_RESPONSE_REJECT,
1050 _("_OK"),
1051 GTK_RESPONSE_ACCEPT,
1052 NULL);
1053
1054 data.window = dialog;
1055
1056 //store our dialog private data
1057 g_object_set_data(G_OBJECT(dialog), "inst_data", (gpointer)&data);
1058 DB( g_printf("(ui_cur_select_dialog_new) dialog=%x, inst_data=%x\n", (guint)dialog, (guint)&data) );
1059
1060
1061 content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog)); // return a vbox
1062
1063 content_grid = gtk_grid_new();
1064 gtk_grid_set_row_spacing (GTK_GRID (content_grid), SPACING_LARGE);
1065 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
1066 gtk_container_set_border_width (GTK_CONTAINER(content_grid), SPACING_MEDIUM);
1067 gtk_box_pack_start (GTK_BOX (content_area), content_grid, TRUE, TRUE, 0);
1068
1069 crow = 0;
1070 // group :: Search
1071 group_grid = gtk_grid_new ();
1072 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
1073 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
1074 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
1075
1076 row = 1;
1077 widget = gtk_search_entry_new();
1078 data.ST_search = widget;
1079 gtk_widget_set_hexpand (widget, TRUE);
1080 gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 1, 1);
1081
1082
1083 row++;
1084 scrollwin = gtk_scrolled_window_new(NULL,NULL);
1085 gtk_grid_attach (GTK_GRID (group_grid), scrollwin, 1, row, 1, 1);
1086
1087 gtk_widget_set_vexpand (scrollwin, TRUE);
1088 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
1089 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1090
1091 //test treefilter
1092 data.model = ui_cur_select_model_create();
1093 data.modelfilter = gtk_tree_model_filter_new(GTK_TREE_MODEL(data.model), NULL);
1094 gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(data.modelfilter), ui_cur_select_model_func_visible, data.ST_search, NULL);
1095 data.sortmodel = gtk_tree_model_sort_new_with_model(data.modelfilter);
1096
1097
1098 //
1099
1100 treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL(data.sortmodel));
1101 data.LV_cur = treeview;
1102 //gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview), LST_CURSEL_NAME);
1103 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(data.sortmodel), LST_CURSEL_NAME, GTK_SORT_ASCENDING);
1104 //g_object_unref (model);
1105 gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
1106
1107 // populate list
1108 GtkCellRenderer *renderer;
1109 GtkTreeViewColumn *column;
1110
1111 renderer = gtk_cell_renderer_text_new ();
1112 column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, "text", LST_CURSEL_NAME, NULL);
1113 gtk_tree_view_column_set_sort_column_id (column, LST_CURSEL_NAME);
1114 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1115
1116 renderer = gtk_cell_renderer_text_new ();
1117 column = gtk_tree_view_column_new_with_attributes (_("ISO Code"), renderer, "text", LST_CURSEL_ISO, NULL);
1118 gtk_tree_view_column_set_sort_column_id (column, LST_CURSEL_ISO);
1119 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1120
1121 gtk_window_resize(GTK_WINDOW(dialog), 400/PHI, 400);
1122
1123
1124 gtk_widget_show_all(content_area);
1125
1126 // signals
1127 g_signal_connect (data.ST_search, "search-changed", G_CALLBACK (ui_cur_select_search_changed_cb), &data);
1128 g_signal_connect (GTK_TREE_VIEW(data.LV_cur), "row-activated", G_CALLBACK (ui_cur_select_rowactivated), &data);
1129
1130
1131 // wait for the user
1132 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
1133 if(result == GTK_RESPONSE_ACCEPT)
1134 {
1135 curfmt = ui_cur_select_dialog_get_langue(&data);
1136 }
1137
1138
1139 // cleanup and destroy
1140 gtk_widget_destroy (dialog);
1141
1142 return curfmt;
1143 }
1144
1145
1146 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
1147
1148
1149 gint ui_cur_manage_dialog_update_currencies(GtkWindow *parent)
1150 {
1151 GError *error = NULL;
1152 gboolean retcode = FALSE;
1153
1154 DB( g_printf("\n(ui_cur_manage) update currencies\n") );
1155
1156 // do nothing if just the base currency
1157 if(da_cur_length() <= 1)
1158 return TRUE;
1159
1160 retcode = currency_sync_online(&error);
1161
1162 DB( g_print("retcode: %d\n", retcode) );
1163
1164 if(!retcode)
1165 {
1166 gchar *msg = _("Unknow error");
1167
1168 if( error )
1169 msg = error->message;
1170
1171 g_warning("update online: '%s'", msg);
1172
1173 ui_dialog_msg_infoerror(GTK_WINDOW(parent), GTK_MESSAGE_ERROR,
1174 _("Update online error"),
1175 msg,
1176 NULL
1177 );
1178
1179 if( error )
1180 g_error_free (error);
1181 }
1182
1183 return retcode;
1184 }
1185
1186
1187 static void
1188 ui_cur_manage_dialog_sync(GtkWidget *widget, gpointer user_data)
1189 {
1190 struct ui_cur_manage_dialog_data *data;
1191 gboolean retcode;
1192
1193 DB( g_printf("\n(ui_cur_manage) sync online\n") );
1194
1195 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1196
1197 retcode = ui_cur_manage_dialog_update_currencies(GTK_WINDOW(data->window));
1198
1199 if(retcode == TRUE)
1200 {
1201 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_cur));
1202 //todo: (or not) msg with changes
1203
1204 }
1205 }
1206
1207
1208 /**
1209 * ui_cur_manage_dialog_add:
1210 *
1211 */
1212 static void
1213 ui_cur_manage_dialog_add(GtkWidget *widget, gpointer user_data)
1214 {
1215 struct ui_cur_manage_dialog_data *data;
1216 Currency4217 *curfmt;
1217
1218 DB( g_printf("\n(ui_cur_manage) add\n") );
1219
1220 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1221
1222 curfmt = ui_cur_select_dialog_new(GTK_WINDOW(data->window), CUR_SELECT_MODE_NORMAL);
1223 if( curfmt != NULL )
1224 {
1225 Currency *item;
1226
1227 DB( g_printf("- user selected: '%s' '%s'\n", curfmt->curr_iso_code, curfmt->name) );
1228 item = da_cur_get_by_iso_code(curfmt->curr_iso_code);
1229 if( item == NULL )
1230 {
1231 item = currency_add_from_user(curfmt);
1232 ui_cur_listview_add(GTK_TREE_VIEW(data->LV_cur), item);
1233 gtk_tree_sortable_sort_column_changed(GTK_TREE_SORTABLE(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_cur))));
1234
1235 ui_cur_manage_dialog_update (widget, user_data);
1236 GLOBALS->changes_count++;
1237 }
1238 else
1239 {
1240 DB( g_printf("- already exists\n") );
1241 }
1242 }
1243 }
1244
1245
1246
1247 static void
1248 ui_cur_manage_dialog_modify(GtkWidget *widget, gpointer user_data)
1249 {
1250 struct ui_cur_manage_dialog_data *data;
1251 GtkTreeSelection *selection;
1252 GtkTreeModel *model;
1253 GtkTreeIter iter;
1254
1255 DB( g_printf("\n(ui_cur_manage) modify\n") );
1256
1257
1258 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1259
1260 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_cur));
1261 if (gtk_tree_selection_get_selected(selection, &model, &iter))
1262 {
1263 Currency *item;
1264
1265 gtk_tree_model_get(model, &iter, LST_DEFCUR_DATAS, &item, -1);
1266
1267 if( item!= NULL )
1268 {
1269 ui_cur_edit_dialog_new(GTK_WINDOW(data->window), item);
1270 GLOBALS->changes_count++;
1271 }
1272
1273 }
1274 }
1275
1276
1277 /*
1278 ** remove the selected curee to our treeview and temp GList
1279 */
1280 static void ui_cur_manage_dialog_remove(GtkWidget *widget, gpointer user_data)
1281 {
1282 struct ui_cur_manage_dialog_data *data;
1283 guint32 key;
1284 gboolean do_remove, result;
1285
1286 DB( g_printf("\n(ui_cur_manage) remove\n") );
1287
1288 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1289
1290 do_remove = TRUE;
1291 key = ui_cur_listview_get_selected_key(GTK_TREE_VIEW(data->LV_cur));
1292 if( key > 0 )
1293 {
1294 Currency *cur;
1295 gchar *title;
1296 gchar *secondtext;
1297
1298 if( currency_is_used(key) == TRUE )
1299 {
1300 do_remove = FALSE;
1301 }
1302 else
1303 {
1304 cur = da_cur_get(key);
1305
1306 title = g_strdup_printf (
1307 _("Are you sure you want to permanently delete '%s'?"), cur->name);
1308
1309 secondtext = _("If you delete a currency, it will be permanently lost.");
1310
1311 result = ui_dialog_msg_confirm_alert(
1312 GTK_WINDOW(data->window),
1313 title,
1314 secondtext,
1315 _("_Delete")
1316 );
1317
1318 g_free(title);
1319
1320 do_remove = (result == GTK_RESPONSE_OK) ? TRUE :FALSE;
1321 }
1322
1323 if( do_remove )
1324 {
1325 da_cur_remove(key);
1326 ui_cur_listview_remove_selected(GTK_TREE_VIEW(data->LV_cur));
1327 ui_cur_manage_dialog_update (widget, user_data);
1328 data->change++;
1329 }
1330 }
1331
1332 }
1333
1334 /*
1335 ** button callback: set base currency
1336 */
1337 static void ui_cur_manage_dialog_setbase(GtkWidget *widget, gpointer user_data)
1338 {
1339 struct ui_cur_manage_dialog_data *data;
1340 guint32 key;
1341 gboolean do_change;
1342
1343 DB( g_printf("\n(ui_cur_manage) setbase\n") );
1344
1345
1346 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1347
1348 key = ui_cur_listview_get_selected_key(GTK_TREE_VIEW(data->LV_cur));
1349 if( key > 0 )
1350 {
1351 do_change = ui_dialog_msg_question(
1352 GTK_WINDOW(data->window),
1353 _("Change the base currency"),
1354 _("If you proceed, rates of other currencies\n"
1355 "will be set to 0, don't forget to update it"),
1356 NULL
1357 );
1358 if(do_change == GTK_RESPONSE_YES)
1359 {
1360 hbfile_change_basecurrency(key);
1361 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(data->LV_cur));
1362 }
1363 }
1364
1365 }
1366
1367
1368 /*
1369 **
1370 */
1371 static void ui_cur_manage_dialog_update(GtkWidget *treeview, gpointer user_data)
1372 {
1373 struct ui_cur_manage_dialog_data *data;
1374 GtkTreeSelection *selection;
1375 GtkTreeModel *model;
1376 GtkTreeIter iter;
1377 Currency *item;
1378 gboolean sensitive;
1379
1380 DB( g_printf("\n(ui_cur_manage_dialog) update\n") );
1381
1382 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW)), "inst_data");
1383
1384 sensitive = da_cur_length() <= 1 ? FALSE : TRUE;
1385 gtk_widget_set_sensitive (data->BB_update, sensitive);
1386
1387
1388 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_cur));
1389
1390 //if true there is a selected node
1391 if (gtk_tree_selection_get_selected(selection, &model, &iter))
1392 {
1393 gtk_tree_model_get(model, &iter, LST_DEFCUR_DATAS, &item, -1);
1394
1395 gtk_widget_set_sensitive(data->BT_edit, TRUE);
1396
1397 sensitive = !(currency_is_used(item->key));
1398 //gtk_widget_set_sensitive(data->BT_mov, sensitive);
1399 //gtk_widget_set_sensitive(data->BT_mod, sensitive);
1400 gtk_widget_set_sensitive(data->BT_rem, sensitive);
1401
1402 //disable set as base on actual base currency
1403 sensitive = (item->key != GLOBALS->kcur) ? TRUE : FALSE;
1404 gtk_widget_set_sensitive(data->BT_base, sensitive);
1405 }
1406 else
1407 {
1408 gtk_widget_set_sensitive(data->BT_edit, FALSE);
1409 gtk_widget_set_sensitive(data->BT_rem , FALSE);
1410 gtk_widget_set_sensitive(data->BT_base, FALSE);
1411 }
1412 }
1413
1414
1415 /*
1416 **
1417 */
1418 static void ui_cur_manage_dialog_selection(GtkTreeSelection *treeselection, gpointer user_data)
1419 {
1420 ui_cur_manage_dialog_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), NULL);
1421 }
1422
1423 static void ui_cur_manage_dialog_onRowActivated (GtkTreeView *treeview,
1424 GtkTreePath *path,
1425 GtkTreeViewColumn *col,
1426 gpointer userdata)
1427 {
1428
1429 //model = gtk_tree_view_get_model(treeview);
1430 //gtk_tree_model_get_iter_first(model, &iter);
1431 //if(gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), &iter) == FALSE)
1432 //{
1433 ui_cur_manage_dialog_modify(GTK_WIDGET(treeview), NULL);
1434 //}
1435 }
1436
1437
1438
1439 /*
1440 **
1441 */
1442 static void ui_cur_manage_dialog_setup(struct ui_cur_manage_dialog_data *data)
1443 {
1444
1445 DB( g_printf("\n(ui_cur_manage_setup)\n") );
1446
1447
1448 ui_cur_listview_populate(data->LV_cur);
1449
1450 //ui_cur_combobox_populate(data->CY_curr, GLOBALS->h_cur);
1451 //ui_cur_combobox_set_active(GTK_COMBO_BOX(data->CY_curr), GLOBALS->kcur);
1452
1453
1454
1455 }
1456
1457
1458 /*
1459 **
1460 */
1461 GtkWidget *ui_cur_manage_dialog (void)
1462 {
1463 struct ui_cur_manage_dialog_data data;
1464 GtkWidget *dialog, *content_area, *content_grid, *group_grid, *bbox;
1465 GtkWidget *widget, *scrollwin, *treeview;
1466 gint crow, row, w, h;
1467
1468 DB( g_printf("\n(ui_cur_manage_dialog)\n") );
1469
1470 dialog = gtk_dialog_new_with_buttons (_("Currencies"),
1471 GTK_WINDOW(GLOBALS->mainwindow),
1472 0,
1473 _("_Close"),
1474 GTK_RESPONSE_ACCEPT,
1475 NULL);
1476
1477 data.window = dialog;
1478 data.change = 0;
1479
1480 //set the dialog icon
1481 gtk_window_set_icon_name(GTK_WINDOW (dialog), ICONNAME_HB_CURRENCY);
1482
1483 //set a nice dialog size
1484 gtk_window_get_size(GTK_WINDOW(GLOBALS->mainwindow), &w, &h);
1485 gtk_window_set_default_size (GTK_WINDOW(dialog), -1, h/PHI);
1486
1487
1488 //store our window private data
1489 g_object_set_data(G_OBJECT(dialog), "inst_data", (gpointer)&data);
1490 DB( g_printf("(ui_cur_manage_dialog) dialog=%p, inst_data=%p\n", dialog, &data) );
1491
1492 g_signal_connect (dialog, "destroy",
1493 G_CALLBACK (gtk_widget_destroyed), &dialog);
1494
1495 content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog)); // return a vbox
1496
1497 content_grid = gtk_grid_new();
1498 gtk_grid_set_row_spacing (GTK_GRID (content_grid), SPACING_LARGE);
1499 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
1500 gtk_container_set_border_width (GTK_CONTAINER(content_grid), SPACING_MEDIUM);
1501 gtk_box_pack_start (GTK_BOX (content_area), content_grid, TRUE, TRUE, 0);
1502
1503 crow = 0;
1504 // group :: --------
1505 group_grid = gtk_grid_new ();
1506 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
1507 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
1508 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
1509
1510 row = 1;
1511 bbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, SPACING_MEDIUM);
1512 data.BB_update = bbox;
1513 gtk_grid_attach (GTK_GRID(group_grid), bbox, 0, row, 1, 1);
1514
1515 widget = gtk_button_new_from_icon_name (ICONNAME_REFRESH, GTK_ICON_SIZE_BUTTON);
1516 gtk_container_add (GTK_CONTAINER (bbox), widget);
1517
1518 g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (ui_cur_manage_dialog_sync), NULL);
1519
1520 widget = make_label_widget (_("Update online"));
1521 gtk_container_add (GTK_CONTAINER (bbox), widget);
1522
1523 row++;
1524 scrollwin = gtk_scrolled_window_new(NULL,NULL);
1525 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
1526 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1527 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrollwin), HB_MINHEIGHT_LIST);
1528 treeview = ui_cur_listview_new(FALSE);
1529 data.LV_cur = treeview;
1530 gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
1531 gtk_widget_set_vexpand (scrollwin, TRUE);
1532 gtk_widget_set_hexpand (scrollwin, TRUE);
1533 gtk_grid_attach (GTK_GRID(group_grid), scrollwin, 0, row, 2, 1);
1534
1535 row++;
1536 bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
1537 gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
1538 gtk_box_set_spacing (GTK_BOX (bbox), SPACING_SMALL);
1539 gtk_grid_attach (GTK_GRID (group_grid), bbox, 0, row, 2, 1);
1540
1541 widget = gtk_button_new_with_mnemonic(_("_Add"));
1542 data.BT_add = widget;
1543 gtk_container_add (GTK_CONTAINER (bbox), widget);
1544
1545 widget = gtk_button_new_with_mnemonic(_("_Edit"));
1546 data.BT_edit = widget;
1547 gtk_container_add (GTK_CONTAINER (bbox), widget);
1548
1549 widget = gtk_button_new_with_mnemonic(_("_Delete"));
1550 data.BT_rem = widget;
1551 gtk_container_add (GTK_CONTAINER (bbox), widget);
1552
1553 widget = gtk_button_new_with_mnemonic(_("Set as base"));
1554 data.BT_base = widget;
1555 gtk_container_add (GTK_CONTAINER (bbox), widget);
1556
1557
1558 //connect all our signals
1559 //g_signal_connect (G_OBJECT (data.ST_name), "activate", G_CALLBACK (ui_cur_manage_dialog_add), NULL);
1560
1561 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data.LV_cur)), "changed", G_CALLBACK (ui_cur_manage_dialog_selection), NULL);
1562 g_signal_connect (GTK_TREE_VIEW(data.LV_cur), "row-activated", G_CALLBACK (ui_cur_manage_dialog_onRowActivated), NULL);
1563
1564 g_signal_connect (G_OBJECT (data.BT_add), "clicked", G_CALLBACK (ui_cur_manage_dialog_add), NULL);
1565 g_signal_connect (G_OBJECT (data.BT_rem), "clicked", G_CALLBACK (ui_cur_manage_dialog_remove), NULL);
1566 g_signal_connect (G_OBJECT (data.BT_edit), "clicked", G_CALLBACK (ui_cur_manage_dialog_modify), NULL);
1567 //g_signal_connect (G_OBJECT (data.BT_mov), "clicked", G_CALLBACK (ui_cur_manage_dialog_move), NULL);
1568 g_signal_connect (G_OBJECT (data.BT_base), "clicked", G_CALLBACK (ui_cur_manage_dialog_setbase), NULL);
1569
1570 //setup, init and show window
1571 ui_cur_manage_dialog_setup(&data);
1572
1573 ui_cur_manage_dialog_update(data.LV_cur, NULL);
1574
1575 //gtk_window_resize(GTK_WINDOW(dialog), 256, 414);
1576
1577 gtk_widget_show_all (dialog);
1578
1579 //wait for the user
1580 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
1581
1582 switch (result)
1583 {
1584 case GTK_RESPONSE_ACCEPT:
1585 //do_application_specific_something ();
1586 break;
1587 default:
1588 //do_nothing_since_dialog_was_cancelled ();
1589 break;
1590 }
1591
1592
1593 // cleanup and destroy
1594 GLOBALS->changes_count += data.change;
1595 gtk_widget_destroy (dialog);
1596
1597 return NULL;
1598 }
1599
1600
1601
This page took 0.100518 seconds and 4 git commands to generate.