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 "ui-category.h"
24 #include "ui-budget.h"
27 /****************************************************************************/
29 /****************************************************************************/
38 /* our global datas */
39 extern struct HomeBank
*GLOBALS
;
60 static gchar
*ui_bud_manage_getcsvbudgetstr(Category
*item
);
61 static void ui_bud_manage_update(GtkWidget
*treeview
, gpointer user_data
);
62 static void ui_bud_manage_set(GtkWidget
*widget
, gpointer user_data
);
63 static void ui_bud_manage_getlast(struct ui_bud_manage_data
*data
);
64 static void ui_bud_manage_selection_change(GtkWidget
*treeview
, gpointer user_data
);
65 static void ui_bud_manage_toggle(GtkRadioButton
*radiobutton
, gpointer user_data
);
66 static void ui_bud_manage_selection(GtkTreeSelection
*treeselection
, gpointer user_data
);
69 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
73 ** The function should return:
74 ** a negative integer if the first value comes before the second,
75 ** 0 if they are equal,
76 ** or a positive integer if the first value comes after the second.
78 static gint
ui_bud_listview_compare_funct (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
81 Category
*entry1
, *entry2
;
83 gtk_tree_model_get(model
, a
, LST_DEFCAT_DATAS
, &entry1
, -1);
84 gtk_tree_model_get(model
, b
, LST_DEFCAT_DATAS
, &entry2
, -1);
86 retval
= (entry1
->flags
& GF_INCOME
) - (entry2
->flags
& GF_INCOME
);
89 retval
= hb_string_utf8_compare(entry1
->name
, entry2
->name
);
96 ** draw some text from the stored data structure
98 static void ui_bud_listview_cell_data_function_text (GtkTreeViewColumn
*col
,
99 GtkCellRenderer
*renderer
,
109 gtk_tree_model_get(model
, iter
, LST_DEFCAT_DATAS
, &entry
, -1);
112 name
= g_strdup(_("(no category)"));
116 type
= (entry
->flags
& GF_INCOME
) ? '+' : '-';
119 string
= g_markup_printf_escaped("%s ::(f=%d, %c)", name
, entry
->flags
, type
);
122 string
= g_strdup(name
);
125 if(entry
->flags
& GF_BUDGET
)
127 if( entry
->parent
== 0 )
128 string
= g_markup_printf_escaped("<b>%s</b> [%c]", name
, type
);
130 string
= g_markup_printf_escaped(" %c <b><i>%s</i></b>", type
, name
);
134 if( entry
->parent
== 0 )
135 string
= g_markup_printf_escaped("%s [%c]", name
, type
);
137 string
= g_markup_printf_escaped(" %c <i>%s</i>", type
, name
);
142 g_object_set(renderer
, "markup", string
, NULL
);
150 static GtkWidget
*ui_bud_listview_new(void)
154 GtkCellRenderer
*renderer
;
155 GtkTreeViewColumn
*column
;
158 store
= gtk_tree_store_new (
167 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_DEFCAT_DATAS
, ui_bud_listview_compare_funct
, NULL
, NULL
);
168 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store
), LST_DEFCAT_DATAS
, GTK_SORT_ASCENDING
);
172 view
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
173 g_object_unref(store
);
176 column
= gtk_tree_view_column_new();
177 renderer
= gtk_cell_renderer_text_new ();
178 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
179 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_bud_listview_cell_data_function_text
, GINT_TO_POINTER(1), NULL
);
180 //gtk_tree_view_column_set_sort_column_id (column, LST_DEFACC_NAME);
181 gtk_tree_view_append_column (GTK_TREE_VIEW(view
), column
);
183 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(view
), FALSE
);
184 //gtk_tree_view_set_reorderable (GTK_TREE_VIEW(view), TRUE);
192 ** index 0 is all month, then 1 -> 12 are months
194 static gchar
*ui_bud_manage_getcsvbudgetstr(Category
*item
)
196 gchar
*retval
= NULL
;
197 char buf
[G_ASCII_DTOSTR_BUF_SIZE
];
199 //DB( g_print(" get budgetstr for '%s'\n", item->name) );
201 if( !(item
->flags
& GF_CUSTOM
) )
203 if( item
->budget
[0] )
205 g_ascii_dtostr (buf
, sizeof (buf
), item
->budget
[0]);
206 retval
= g_strdup(buf
);
208 //DB( g_print(" => %d: %s\n", 0, retval) );
217 //if( item->budget[i] )
221 g_ascii_dtostr (buf
, sizeof (buf
), item
->budget
[i
]);
225 retval
= g_strconcat(retval
, ";", buf
, NULL
);
229 retval
= g_strdup(buf
);
231 //DB( g_print(" => %d: %s\n", i, retval) );
241 static gint
ui_bud_manage_category_exists (GtkTreeModel
*model
, gchar
*level
, gchar
*type
, gchar
*name
, GtkTreeIter
*return_iter
)
243 GtkTreeIter iter
, child
;
251 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
255 gtk_tree_model_get (model
, &iter
, LST_DEFCAT_DATAS
, &entry
, -1);
259 if(entry
->name
&& g_ascii_strcasecmp(name
, entry
->name
) == 0)
269 gint n_child
= gtk_tree_model_iter_n_children (GTK_TREE_MODEL(model
), &iter
);
270 gtk_tree_model_iter_children (GTK_TREE_MODEL(model
), &child
, &iter
);
274 gtk_tree_model_get(GTK_TREE_MODEL(model
), &child
,
275 LST_DEFCAT_DATAS
, &entry
,
278 if(entry
->name
&& g_ascii_strcasecmp(name
, entry
->name
) == 0)
280 *return_iter
= child
;
285 gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &child
);
290 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
298 static void ui_bud_manage_load_csv( GtkWidget
*widget
, gpointer user_data
)
300 struct ui_bud_manage_data
*data
= user_data
;
301 gchar
*filename
= NULL
;
303 const gchar
*encoding
;
306 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
309 DB( g_print("(ui_bud_manage) load csv - data %p\n", data
) );
311 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_OPEN
, &filename
, NULL
) == TRUE
)
313 DB( g_print(" + filename is %s\n", filename
) );
315 encoding
= homebank_file_getencoding(filename
);
317 io
= g_io_channel_new_file(filename
, "r", NULL
);
322 gboolean error
= FALSE
;
326 DB( g_print(" -> encoding should be %s\n", encoding
) );
327 if( encoding
!= NULL
)
329 g_io_channel_set_encoding(io
, encoding
, NULL
);
332 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_cat
));
337 io_stat
= g_io_channel_read_line(io
, &tmpstr
, NULL
, NULL
, NULL
);
338 if( io_stat
== G_IO_STATUS_EOF
)
340 if( io_stat
== G_IO_STATUS_NORMAL
)
346 hb_string_strip_crlf(tmpstr
);
348 str_array
= g_strsplit (tmpstr
, ";", 15);
351 if( (g_strv_length (str_array
) < 4 || *str_array
[1] != '*') && (g_strv_length (str_array
) < 15))
357 DB( g_print(" csv read '%s : %s : %s ...'\n", str_array
[0], str_array
[1], str_array
[2]) );
359 gint pos
= ui_bud_manage_category_exists(model
, str_array
[0], str_array
[1], str_array
[2], &iter
);
361 DB( g_print(" pos=%d\n", pos
) );
369 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
,
370 LST_DEFCAT_DATAS
, &tmpitem
,
373 DB( g_print(" found cat, updating '%s'\n", tmpitem
->name
) );
377 tmpitem
->flags
&= ~(GF_CUSTOM
); //remove flag
378 if( *str_array
[1] == '*' )
380 tmpitem
->budget
[0] = g_ascii_strtod(str_array
[3], NULL
);
382 DB( g_print(" monthly '%.2f'\n", tmpitem
->budget
[0]) );
386 tmpitem
->flags
|= (GF_CUSTOM
);
390 tmpitem
->budget
[i
] = g_ascii_strtod(str_array
[2+i
], NULL
);
391 DB( g_print(" month %d '%.2f'\n", i
, tmpitem
->budget
[i
]) );
395 // if any value,set the flag to visual indicator
397 tmpitem
->flags
&= ~(GF_BUDGET
); //remove flag
400 if(tmpitem
->budget
[i
])
408 tmpitem
->flags
|= GF_BUDGET
;
411 g_strfreev (str_array
);
418 //update the treeview
419 gtk_tree_selection_unselect_all (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_cat
)));
422 g_io_channel_unref (io
);
426 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_ERROR
,
427 _("File format error"),
428 _("The csv file must contains the exact numbers of column,\nseparated by a semi-colon, read the help for more details.")
442 static void ui_bud_manage_save_csv( GtkWidget
*widget
, gpointer user_data
)
444 struct ui_bud_manage_data
*data
= user_data
;
445 gchar
*filename
= NULL
;
447 GtkTreeIter iter
, child
;
451 DB( g_print("(ui_bud_manage) save csv\n") );
453 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
455 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, NULL
) == TRUE
)
458 DB( g_print(" + filename is %s\n", filename
) );
460 io
= g_io_channel_new_file(filename
, "w", NULL
);
464 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_cat
));
466 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
470 gchar
*outstr
, *outvalstr
;
474 gtk_tree_model_get (GTK_TREE_MODEL(model
), &iter
, LST_DEFCAT_DATAS
, &category
, -1);
476 if( category
->name
!= NULL
)
480 if( category
->flags
& GF_BUDGET
)
482 type
= (category
->flags
& GF_CUSTOM
) ? ' ' : '*';
484 outvalstr
= ui_bud_manage_getcsvbudgetstr(category
);
485 outstr
= g_strdup_printf("1;%c;%s;%s\n", type
, category
->name
, outvalstr
);
486 DB( g_print("%s", outstr
) );
487 g_io_channel_write_chars(io
, outstr
, -1, NULL
, NULL
);
493 //level 2: subcategory
494 gint n_child
= gtk_tree_model_iter_n_children (GTK_TREE_MODEL(model
), &iter
);
495 gtk_tree_model_iter_children (GTK_TREE_MODEL(model
), &child
, &iter
);
498 gtk_tree_model_get(GTK_TREE_MODEL(model
), &child
, LST_DEFCAT_DATAS
, &category
, -1);
500 type
= (category
->flags
& GF_CUSTOM
) ? ' ' : '*';
502 outvalstr
= ui_bud_manage_getcsvbudgetstr(category
);
505 outstr
= g_strdup_printf("2;%c;%s;%s\n", type
, category
->name
, outvalstr
);
506 DB( g_print("%s", outstr
) );
507 g_io_channel_write_chars(io
, outstr
, -1, NULL
, NULL
);
513 gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &child
);
517 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
520 g_io_channel_unref (io
);
537 static void ui_bud_manage_update(GtkWidget
*treeview
, gpointer user_data
)
539 struct ui_bud_manage_data
*data
;
540 gboolean name
, custom
, sensitive
;
543 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview
), GTK_TYPE_WINDOW
)), "inst_data");
545 DB( g_print("\n(ui_bud_manage) update %x\n", (gint
)data
) );
549 if(data
->cat
!= NULL
)
551 name
= data
->cat
->name
== NULL
? FALSE
: TRUE
;
555 gtk_widget_set_sensitive(data
->CM_type
[0], sensitive
);
556 gtk_widget_set_sensitive(data
->CM_type
[1], sensitive
);
558 gtk_widget_set_sensitive(data
->BT_clear
, sensitive
);
561 gint toto
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_type
[0]));
562 DB( g_print(" monthly = %d\n", toto
) );
565 custom
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_type
[1]));
566 DB( g_print(" custom = %d\n\n", custom
) );
568 sensitive
= name
== FALSE
? FALSE
: custom
== TRUE
? FALSE
: TRUE
;
569 gtk_widget_set_sensitive(data
->spinner
[0], sensitive
);
571 sensitive
= name
== FALSE
? FALSE
: custom
;
574 gtk_widget_set_sensitive(data
->spinner
[i
+1], sensitive
);
582 static void ui_bud_manage_clear(GtkWidget
*widget
, gpointer user_data
)
584 struct ui_bud_manage_data
*data
;
587 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
589 DB( g_print("(ui_bud_manage) clear\n") );
591 //g_signal_handler_block(data->CM_type[0], data->handler_id[HID_CUSTOM]);
592 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_type
[0]), TRUE
);
593 //g_signal_handler_unblock(data->CM_type[0], data->handler_id[HID_CUSTOM]);
597 //g_signal_handler_block(data->spinner[i], data->spinner_hid[i]);
599 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data
->spinner
[i
]), 0);
600 data
->cat
->budget
[i
] = 0;
602 //g_signal_handler_unblock(data->spinner[i], data->spinner_hid[i]);
605 data
->cat
->flags
&= ~(GF_BUDGET
); //remove flag
607 gtk_widget_queue_draw (data
->LV_cat
);
615 static void ui_bud_manage_set(GtkWidget
*widget
, gpointer user_data
)
617 struct ui_bud_manage_data
*data
;
621 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
623 DB( g_print("(ui_bud_manage) set\n") );
625 active
= data
->cat
->flags
& GF_CUSTOM
? 1 : 0;
626 //data->custom = active;
628 //DB( g_print(" set custom to %d\n", data->custom) );
630 g_signal_handler_block(data
->CM_type
[0], data
->handler_id
[HID_CUSTOM
]);
631 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_type
[active
]), TRUE
);
632 g_signal_handler_unblock(data
->CM_type
[0], data
->handler_id
[HID_CUSTOM
]);
636 //g_signal_handler_block(data->spinner[i], data->spinner_hid[i]);
638 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data
->spinner
[i
]), data
->cat
->budget
[i
]);
639 //DB( g_print(" %.2f\n", data->cat->budget[i]) );
641 //g_signal_handler_unblock(data->spinner[i], data->spinner_hid[i]);
644 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_force
), (data
->cat
->flags
& GF_FORCED
) ? 1 : 0);
651 static void ui_bud_manage_getlast(struct ui_bud_manage_data
*data
)
653 gboolean budget
, change
;
659 item
= data
->lastcatitem
;
661 DB( g_print("****\n(ui_bud_manage) getlast for '%s'\n", item
->name
) );
665 gushort old_flags
= item
->flags
;
667 item
->flags
&= ~(GF_CUSTOM
);
668 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_type
[0])) == FALSE
)
669 item
->flags
|= GF_CUSTOM
;
671 DB( g_print(" custom flag=%d\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_type
[1]))) );
673 // if any value,set the flag to visual indicator
676 item
->flags
&= ~(GF_BUDGET
); //remove flag
679 gtk_spin_button_update(GTK_SPIN_BUTTON(data
->spinner
[i
]));
680 oldvalue
= item
->budget
[i
];
682 item
->budget
[i
] = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data
->spinner
[i
]));
684 if( oldvalue
!= item
->budget
[i
])
687 DB( g_print(" set value %d to %.2f\n", i
, item
->budget
[i
]) );
694 item
->flags
&= ~(GF_FORCED
); //remove flag
695 active
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_force
));
697 item
->flags
|= GF_FORCED
;
699 if(budget
== TRUE
|| active
== 1)
700 item
->flags
|= GF_BUDGET
;
703 if( (old_flags
!= item
->flags
) || change
)
706 gtk_widget_queue_draw (data
->LV_cat
);
718 static void ui_bud_manage_selection_change(GtkWidget
*treeview
, gpointer user_data
)
720 struct ui_bud_manage_data
*data
;
724 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview
), GTK_TYPE_WINDOW
)), "inst_data");
726 DB( g_print("(ui_bud_manage) changed\n") );
730 if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_cat
)), &model
, &iter
))
734 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
,
735 LST_DEFCAT_DATAS
, &item
,
738 DB( g_print(" selected %s\n", item
->name
) );
740 if(data
->lastcatitem
!= NULL
&& item
!= data
->lastcatitem
)
742 DB( g_print(" -> should do a get for last selected (%s)\n", data
->lastcatitem
->name
) );
743 ui_bud_manage_getlast(data
);
748 data
->lastcatitem
= item
;
750 ui_bud_manage_set(treeview
, NULL
);
754 data
->lastcatitem
= NULL
;
757 ui_bud_manage_update(treeview
, NULL
);
761 static void ui_bud_manage_toggle(GtkRadioButton
*radiobutton
, gpointer user_data
)
763 //struct ui_bud_manage_data *data;
765 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(radiobutton), GTK_TYPE_WINDOW)), "inst_data");
767 DB( g_print("(ui_bud_manage) toggle\n") );
769 //ui_bud_manage_get(GTK_WIDGET(radiobutton), GINT_TO_POINTER(FIELD_TYPE));
772 ui_bud_manage_update(GTK_WIDGET(radiobutton
), NULL
);
778 void ui_bud_manage_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
780 ui_bud_manage_selection_change(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), NULL
);
786 static gboolean
ui_bud_manage_cleanup(struct ui_bud_manage_data
*data
, gint result
)
788 gboolean doupdate
= FALSE
;
790 DB( g_print("(ui_bud_manage) cleanup\n") );
793 if(data
->lastcatitem
!= NULL
)
795 DB( g_print(" -> should do a get for last selected (%s)\n", data
->lastcatitem
->name
) );
796 ui_bud_manage_getlast(data
);
800 //do_application_specific_something ();
801 DB( g_print(" accept\n") );
803 GLOBALS
->changes_count
+= data
->change
;
805 DB( g_print(" free tmp_list\n") );
814 static void ui_bud_manage_setup(struct ui_bud_manage_data
*data
)
817 DB( g_print("(ui_bud_manage) setup\n") );
819 data
->tmp_list
= NULL
;
822 data
->lastcatitem
= NULL
;
824 ui_cat_listview_populate(data
->LV_cat
);
825 gtk_tree_view_expand_all (GTK_TREE_VIEW(data
->LV_cat
));
830 // the window creation
831 GtkWidget
*ui_bud_manage_dialog (void)
833 struct ui_bud_manage_data data
;
834 GtkWidget
*window
, *content
, *bbox
, *mainbox
, *treeview
, *scrollwin
, *vbox
, *radio
, *table
, *label
, *widget
;
836 GtkWidget
*alignment
, *hpaned
;
839 memset(&data
, 0, sizeof(struct ui_bud_manage_data
));
841 window
= gtk_dialog_new_with_buttons (_("Manage Budget"),
842 GTK_WINDOW(GLOBALS
->mainwindow
),
848 data
.window
= window
;
850 //homebank_window_set_icon_from_file(GTK_WINDOW (window), "budget.svg");
851 gtk_window_set_icon_name(GTK_WINDOW (window
), HB_STOCK_BUDGET
);
853 //store our window private data
854 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)&data
);
855 DB( g_print("(ui_bud_manage) window=%p, inst_data=%p\n", window
, &data
) );
859 content
= gtk_dialog_get_content_area(GTK_DIALOG (window
));
860 mainbox
= gtk_hbox_new (FALSE
, HB_BOX_SPACING
);
861 gtk_box_pack_start (GTK_BOX (content
), mainbox
, TRUE
, TRUE
, 0);
862 gtk_container_set_border_width (GTK_CONTAINER(mainbox
), HB_MAINBOX_SPACING
);
864 hpaned
= gtk_hpaned_new();
865 gtk_box_pack_start (GTK_BOX (mainbox
), hpaned
, TRUE
, TRUE
, 0);
868 vbox
= gtk_vbox_new (FALSE
, HB_BOX_SPACING
);
869 //gtk_box_pack_start (GTK_BOX (mainbox), vbox, FALSE, FALSE, 0);
870 gtk_paned_pack1 (GTK_PANED(hpaned
), vbox
, FALSE
, FALSE
);
873 scrollwin
= gtk_scrolled_window_new(NULL
,NULL
);
874 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin
), GTK_SHADOW_ETCHED_IN
);
875 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
), GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
876 gtk_box_pack_start (GTK_BOX (vbox
), scrollwin
, TRUE
, TRUE
, 0);
877 treeview
= (GtkWidget
*)ui_bud_listview_new();
878 data
.LV_cat
= treeview
;
879 gtk_widget_set_size_request(treeview
, HB_MINWIDTH_LIST
, -1);
880 gtk_container_add(GTK_CONTAINER(scrollwin
), treeview
);
883 vbox
= gtk_vbox_new (FALSE
, HB_BOX_SPACING
);
884 //gtk_box_pack_start (GTK_BOX (mainbox), vbox, TRUE, TRUE, 0);
885 gtk_paned_pack2 (GTK_PANED(hpaned
), vbox
, FALSE
, FALSE
);
888 table
= gtk_table_new (12, 5, FALSE
);
889 gtk_table_set_row_spacings (GTK_TABLE (table
), HB_TABROW_SPACING
);
890 gtk_table_set_col_spacings (GTK_TABLE (table
), HB_TABCOL_SPACING
);
892 // gtk_alignment_new(xalign, yalign, xscale, yscale)
893 alignment
= gtk_alignment_new(0.5, 0.0, 1.0, 0.0);
894 gtk_container_add(GTK_CONTAINER(alignment
), table
);
895 gtk_container_add (GTK_CONTAINER (vbox
), alignment
);
898 //gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
901 label
= make_label(_("Budget for each month"), 0.0, 0.5);
902 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
903 gtk_table_attach_defaults (GTK_TABLE (table
), label
, 0, 5, row
, row
+1);
906 label
= make_label("", 0.0, 0.5);
907 gtk_misc_set_padding (GTK_MISC (label
), HB_BOX_SPACING
, 0);
908 gtk_table_attach (GTK_TABLE (table
), label
, 0, 1, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
910 radio
= gtk_radio_button_new_with_label (NULL
, _("is the same"));
911 data
.CM_type
[0] = radio
;
912 gtk_table_attach_defaults (GTK_TABLE (table
), radio
, 1, 5, row
, row
+1);
915 //label = make_label(_("Each"), 1.0, 0.5);
916 //gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, row, row+1);
917 spinner
= make_amount(label
);
918 data
.spinner
[0] = spinner
;
919 gtk_table_attach_defaults (GTK_TABLE (table
), spinner
, 2, 3, row
, row
+1);
921 widget
= gtk_button_new_with_mnemonic (_("_Clear input"));
922 data
.BT_clear
= widget
;
923 gtk_table_attach_defaults (GTK_TABLE (table
), widget
, 4, 5, row
, row
+1);
928 button = gtk_button_new_with_label(_("Propagate"));
929 gtk_table_attach_defaults (GTK_TABLE (table), button, 1, 2, row, row+1);
933 radio
= gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (radio
), _("is different"));
934 data
.CM_type
[1] = radio
;
935 gtk_table_attach_defaults (GTK_TABLE (table
), radio
, 1, 5, row
, row
+1);
941 col
= ((i
<6) ? 1 : 3);
942 row
= 4 + ((i
<6) ? i
: i
-6);
946 label
= make_label(months
[i
], 0, 0.5);
947 gtk_table_attach_defaults (GTK_TABLE (table
), label
, col
, col
+1, row
, row
+1);
949 spinner
= make_amount(label
);
950 data
.spinner
[i
+1] = spinner
;
951 gtk_table_attach_defaults (GTK_TABLE (table
), spinner
, col
+1, col
+2, row
, row
+1);
953 DB( g_print("(ui_bud_manage) %s, col=%d, row=%d", months
[i
], col
, row
) );
957 label
= make_label(_("Options"), 0.0, 0.5);
958 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
959 gtk_table_attach_defaults (GTK_TABLE (table
), label
, 0, 5, row
, row
+1);
962 widget
= gtk_check_button_new_with_mnemonic (_("_Force monitoring this category"));
963 data
.CM_force
= widget
;
964 gtk_table_attach_defaults (GTK_TABLE (table
), widget
, 1, 5, row
, row
+1);
968 bbox
= gtk_hbox_new (FALSE
, HB_BOX_SPACING
);
969 gtk_box_pack_start (GTK_BOX (vbox
), bbox
, FALSE
, FALSE
, 0);
970 //gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
971 gtk_box_set_spacing (GTK_BOX (bbox
), HB_BOX_SPACING
);
973 data
.BT_import
= gtk_button_new_with_mnemonic(_("_Import"));
974 //data.BT_import = gtk_button_new_from_stock(GTK_STOCK_OPEN);
975 gtk_box_pack_start (GTK_BOX (bbox
), data
.BT_import
, FALSE
, FALSE
, 0);
977 data
.BT_export
= gtk_button_new_with_mnemonic(_("E_xport"));
978 //data.BT_export = gtk_button_new_from_stock(GTK_STOCK_SAVE);
979 gtk_box_pack_start (GTK_BOX (bbox
), data
.BT_export
, FALSE
, FALSE
, 0);
982 //connect all our signals
983 g_signal_connect (window
, "destroy",
984 G_CALLBACK (gtk_widget_destroyed
), &window
);
987 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
.LV_cat
)), "changed", G_CALLBACK (ui_bud_manage_selection
), NULL
);
988 //g_signal_connect (GTK_TREE_VIEW(data.LV_cat), "row-activated", G_CALLBACK (ui_bud_manage_onRowActivated), NULL);
990 data
.handler_id
[HID_CUSTOM
] = g_signal_connect (data
.CM_type
[0], "toggled", G_CALLBACK (ui_bud_manage_toggle
), NULL
);
993 g_signal_connect (G_OBJECT (data
.BT_clear
), "clicked", G_CALLBACK (ui_bud_manage_clear
), NULL
);
995 g_signal_connect (G_OBJECT (data
.BT_import
), "clicked", G_CALLBACK (ui_bud_manage_load_csv
), NULL
);
996 g_signal_connect (G_OBJECT (data
.BT_export
), "clicked", G_CALLBACK (ui_bud_manage_save_csv
), NULL
);
998 //data.custom = FALSE;
999 //gtk_widget_set_sensitive(data.table, FALSE);
1001 //setup, init and show window
1002 ui_bud_manage_setup(&data
);
1003 ui_bud_manage_update(window
, NULL
);
1007 gtk_widget_show_all (window
);
1010 gint result
= gtk_dialog_run (GTK_DIALOG (window
));
1013 case GTK_RESPONSE_ACCEPT
:
1014 //do_application_specific_something ();
1017 //do_nothing_since_dialog_was_cancelled ();
1021 // cleanup and destroy
1022 ui_bud_manage_cleanup(&data
, result
);
1023 gtk_widget_destroy (window
);