]> Dogcows Code - chaz/homebank/blob - src/list-account.c
add editorconfig file
[chaz/homebank] / src / list-account.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 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
21 #include "homebank.h"
22
23 #include "list-account.h"
24
25 /****************************************************************************/
26 /* Debug macros */
27 /****************************************************************************/
28 #define MYDEBUG 0
29
30 #if MYDEBUG
31 #define DB(x) (x);
32 #else
33 #define DB(x);
34 #endif
35
36 /* our global datas */
37 extern struct HomeBank *GLOBALS;
38 extern struct Preferences *PREFS;
39
40
41
42
43 gboolean list_account_level1_expanded(GtkTreeView *treeview, gchar *name)
44 {
45 gboolean retval, valid;
46 GtkTreeModel *model;
47 GtkTreeIter iter1;
48
49 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
50 retval = TRUE;
51 valid = gtk_tree_model_get_iter_first (model, &iter1);
52 while(valid)
53 {
54 GtkTreePath *tmppath = gtk_tree_model_get_path(model, &iter1);
55
56 if( gtk_tree_view_row_expanded(GTK_TREE_VIEW(treeview), tmppath) == FALSE )
57 {
58 gchar *tmpname;
59
60 gtk_tree_model_get(model, &iter1, LST_DSPACC_NAME, &tmpname, -1);
61 if( !strcmp(name, tmpname) )
62 retval = FALSE;
63
64 g_free(tmpname);
65 }
66 gtk_tree_path_free(tmppath);
67 valid = gtk_tree_model_iter_next (model, &iter1);
68 }
69 return retval;
70 }
71
72
73 /*
74 ** draw some icons according to the stored data structure
75 */
76 static void
77 status_cell_data_function (GtkTreeViewColumn *col,
78 GtkCellRenderer *renderer,
79 GtkTreeModel *model,
80 GtkTreeIter *iter,
81 gpointer user_data)
82 {
83 Account *acc;
84 gchar *iconname = NULL;
85 gint dt;
86
87 gtk_tree_model_get(model, iter,
88 LST_DSPACC_DATATYPE, &dt,
89 LST_DSPACC_DATAS, &acc,
90 -1);
91
92 if( dt == DSPACC_TYPE_NORMAL )
93 {
94
95 switch(GPOINTER_TO_INT(user_data))
96 {
97 case 1:
98 iconname = (acc->flags & AF_ADDED) ? ICONNAME_HB_OPE_NEW : NULL;
99 // override if closed account
100 if( acc->flags & AF_CLOSED )
101 iconname = ICONNAME_CHANGES_PREVENT;
102 break;
103 case 2:
104 iconname = (acc->flags & AF_CHANGED) ? ICONNAME_HB_OPE_EDIT : NULL;
105 break;
106 }
107 }
108
109 g_object_set(renderer, "icon-name", iconname, NULL);
110 }
111
112
113 /*
114 ** draw some text from the stored data structure
115 */
116 static void
117 text_cell_data_function (GtkTreeViewColumn *col,
118 GtkCellRenderer *renderer,
119 GtkTreeModel *model,
120 GtkTreeIter *iter,
121 gpointer user_data)
122 {
123 Account *acc;
124 gint dt;
125 gchar *groupname;
126
127 gtk_tree_model_get(model, iter,
128 LST_DSPACC_DATATYPE, &dt,
129 LST_DSPACC_DATAS, &acc,
130 LST_DSPACC_NAME, &groupname,
131 -1);
132
133 if( dt == DSPACC_TYPE_NORMAL )
134 {
135 switch(GPOINTER_TO_INT(user_data))
136 {
137 case 1:
138 g_object_set(renderer, "weight", PANGO_WEIGHT_NORMAL, "text", acc->name, NULL);
139 break;
140 case 2:
141 //g_object_set(renderer, "text", acc->number, NULL);
142 break;
143
144 }
145 }
146 else
147 g_object_set(renderer,
148 "weight", PANGO_WEIGHT_BOLD,
149 "text", groupname,
150 NULL);
151
152 //leak
153 g_free(groupname);
154 }
155
156
157 static void
158 float_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
159 {
160 gdouble value;
161 gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
162 Account *acc;
163 gint dt;
164 gint weight;
165 gchar *color;
166
167 gtk_tree_model_get(model, iter,
168 LST_DSPACC_DATATYPE, &dt,
169 LST_DSPACC_DATAS, &acc,
170 GPOINTER_TO_INT(user_data), &value, //LST_DSPACC_(BANK/TODAY/FUTURE)
171 -1);
172
173 guint32 kcur = (acc != NULL) ? acc->kcur : GLOBALS->kcur;
174
175 if( dt == DSPACC_TYPE_HEADER )
176 {
177 gboolean expanded;
178 GtkTreePath* tp;
179
180 tp = gtk_tree_model_get_path(model, iter);
181 expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(gtk_tree_view_column_get_tree_view(col)), tp);
182
183 //leak
184 gtk_tree_path_free(tp);
185
186 if(!expanded)
187 {
188 hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, value, kcur, GLOBALS->minor);
189 color = get_normal_color_amount(value);
190 g_object_set(renderer,
191 "weight", PANGO_WEIGHT_NORMAL,
192 "foreground", color,
193 "text", buf,
194 NULL);
195 }
196 else
197 g_object_set(renderer, "text", NULL,
198 NULL);
199
200 }
201 else
202 {
203 hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, value, kcur, GLOBALS->minor);
204
205 color = NULL;
206 weight = PANGO_WEIGHT_NORMAL;
207
208 if( dt == DSPACC_TYPE_NORMAL )
209 {
210 color = get_minimum_color_amount(value, acc->minimum);
211 }
212 else
213 {
214 color = get_normal_color_amount(value);
215 weight = PANGO_WEIGHT_BOLD;
216 }
217
218 //g_print("value='%.2f' buf='%s' color='%s'\n", value, buf, color);
219
220 g_object_set(renderer,
221 "weight", weight,
222 "foreground", color,
223 "text", buf,
224 NULL);
225
226 }
227 }
228
229
230 static GtkTreeViewColumn *amount_list_account_column(gchar *name, gint id)
231 {
232 GtkTreeViewColumn *column;
233 GtkCellRenderer *renderer;
234
235 column = gtk_tree_view_column_new();
236 gtk_tree_view_column_set_title(column, name);
237
238 renderer = gtk_cell_renderer_text_new ();
239 g_object_set(renderer, "xalign", 1.0, NULL);
240 gtk_tree_view_column_pack_start(column, renderer, TRUE);
241 gtk_tree_view_column_set_cell_data_func(column, renderer, float_cell_data_function, GINT_TO_POINTER(id), NULL);
242 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
243 gtk_tree_view_column_set_alignment (column, 0.5);
244 gtk_tree_view_column_set_spacing( column, 16 );
245 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPACC_BANK);
246
247 return column;
248 }
249
250 static gint
251 list_account_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
252 {
253 gint retval = 0;
254 gint dt1, dt2;
255 Account *entry1, *entry2;
256 gchar *name1, *name2;
257 gint pos1, pos2;
258
259 gtk_tree_model_get(model, a,
260 LST_DSPACC_POS, &pos1,
261 LST_DSPACC_DATATYPE, &dt1,
262 LST_DSPACC_DATAS, &entry1,
263 LST_DSPACC_NAME, &name1,
264 -1);
265 gtk_tree_model_get(model, b,
266 LST_DSPACC_POS, &pos2,
267 LST_DSPACC_DATATYPE, &dt2,
268 LST_DSPACC_DATAS, &entry2,
269 LST_DSPACC_NAME, &name2,
270 -1);
271
272 if( dt1 == DSPACC_TYPE_NORMAL && dt2 == DSPACC_TYPE_NORMAL )
273 {
274 retval = entry1->pos - entry2->pos;
275 }
276 else
277 if( dt1 == DSPACC_TYPE_HEADER && dt2 == DSPACC_TYPE_HEADER )
278 {
279 retval = pos1 - pos2;
280 if( !retval )
281 retval = hb_string_utf8_compare(name1, name2);
282 }
283
284 g_free(name2);
285 g_free(name1);
286
287 return retval;
288 }
289
290
291 /*
292 *
293 */
294 static
295 gboolean list_account_selectionfunc(
296 GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data)
297 {
298 GtkTreeIter iter;
299
300 if( gtk_tree_path_get_depth( path ) < 2 )
301 return FALSE;
302
303 if(gtk_tree_model_get_iter(model, &iter, path))
304 {
305 gint dt;
306
307 gtk_tree_model_get(model, &iter,
308 LST_DSPACC_DATATYPE, &dt,
309 -1);
310
311 if( dt != DSPACC_TYPE_NORMAL )
312 return FALSE;
313 }
314
315 return TRUE;
316 }
317
318
319 static GtkTreeViewColumn *list_account_get_column(GtkTreeView *treeview, gint uid)
320 {
321 GtkTreeViewColumn *retval = NULL;
322 guint i;
323
324 for(i=0;i<gtk_tree_view_get_n_columns(treeview);i++)
325 {
326 GtkTreeViewColumn *column = gtk_tree_view_get_column(treeview, i);
327
328 if(column)
329 {
330 gint coluid = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(column), "uid"));
331 if( coluid == uid )
332 retval = column;
333 }
334 }
335 return retval;
336 }
337
338
339 static void list_account_destroy(GtkTreeView *treeview, gpointer user_data)
340 {
341 GtkTreeViewColumn *column;
342
343 DB( g_print ("\n[list_account] destroy\n") );
344
345 column = list_account_get_column(treeview, COL_DSPACC_ACCOUNTS);
346 if( column )
347 {
348 PREFS->pnl_acc_col_acc_width = gtk_tree_view_column_get_width(column);
349 }
350 }
351
352
353 GtkWidget *create_list_account(void)
354 {
355 GtkTreeStore *store;
356 GtkWidget *view;
357 GtkCellRenderer *renderer;
358 GtkTreeViewColumn *column;
359
360 DB( g_print ("\n[list_account] create\n") );
361
362 /* create list store */
363 store = gtk_tree_store_new(
364 NUM_LST_DSPACC,
365 G_TYPE_INT, /* fake: status */
366 G_TYPE_STRING, /* fake: name */
367 G_TYPE_DOUBLE,
368 G_TYPE_DOUBLE,
369 G_TYPE_DOUBLE,
370 G_TYPE_POINTER, /* datas*/
371 G_TYPE_INT /* datatype */
372 );
373
374 //treeview
375 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
376 g_object_unref(store);
377
378 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), PREFS->grid_lines);
379 //gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview),
380 // COLUMN_DESCRIPTION);
381
382 //gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW (view), TRUE);
383
384 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), GTK_SELECTION_SINGLE);
385
386 /* Status */
387 column = gtk_tree_view_column_new();
388 //gtk_tree_view_column_set_title(column, _("Status"));
389
390 renderer = gtk_cell_renderer_pixbuf_new ();
391 gtk_tree_view_column_pack_start(column, renderer, TRUE);
392 gtk_tree_view_column_set_cell_data_func(column, renderer, status_cell_data_function, GINT_TO_POINTER(1), NULL);
393
394 renderer = gtk_cell_renderer_pixbuf_new ();
395 gtk_tree_view_column_pack_start(column, renderer, TRUE);
396 gtk_tree_view_column_set_cell_data_func(column, renderer, status_cell_data_function, GINT_TO_POINTER(2), NULL);
397
398 gtk_tree_view_column_set_alignment (column, 0.5);
399 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
400
401 /* Account */
402 renderer = gtk_cell_renderer_text_new ();
403 g_object_set(renderer,
404 "ellipsize", PANGO_ELLIPSIZE_END,
405 "ellipsize-set", TRUE,
406 NULL);
407
408 column = gtk_tree_view_column_new();
409 g_object_set_data(G_OBJECT(column), "uid", GUINT_TO_POINTER(COL_DSPACC_ACCOUNTS));
410 gtk_tree_view_column_set_title(column, _("Accounts"));
411 gtk_tree_view_column_pack_start(column, renderer, TRUE);
412 gtk_tree_view_column_set_cell_data_func(column, renderer, text_cell_data_function, GINT_TO_POINTER(LST_DSPACC_NAME), NULL);
413 gtk_tree_view_column_set_alignment (column, 0.5);
414 gtk_tree_view_column_set_min_width(column, HB_MINWIDTH_LIST/2);
415 gtk_tree_view_column_set_resizable(column, TRUE);
416 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
417
418 gtk_tree_view_column_set_fixed_width(column, PREFS->pnl_acc_col_acc_width);
419 gtk_tree_view_set_expander_column(GTK_TREE_VIEW (view), column);
420
421 /* Bank */
422 column = amount_list_account_column(_("Bank"), LST_DSPACC_BANK);
423 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
424
425 /* Today */
426 column = amount_list_account_column(_("Today"), LST_DSPACC_TODAY);
427 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
428
429 /* Future */
430 column = amount_list_account_column(_("Future"), LST_DSPACC_FUTURE);
431 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
432
433 /* column 7: empty */
434 column = gtk_tree_view_column_new();
435 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
436
437
438 /* disable selection for level 1 of the tree */
439
440 gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), list_account_selectionfunc, NULL, NULL);
441
442 //sort etc
443 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), list_account_compare_func, NULL, NULL);
444 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
445
446 g_signal_connect (view, "destroy", G_CALLBACK (list_account_destroy), NULL);
447
448 return(view);
449 }
450
This page took 0.055224 seconds and 4 git commands to generate.