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/>.
23 #include "gtk-chart.h"
24 #include "ui-widgets.h"
26 /****************************************************************************/
28 /****************************************************************************/
37 /* our global datas */
38 extern struct HomeBank
*GLOBALS
;
41 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
44 extern gchar
*CYA_FLT_RANGE
[];
48 gimp_label_set_attributes (GtkLabel
*label
,
51 PangoAttribute
*attr
= NULL
;
55 g_return_if_fail (GTK_IS_LABEL (label
));
57 attrs
= pango_attr_list_new ();
59 va_start (args
, label
);
63 PangoAttrType attr_type
= va_arg (args
, PangoAttrType
);
66 attr_type
= PANGO_ATTR_INVALID
;
70 case PANGO_ATTR_LANGUAGE
:
71 attr
= pango_attr_language_new (va_arg (args
, PangoLanguage
*));
74 case PANGO_ATTR_FAMILY
:
75 attr
= pango_attr_family_new (va_arg (args
, const gchar
*));
78 case PANGO_ATTR_STYLE
:
79 attr
= pango_attr_style_new (va_arg (args
, PangoStyle
));
82 case PANGO_ATTR_WEIGHT
:
83 attr
= pango_attr_weight_new (va_arg (args
, PangoWeight
));
86 case PANGO_ATTR_VARIANT
:
87 attr
= pango_attr_variant_new (va_arg (args
, PangoVariant
));
90 case PANGO_ATTR_STRETCH
:
91 attr
= pango_attr_stretch_new (va_arg (args
, PangoStretch
));
95 attr
= pango_attr_size_new (va_arg (args
, gint
));
98 case PANGO_ATTR_FONT_DESC
:
99 attr
= pango_attr_font_desc_new (va_arg (args
,
100 const PangoFontDescription
*));
103 case PANGO_ATTR_FOREGROUND
:
105 const PangoColor
*color
= va_arg (args
, const PangoColor
*);
107 attr
= pango_attr_foreground_new (color
->red
,
113 case PANGO_ATTR_BACKGROUND
:
115 const PangoColor
*color
= va_arg (args
, const PangoColor
*);
117 attr
= pango_attr_background_new (color
->red
,
123 case PANGO_ATTR_UNDERLINE
:
124 attr
= pango_attr_underline_new (va_arg (args
, PangoUnderline
));
127 case PANGO_ATTR_STRIKETHROUGH
:
128 attr
= pango_attr_strikethrough_new (va_arg (args
, gboolean
));
131 case PANGO_ATTR_RISE
:
132 attr
= pango_attr_rise_new (va_arg (args
, gint
));
135 case PANGO_ATTR_SCALE
:
136 attr
= pango_attr_scale_new (va_arg (args
, gdouble
));
140 //g_warning ("%s: invalid PangoAttribute type %d", G_STRFUNC, attr_type);
141 case PANGO_ATTR_INVALID
:
148 attr
->start_index
= 0;
149 attr
->end_index
= -1;
150 pango_attr_list_insert (attrs
, attr
);
157 gtk_label_set_attributes (label
, attrs
);
158 pango_attr_list_unref (attrs
);
162 void hb_widget_visible(GtkWidget
*widget
, gboolean visible
)
164 if(!GTK_IS_WIDGET(widget
))
169 gtk_widget_show(widget
);
173 gtk_widget_hide(widget
);
178 void ui_gtk_entry_set_text(GtkWidget
*widget
, gchar
*text
)
180 DB( g_print(" set text to '%s'\n", text
) );
183 gtk_entry_set_text(GTK_ENTRY(widget
), text
);
185 gtk_entry_set_text(GTK_ENTRY(widget
), "");
192 GtkWidget
*make_label(char *str
, gfloat xalign
, gfloat yalign
)
196 label
= gtk_label_new_with_mnemonic (str
);
197 gtk_misc_set_alignment (GTK_MISC (label
), xalign
, yalign
);
206 GtkWidget
*make_text(gfloat xalign
)
210 entry
= gtk_entry_new ();
211 gtk_editable_set_editable (GTK_EDITABLE(entry
), FALSE
);
212 g_object_set(entry
, "xalign", xalign
, NULL
);
214 //entry = gtk_label_new(NULL);
215 //gtk_misc_set_padding (entry, 4, 2);
216 //gtk_misc_set_alignment(entry, xalign, 0.5);
224 GtkWidget
*make_string(GtkWidget
*label
)
228 entry
= gtk_entry_new ();
231 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), entry
);
239 GtkWidget
*make_memo_entry(GtkWidget
*label
)
243 GtkEntryCompletion
*completion
;
246 store
= gtk_list_store_new (1, G_TYPE_STRING
);
248 completion
= gtk_entry_completion_new ();
249 gtk_entry_completion_set_model (completion
, GTK_TREE_MODEL(store
));
250 gtk_entry_completion_set_text_column (completion
, 0);
252 entry
= gtk_entry_new ();
253 gtk_entry_set_completion (GTK_ENTRY (entry
), completion
);
255 g_object_unref(store
);
258 //gtk_list_store_clear (GTK_LIST_STORE(store));
260 lmem
= list
= g_hash_table_get_keys(GLOBALS
->h_memo
);
265 gtk_list_store_append (GTK_LIST_STORE(store
), &iter
);
266 gtk_list_store_set (GTK_LIST_STORE(store
), &iter
, 0, list
->data
, -1);
268 list
= g_list_next(list
);
274 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), entry
);
283 GtkWidget
*make_string_maxlength(GtkWidget
*label
, guint max_length
)
287 entry
= make_string(label
);
288 gtk_entry_set_max_length(GTK_ENTRY(entry
), max_length
);
295 static void hb_amount_insert_text_handler (GtkEntry
*entry
, const gchar
*text
, gint length
, gint
*position
, gpointer data
)
297 GtkEditable
*editable
= GTK_EDITABLE(entry
);
298 int i
, count
=0, dcpos
=-1;
299 gchar
*result
= g_new0 (gchar
, length
+1);
300 const gchar
*numtext
;
302 //g_message("insert_text-handler: text:%s - pos:%d - length:%d", text, *position, length);
304 numtext
= gtk_entry_get_text(entry
);
305 for (i
=0 ; numtext
[i
]!='\0' ; i
++)
307 if(numtext
[i
]==',' || numtext
[i
]=='.')
312 //g_message("previous text='%s' dcpos:'%d'", numtext, dcpos);
313 for (i
=0 ; i
< length
; i
++)
315 if( isdigit(text
[i
]) && ( (*position
<= dcpos
+2) || dcpos
< 0) )
318 if( text
[i
]=='-' && *position
==0 ) /* minus sign only at position 0 */
321 if( dcpos
< 0 && (text
[i
]=='.' || text
[i
]==',') ) /* decimal separator if not in previous string */
322 result
[count
++] = '.';
327 result
[count
++] = text
[i
];
331 g_signal_handlers_block_by_func (G_OBJECT (editable
), G_CALLBACK (hb_amount_insert_text_handler
), data
);
332 gtk_editable_insert_text (editable
, result
, count
, position
);
333 g_signal_handlers_unblock_by_func (G_OBJECT (editable
), G_CALLBACK (hb_amount_insert_text_handler
), data
);
335 g_signal_stop_emission_by_name (G_OBJECT (editable
), "insert_text");
343 GtkWidget
*make_amount(GtkWidget
*label
)
348 adj
= (GtkAdjustment
*) gtk_adjustment_new (0.0, -G_MAXINT32
, G_MAXINT32
, 0.01, 1.0, 0.0);
349 spinner
= gtk_spin_button_new (adj
, 1.0, 2);
350 g_object_set(spinner
, "xalign", 1.0, NULL
);
353 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), spinner
);
355 g_signal_connect(G_OBJECT(spinner
), "insert_text",
356 G_CALLBACK(hb_amount_insert_text_handler
),
363 GtkWidget
*make_euro(GtkWidget
*label
)
368 adj
= (GtkAdjustment
*) gtk_adjustment_new (0.0, -G_MAXINT32
, G_MAXINT32
, 0.01, 1.0, 0.0);
369 spinner
= gtk_spin_button_new (adj
, 1.0, 6);
370 //gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
371 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner
), TRUE
);
372 g_object_set(spinner
, "xalign", 1.0, NULL
);
375 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), spinner
);
383 GtkWidget
*make_numeric(GtkWidget
*label
, gdouble min
, gdouble max
)
388 adj
= (GtkAdjustment
*) gtk_adjustment_new (0.0, min
, max
, 1.0, 10.0, 0.0);
389 spinner
= gtk_spin_button_new (adj
, 0, 0);
390 //gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
391 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner
), TRUE
);
392 g_object_set(spinner
, "xalign", 1.0, NULL
);
395 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), spinner
);
403 GtkWidget
*make_scale(GtkWidget
*label
)
407 scale
= gtk_hscale_new_with_range(GTK_CHART_MINBARW
, GTK_CHART_MAXBARW
, 1.0);
408 gtk_scale_set_draw_value(GTK_SCALE(scale
), FALSE
);
409 gtk_range_set_value(GTK_RANGE(scale
), GTK_CHART_BARW
);
412 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), scale
);
420 GtkWidget
*make_long(GtkWidget
*label
)
424 spinner
= make_numeric(label
, 0.0, G_MAXINT
);
429 GtkWidget
*make_year(GtkWidget
*label
)
434 adj
= (GtkAdjustment
*) gtk_adjustment_new (0.0, 1900, 2200, 1.0, 10.0, 0.0);
435 spinner
= gtk_spin_button_new (adj
, 0, 0);
436 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner
), TRUE
);
437 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner
), TRUE
);
438 g_object_set(spinner
, "xalign", 1.0, NULL
);
441 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), spinner
);
448 is_separator (GtkTreeModel
*model
,
456 gtk_tree_model_get (model
, iter
, 0, &txt
, -1);
458 retval
= *txt
== 0 ? TRUE
: FALSE
;
459 //path = gtk_tree_model_get_path (model, iter);
460 //result = gtk_tree_path_get_indices (path)[0] == 4;
461 //gtk_tree_path_free (path);
467 set_sensitive (GtkCellLayout
*cell_layout
,
468 GtkCellRenderer
*cell
,
469 GtkTreeModel
*tree_model
,
477 path
= gtk_tree_model_get_path (tree_model
, iter
);
478 indices
= gtk_tree_path_get_indices (path
);
479 sensitive
= indices
[0] != FLT_RANGE_OTHER
;
480 gtk_tree_path_free (path
);
482 g_object_set (cell
, "sensitive", sensitive
, NULL
);
486 GtkWidget
*make_cycle(GtkWidget
*label
, gchar
**items
)
491 combobox
= gtk_combo_box_text_new ();
493 for (i
= 0; items
[i
] != NULL
; i
++)
496 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combobox
), _(items
[i
]));
498 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combobox
), "");
500 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox
), 0);
501 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combobox
), is_separator
, NULL
, NULL
);
504 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), combobox
);
510 GtkWidget
*make_daterange(GtkWidget
*label
, gboolean custom
)
513 GList
*renderers
, *list
;
514 GtkCellRenderer
*renderer
;
515 gchar
**items
= CYA_FLT_RANGE
;
518 combobox
= gtk_combo_box_text_new ();
520 for (i
= 0; items
[i
] != NULL
; i
++)
523 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combobox
), _(items
[i
]));
525 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combobox
), "");
527 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox
), 0);
530 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), combobox
);
533 renderers
= gtk_cell_layout_get_cells (GTK_CELL_LAYOUT(combobox
));
534 if(g_list_length(renderers
) == 1 && custom
== FALSE
)
536 list
= g_list_first(renderers
);
537 renderer
= list
->data
;
540 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combobox
),
545 g_list_free(renderers
);
547 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combobox
), is_separator
, NULL
, NULL
);
556 GtkWidget
*make_radio(GtkWidget
*label
, gchar
**items
, GtkOrientation orientation
)
558 GtkWidget
*box
, *button
;
562 if(orientation
== GTK_ORIENTATION_HORIZONTAL
)
563 box
= gtk_hbox_new(FALSE
, 0);
565 box
= gtk_vbox_new (FALSE
, 0);
567 button
= gtk_radio_button_new_with_label (NULL
, _(items
[0]));
568 gtk_box_pack_start (GTK_BOX (box
), button
, FALSE
, FALSE
, 0);
569 for (i
= 1; items
[i
] != NULL
; i
++)
571 button
= gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button
), _(items
[i
]));
572 gtk_box_pack_start (GTK_BOX (box
), button
, FALSE
, FALSE
, 0);
578 gint
radio_get_active (GtkContainer
*container
)
584 list
= gtk_container_get_children (container
);
585 for(i
=0;list
!= NULL
;i
++)
588 if(GTK_IS_TOGGLE_BUTTON(radio
))
590 if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio
)) == TRUE
)
596 list
= g_list_next(list
);
602 void radio_set_active (GtkContainer
*container
, gint active
)
607 if(!GTK_IS_CONTAINER(container
))
610 list
= gtk_container_get_children (container
);
611 radio
= g_list_nth_data (list
, active
);
612 if(radio
!= NULL
&& GTK_IS_TOGGLE_BUTTON(radio
))
614 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radio
), TRUE
);
622 guint
make_poparchive_populate(GtkComboBox
*combobox
, GList
*srclist
)
629 //insert all glist item into treeview
630 model
= gtk_combo_box_get_model(combobox
);
631 gtk_list_store_clear(GTK_LIST_STORE(model
));
633 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
634 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
, 0, "----", -1);
637 list
= g_list_first(srclist
);
640 Archive
*entry
= list
->data
;
642 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
643 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
, 0, entry
->wording
, -1);
645 //DB( g_print(" populate_treeview: %d %08x\n", i, list->data) );
647 i
++; list
= g_list_next(list
);
654 GtkWidget
*make_poparchive(GtkWidget
*label
)
658 GtkCellRenderer
*renderer
;
661 store
= gtk_list_store_new (1, G_TYPE_STRING
);
662 combobox
= gtk_combo_box_new_with_model (GTK_TREE_MODEL(store
));
663 g_object_unref(store
);
664 renderer
= gtk_cell_renderer_text_new ();
665 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox
), renderer
, TRUE
);
666 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox
), renderer
, "text", 0, NULL
);
669 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), combobox
);
674 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
677 * free_combobox_icons:
679 * generic function to free combobox icons
682 static void free_combobox_icons(GdkPixbuf
**storage
, guint max
)
688 if(storage
[i
] != NULL
)
689 g_object_unref(storage
[i
]);
694 * load_combobox_icons:
696 * generic function to load combobox icons
699 static void load_combobox_icons(gchar
**filenames
, GdkPixbuf
**storage
, guint max
)
701 //GError *error = NULL;
705 cellview
= gtk_cell_view_new ();
709 storage
[i
] = gtk_widget_render_icon (cellview
, filenames
[i
], GTK_ICON_SIZE_BUTTON
, NULL
);
712 g_print("cannot found a private stock %s\n", filenames
[i
]);
716 gtk_widget_destroy (cellview
);
723 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
732 GdkPixbuf
*paymode_icons
[NUM_PAYMODE_MAX
];
734 char *paymode_pixbuf_names
[NUM_PAYMODE_MAX
] =
750 char *paymode_label_names
[NUM_PAYMODE_MAX
] =
757 N_("Internal transfer"),
759 N_("Standing order"),
760 N_("Electronic payment"),
768 id ofx english french
769 ---------------------------------------------------------------------
770 0 -------- (none) (aucun)
771 1 -------- credit card carte de crédit
772 2 OFX_CHECK Check cheque
773 3 OFX_CASH Cash withdrawal retrait espece
774 4 OFX_XFER Transfer virement
775 5 -------- internal transfer virement compte
776 6 -------- (debit card) (carte de paiement
777 7 OFX_REPEATPMT Repeating payment/standing order Paiement recurrent/Virement auto.
779 8 OFX_PAYMENT Electronic payment télépaiement
780 9 OFX_DEP Deposit dépôt
781 10 OFX_FEE FI fee frais bancaires
784 OFX_DIRECTDEBIT Merchant initiated debit prelevement
785 OFX_OTHER Somer other type of transaction autre
789 OFX_CREDIT Generic credit
790 OFX_DEBIT Generic debit
791 OFX_INT Interest earned or paid (Note: Depends on signage of amount)
793 OFX_SRVCHG Service charge
795 OFX_ATM ATM debit or credit (Note: Depends on signage of amount)
796 OFX_POS Point of sale debit or credit (Note: Depends on signage of amount)
799 -OFX_PAYMENT Electronic payment
800 -OFX_CASH Cash withdrawal
801 OFX_DIRECTDEP Direct deposit
802 OFX_DIRECTDEBIT Merchant initiated debit
803 -OFX_REPEATPMT Repeating payment/standing order
804 OFX_OTHER Somer other type of transaction
808 void load_paymode_icons(void)
810 load_combobox_icons(paymode_pixbuf_names
, paymode_icons
, NUM_PAYMODE_MAX
);
814 void free_paymode_icons(void)
816 free_combobox_icons(paymode_icons
, NUM_PAYMODE_MAX
);
821 ** Make a paymode combobox widget
823 GtkWidget
*make_paymode(GtkWidget
*label
)
828 GtkCellRenderer
*renderer
;
832 store
= gtk_list_store_new (
839 combobox
= gtk_combo_box_new_with_model(GTK_TREE_MODEL(store
));
842 renderer
= gtk_cell_renderer_pixbuf_new();
843 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox
), renderer
, FALSE
);
844 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(combobox
), renderer
, "pixbuf", LST_PAYMODE_PIXBUF
);
846 renderer
= gtk_cell_renderer_text_new();
847 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox
), renderer
, FALSE
);
848 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(combobox
), renderer
, "text", LST_PAYMODE_LABEL
);
850 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox
), 0);
852 //populate our combobox model
853 for(i
=0;i
<NUM_PAYMODE_MAX
;i
++)
855 gtk_list_store_append(store
, &iter
);
856 gtk_list_store_set(store
, &iter
,
857 LST_PAYMODE_PIXBUF
, paymode_icons
[i
],
858 LST_PAYMODE_LABEL
, _(paymode_label_names
[i
]),
862 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox
), 0);
865 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), combobox
);
870 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
872 #define NUM_NAINEX_MAX 3
881 GdkPixbuf
*nainex_icons
[NUM_NAINEX_MAX
];
883 char *nainex_pixbuf_names
[NUM_NAINEX_MAX
] =
890 char *nainex_label_names
[NUM_NAINEX_MAX
] =
897 void load_nainex_icons(void)
899 load_combobox_icons(nainex_pixbuf_names
, nainex_icons
, NUM_NAINEX_MAX
);
903 void free_nainex_icons(void)
905 free_combobox_icons(nainex_icons
, NUM_NAINEX_MAX
);
910 ** Make a nainex combobox widget
912 GtkWidget
*make_nainex(GtkWidget
*label
)
917 GtkCellRenderer
*renderer
;
921 store
= gtk_list_store_new (
928 combobox
= gtk_combo_box_new_with_model(GTK_TREE_MODEL(store
));
931 renderer
= gtk_cell_renderer_pixbuf_new();
932 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox
), renderer
, FALSE
);
933 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(combobox
), renderer
, "pixbuf", LST_NAINEX_PIXBUF
);
935 renderer
= gtk_cell_renderer_text_new();
936 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox
), renderer
, FALSE
);
937 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(combobox
), renderer
, "text", LST_NAINEX_LABEL
);
939 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox
), 0);
941 //populate our combobox model
942 for(i
=0;i
<NUM_NAINEX_MAX
;i
++)
944 gtk_list_store_append(store
, &iter
);
945 gtk_list_store_set(store
, &iter
,
946 LST_NAINEX_PIXBUF
, nainex_icons
[i
],
947 LST_NAINEX_LABEL
, _(nainex_label_names
[i
]),
950 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox
), 0);
953 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), combobox
);