1 /*  HomeBank -- Free, easy, personal accounting for everyone.
2  *  Copyright (C) 1995-2021 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 #include "hub-account.h"
25 
26 /****************************************************************************/
27 /* Debug macros																*/
28 /****************************************************************************/
29 #define MYDEBUG 0
30 
31 #if MYDEBUG
32 #define DB(x) (x);
33 #else
34 #define DB(x);
35 #endif
36 
37 /* our global datas */
38 extern struct HomeBank *GLOBALS;
39 extern struct Preferences *PREFS;
40 
41 
42 /*
43 ** draw some icons according to the stored data structure
44 */
lst_accview_cell_data_func_status(GtkTreeViewColumn * col,GtkCellRenderer * renderer,GtkTreeModel * model,GtkTreeIter * iter,gpointer user_data)45 static void lst_accview_cell_data_func_status (GtkTreeViewColumn *col,
46                            GtkCellRenderer   *renderer,
47                            GtkTreeModel      *model,
48                            GtkTreeIter       *iter,
49                            gpointer           user_data)
50 {
51 Account *acc;
52 gchar *iconname = NULL;
53 gint dt;
54 
55 	gtk_tree_model_get(model, iter,
56 		LST_DSPACC_DATATYPE, &dt,
57 		LST_DSPACC_DATAS, &acc,
58 		-1);
59 
60 	if( dt == DSPACC_TYPE_NORMAL )
61 	{
62 
63 		switch(GPOINTER_TO_INT(user_data))
64 		{
65 			case 1:
66 				iconname = (acc->flags & AF_ADDED) ? ICONNAME_HB_OPE_NEW : NULL;
67 				// override if closed account
68 				if( acc->flags & AF_CLOSED )
69 					iconname = ICONNAME_CHANGES_PREVENT;
70 				break;
71 			case 2:
72 				iconname = (acc->flags & AF_CHANGED) ? ICONNAME_HB_OPE_EDIT : NULL;
73 				break;
74 		}
75 	}
76 
77 	g_object_set(renderer, "icon-name", iconname, NULL);
78 }
79 
80 
81 /*
82 ** draw some text from the stored data structure
83 */
lst_accview_cell_data_func_text(GtkTreeViewColumn * col,GtkCellRenderer * renderer,GtkTreeModel * model,GtkTreeIter * iter,gpointer user_data)84 static void lst_accview_cell_data_func_text (GtkTreeViewColumn *col,
85 				GtkCellRenderer *renderer,
86 				GtkTreeModel *model,
87 				GtkTreeIter *iter,
88 				gpointer user_data)
89 {
90 gpointer p;
91 gint dt;
92 gint weight = PANGO_WEIGHT_BOLD;
93 gchar *text = NULL;
94 //gchar *groupname;
95 
96 	gtk_tree_model_get(model, iter,
97 		LST_DSPACC_DATATYPE, &dt,
98 		LST_DSPACC_DATAS, &p,
99 		//LST_DSPACC_NAME, &groupname,
100 		-1);
101 
102 	if( p == NULL )
103 		goto end;
104 
105 	switch( dt )
106 	{
107 		case DSPACC_TYPE_NORMAL:
108 		{
109 		Account *acc = p;
110 			weight = PANGO_WEIGHT_NORMAL;
111 			text = acc->name;
112 		}
113 		break;
114 
115 		case DSPACC_TYPE_HEADER:
116 		{
117 		PnlAccGrp *g = p;
118 			text = g->name;
119 		}
120 		break;
121 
122 		case DSPACC_TYPE_SUBTOTAL:
123 			text = _("Total");
124 		break;
125 
126 		case DSPACC_TYPE_TOTAL:
127 			text = _("Grand total");
128 		break;
129 	}
130 
131 end:
132 	g_object_set(renderer, "weight", weight, "text", text, NULL);
133 
134 }
135 
136 
137 static void
lst_accview_cell_data_func_amount(GtkTreeViewColumn * col,GtkCellRenderer * renderer,GtkTreeModel * model,GtkTreeIter * iter,gpointer user_data)138 lst_accview_cell_data_func_amount (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
139 {
140 gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
141 gpointer p;
142 gint dt;
143 gint colid = GPOINTER_TO_INT(user_data); //LST_DSPACC_(BANK/TODAY/FUTURE)
144 gdouble amount = -1;
145 gint weight = PANGO_WEIGHT_NORMAL;
146 gchar *color = NULL;
147 gchar *text = NULL;
148 
149 	gtk_tree_model_get(model, iter,
150 		LST_DSPACC_DATATYPE, &dt,
151 		LST_DSPACC_DATAS, &p,
152 		-1);
153 
154 	if( p == NULL )
155 		goto end;
156 
157 	if( dt == DSPACC_TYPE_NORMAL )
158 	{
159 	Account *acc = p;
160 
161 		switch(colid)
162 		{
163 			case COL_DSPACC_CLEAR: amount = acc->bal_clear; break;
164 			case COL_DSPACC_RECON: amount = acc->bal_recon; break;
165 			case COL_DSPACC_TODAY: amount = acc->bal_today; break;
166 			case COL_DSPACC_FUTURE: amount = acc->bal_future; break;
167 		}
168 
169 		hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, amount, acc->kcur, GLOBALS->minor);
170 		color = get_minimum_color_amount(amount, acc->minimum);
171 		text = buf;
172 	}
173 	else
174 	{
175 	gboolean expanded = TRUE;
176 
177 		if( dt == DSPACC_TYPE_HEADER )
178 		{
179 		GtkTreePath* tp = gtk_tree_model_get_path(model, iter);
180 			expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(gtk_tree_view_column_get_tree_view(col)), tp);
181 			gtk_tree_path_free(tp);
182 		}
183 
184 		if( dt != DSPACC_TYPE_HEADER || (expanded == FALSE) )
185 		{
186 		PnlAccGrp *g = p;
187 
188 			switch(colid)
189 			{
190 				case COL_DSPACC_CLEAR: amount = g->bal_clear; break;
191 				case COL_DSPACC_RECON: amount = g->bal_recon; break;
192 				case COL_DSPACC_TODAY: amount = g->bal_today; break;
193 				case COL_DSPACC_FUTURE: amount = g->bal_future; break;
194 			}
195 
196 			//nota: header is always in base currency
197 			hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, amount, GLOBALS->kcur, GLOBALS->minor);
198 			if(expanded)
199 				weight = PANGO_WEIGHT_BOLD;
200 			color = get_normal_color_amount(amount);
201 			text = buf;
202 		}
203 	}
204 
205 end:
206 	g_object_set(renderer,
207 		"weight", weight,
208 		"foreground",  color,
209 		"text", text,
210 		NULL);
211 }
212 
213 
214 
215 
216 static gint
lst_accview_func_compare(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer userdata)217 lst_accview_func_compare (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
218 {
219 gint retval = 0;
220 gint dt1, dt2;
221 gpointer p1, p2;
222 gint pos1, pos2;
223 
224     gtk_tree_model_get(model, a,
225 		LST_DSPACC_POS, &pos1,
226     	LST_DSPACC_DATATYPE, &dt1,
227     	LST_DSPACC_DATAS, &p1,
228     	-1);
229     gtk_tree_model_get(model, b,
230 		LST_DSPACC_POS, &pos2,
231     	LST_DSPACC_DATATYPE, &dt2,
232     	LST_DSPACC_DATAS, &p2,
233     	-1);
234 
235 	if( p1 == NULL || p2 == NULL )
236 		return 0;
237 
238 	if( dt1 == DSPACC_TYPE_NORMAL && dt2 == DSPACC_TYPE_NORMAL )
239 	{
240 	Account *entry1 = p1;
241 	Account *entry2 = p2;
242 
243 		retval = entry1->pos - entry2->pos;
244 	}
245 	else
246 	if( dt1 == DSPACC_TYPE_HEADER && dt2 == DSPACC_TYPE_HEADER )
247 	{
248 	PnlAccGrp *elt1 = p1;
249 	PnlAccGrp *elt2 = p2;
250 
251 		retval = pos1 - pos2;
252 		if( !retval )
253 			retval = hb_string_utf8_compare(elt1->name, elt2->name);
254 	}
255 
256     return retval;
257 }
258 
259 
260 static gboolean
lst_accview_func_selection(GtkTreeSelection * selection,GtkTreeModel * model,GtkTreePath * path,gboolean path_currently_selected,gpointer data)261 lst_accview_func_selection(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data)
262 {
263 GtkTreeIter iter;
264 
265 	DB( g_print ("\n[lst_accview] selection\n") );
266 
267 
268 	if( gtk_tree_path_get_depth( path ) < 2 )
269 		return FALSE;
270 
271 	if(gtk_tree_model_get_iter(model, &iter, path))
272 	{
273 	gint dt;
274 
275 		gtk_tree_model_get(model, &iter,
276 			LST_DSPACC_DATATYPE, &dt,
277 			-1);
278 
279 		if( dt != DSPACC_TYPE_NORMAL )
280 			return FALSE;
281 	}
282 
283 	return TRUE;
284 }
285 
286 
287 static void
lst_accview_columns_prefs_get(GtkTreeView * treeview)288 lst_accview_columns_prefs_get(GtkTreeView *treeview)
289 {
290 GtkTreeViewColumn *column;
291 gint i, uid;
292 
293 	DB( g_print ("\n[lst_accview] columns prefs get\n") );
294 
295 	DB( g_print(" nbcol=%d, nbsortid=%d\n", NUM_LST_COL_DSPACC, gtk_tree_view_get_n_columns (treeview)) );
296 
297 	for(i=0 ; i < NUM_LST_COL_DSPACC ; i++ )
298 	{
299 		column = gtk_tree_view_get_column(treeview, i);
300 		if(column != NULL)
301 		{
302 			uid = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(column), "uid"));
303 			if( uid >= 0 )
304 			{
305 			gboolean visible;
306 
307 				visible = gtk_tree_view_column_get_visible (column);
308 				PREFS->lst_acc_columns[i] = (visible == TRUE) ? uid : -uid;
309 				DB( g_print(" col-%2d => %2d '%s' w=%d\n", i, uid, gtk_tree_view_column_get_title(column), PREFS->lst_ope_col_width[uid-1] ) );
310 
311 				/* save width for accounts */
312 				if( uid == COL_DSPACC_ACCOUNTS )
313 				{
314 					PREFS->pnl_acc_col_acc_width = gtk_tree_view_column_get_width(column);
315 				}
316 			}
317 			else	//should not occurs
318 				PREFS->lst_ope_columns[i] = 0;
319 		}
320 	}
321 }
322 
323 
324 
325 
326 static void
lst_accview_columns_prefs_set(GtkTreeView * treeview,gint * cols_id)327 lst_accview_columns_prefs_set(GtkTreeView *treeview, gint *cols_id)
328 {
329 GtkTreeViewColumn *column;
330 gboolean visible;
331 gint uid, i = 0;
332 gint tmpval;
333 
334 	DB( g_print ("\n[lst_accview] columns prefs set\n") );
335 
336 	for(i=0; i < NUM_LST_COL_DSPACC ; i++ )
337 	{
338 		column = gtk_tree_view_get_column(treeview, i);
339 		if( column != NULL )
340 		{
341 			uid = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(column), "uid"));
342 			tmpval = homebank_pref_list_column_get(cols_id, uid, NUM_LST_COL_DSPACC);
343 
344 			DB( g_print(" - pos:%2d uid:%d sortid:%2d (%s)\n", i, uid, tmpval, gtk_tree_view_column_get_title(column)) );
345 			visible = tmpval < 0 ? FALSE : TRUE;
346 			gtk_tree_view_column_set_visible (column, visible);
347 		}
348 	}
349 }
350 
351 
352 static GtkTreeViewColumn *
lst_accview_column_amount_new(gchar * name,gint id)353 lst_accview_column_amount_new(gchar *name, gint id)
354 {
355 GtkTreeViewColumn  *column;
356 GtkCellRenderer    *renderer;
357 
358 	column = gtk_tree_view_column_new();
359 	g_object_set_data(G_OBJECT(column), "uid", GUINT_TO_POINTER(id));
360 	gtk_tree_view_column_set_title(column, name);
361 
362 	renderer = gtk_cell_renderer_text_new ();
363 	g_object_set(renderer, "xalign", 1.0, NULL);
364 	gtk_tree_view_column_pack_start(column, renderer, TRUE);
365 	gtk_tree_view_column_set_cell_data_func(column, renderer, lst_accview_cell_data_func_amount, GINT_TO_POINTER(id), NULL);
366 	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
367 	gtk_tree_view_column_set_alignment (column, 0.5);
368 	gtk_tree_view_column_set_spacing( column, 16 );
369 	//gtk_tree_view_column_set_sort_column_id (column, LST_DSPACC_BANK);
370 
371 	return column;
372 }
373 
374 
375 static void
lst_accview_popmenu_cb_activate(GtkCheckMenuItem * checkmenuitem,gpointer user_data)376 lst_accview_popmenu_cb_activate (GtkCheckMenuItem *checkmenuitem, gpointer user_data)
377 {
378 GtkTreeViewColumn *column = user_data;
379 //GtkWidget *treeview;
380 
381 	DB( g_print ("\n[lst_accview] menuitem activated\n") );
382 
383 	if( !GTK_IS_TREE_VIEW_COLUMN(column) )
384 		return;
385 
386 	//TDOO: useless until we link dsp_accoutn balance to this list
387 	//treeview = gtk_tree_view_column_get_tree_view(GTK_TREE_VIEW_COLUMN(column));
388 	gtk_tree_view_column_set_visible(column, gtk_check_menu_item_get_active(checkmenuitem) );
389 	//lst_accview_columns_prefs_get(GTK_TREE_VIEW(treeview));
390 }
391 
392 
393 static gint
lst_accview_cb_button_pressed_event(GtkWidget * widget,GdkEventButton * event,GtkWidget * menu)394 lst_accview_cb_button_pressed_event (GtkWidget *widget, GdkEventButton *event, GtkWidget *menu)
395 {
396 
397 	DB( g_print ("\n[lst_accview] popmenu\n") );
398 
399 	if (event->type == GDK_BUTTON_PRESS && event->button == 3)
400 	{
401 
402 		// check we ARE in the header but in bin window
403 		if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget)))
404 		{
405 			#if( (GTK_MAJOR_VERSION == 3) && (GTK_MINOR_VERSION >= 22) )
406 				gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
407 			#else
408 				gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);
409 			#endif
410 				// On indique à l'appelant que l'on a géré cet événement.
411 
412 				return TRUE;
413 		}
414 
415 		// On indique à l'appelant que l'on n'a pas géré cet événement.
416 	}
417 		return FALSE;
418 }
419 
420 
421 static void
lst_accview_popmenu_destroy(GtkTreeView * treeview,gpointer user_data)422 lst_accview_popmenu_destroy(GtkTreeView *treeview, gpointer user_data)
423 {
424 	DB( g_print ("\n[lst_accview] menu destroy\n") );
425 
426 }
427 
428 
429 static GtkWidget *
lst_accview_popmenu_new(GtkTreeView * treeview)430 lst_accview_popmenu_new(GtkTreeView *treeview)
431 {
432 GtkTreeViewColumn *column;
433 GtkWidget *menu;
434 GtkWidget *menuitem;
435 gint i, uid;
436 //GtkAccelGroup *accel_group = NULL;
437 
438 	//accel_group = gtk_accel_group_new();
439 	//gtk_window_add_accel_group(GTK_WINDOW(data->window), accel_group);
440 
441 	DB( g_print ("\n[lst_accview] create popmenu\n") );
442 
443 	menu = gtk_menu_new();
444 	//data->ME_popmenu = menu;
445 
446 	for(i=0 ; i < NUM_LST_COL_DSPACC ; i++ )
447 	{
448 		column = gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), i);
449 		if( column != NULL )
450 		{
451 			//uid = gtk_tree_view_column_get_sort_column_id (column);
452 			uid = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(column), "uid"));
453 
454 			DB( g_print (" col %d\n", uid) );
455 
456 			if( (uid == -1)
457 				|| (uid == COL_DSPACC_STATUS)
458 				|| (uid == COL_DSPACC_ACCOUNTS)
459 			)
460 				continue;
461 
462 			menuitem = gtk_check_menu_item_new_with_label ( gtk_tree_view_column_get_title (column) );
463 			gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
464 			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), gtk_tree_view_column_get_visible (column) );
465 
466 			g_signal_connect (menuitem, "activate",
467 								G_CALLBACK (lst_accview_popmenu_cb_activate), column);
468 
469 		}
470 	}
471 
472 	g_signal_connect (menu, "destroy", G_CALLBACK (lst_accview_popmenu_destroy), NULL);
473 
474 	gtk_widget_show_all(menu);
475 
476 	return menu;
477 }
478 
479 
480 static gboolean
gtk_tree_view_set_tooltip_query_cb(GtkWidget * widget,gint x,gint y,gboolean keyboard_tip,GtkTooltip * tooltip,gpointer data)481 gtk_tree_view_set_tooltip_query_cb (GtkWidget  *widget,
482 				    gint        x,
483 				    gint        y,
484 				    gboolean    keyboard_tip,
485 				    GtkTooltip *tooltip,
486 				    gpointer    data)
487 {
488 GtkTreeIter iter;
489 GtkTreePath *path;
490 GtkTreeModel *model;
491 GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
492 GString *node;
493 gint dt;
494 Account *acc;
495 gboolean hastext = FALSE;
496 
497 	if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget),
498 					  &x, &y,
499 					  keyboard_tip,
500 					  &model, &path, &iter))
501 	return FALSE;
502 
503 	gtk_tree_model_get(model, &iter,
504 		LST_DSPACC_DATATYPE, &dt,
505 		LST_DSPACC_DATAS, &acc,
506 		-1);
507 
508 	// no tooltip is not an account
509 	if( (dt != DSPACC_TYPE_NORMAL) )
510 	{
511 		gtk_tree_path_free (path);
512 		return FALSE;
513 	}
514 
515 	node = g_string_sized_new(255);
516 	g_string_append(node, "<b>");
517 	g_string_append(node, acc->name);
518 	g_string_append(node, "</b>\n\n");
519 
520 	if( acc->rdate > 0 )
521 	{
522 	gchar buffer[256];
523 	GDate *date;
524 
525 		//format date
526 		date = g_date_new_julian (acc->rdate);
527 		g_date_strftime (buffer, 256-1, PREFS->date_format, date);
528 		g_date_free(date);
529 
530 		g_string_append(node, buffer);
531 		g_string_append(node, ", ");
532 		g_string_append(node, _("last reconciled"));
533 		g_string_append(node, "\n");
534 		hastext = TRUE;
535 	}
536 
537 	if( (acc->minimum < 0) && (acc->bal_today >= acc->minimum) )
538 	{
539 	gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
540 
541 		hb_strfmon(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, acc->bal_today - acc->minimum, acc->kcur, FALSE);
542 		g_string_append(node, formatd_buf);
543 		g_string_append(node, ", ");
544 		g_string_append(node, _("until"));
545 		g_string_append(node, " ");
546 		hb_strfmon(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, acc->minimum, acc->kcur, FALSE);
547 		g_string_append(node, formatd_buf);
548 		g_string_append(node, "\n");
549 		hastext = TRUE;
550 	}
551 
552 	if( (acc->maximum > 0) && (acc->maximum >= acc->bal_today) )
553 	{
554 	gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
555 
556 		hb_strfmon(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, acc->maximum - acc->bal_today, acc->kcur, FALSE);
557 		g_string_append(node, formatd_buf);
558 		g_string_append(node, ", ");
559 		g_string_append(node, _("before"));
560 		g_string_append(node, " ");
561 		hb_strfmon(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, acc->maximum, acc->kcur, FALSE);
562 		g_string_append(node, formatd_buf);
563 		g_string_append(node, "\n");
564 		hastext = TRUE;
565 	}
566 
567 	if( hastext == FALSE )
568 	{
569 		gtk_tree_path_free (path);
570 		g_string_free(node, TRUE);
571 		return FALSE;
572 	}
573 
574 	gtk_tooltip_set_markup (tooltip, node->str);
575 	gtk_tree_view_set_tooltip_row (tree_view, tooltip, path);
576 
577 	gtk_tree_path_free (path);
578 	g_string_free(node, TRUE);
579 
580 	return TRUE;
581 }
582 
583 
584 static void
lst_accview_destroy(GtkWidget * widget,gpointer user_data)585 lst_accview_destroy(GtkWidget *widget, gpointer user_data)
586 {
587 struct lst_accview_data *data;
588 
589 	data = g_object_get_data(G_OBJECT(widget), "inst_data");
590 
591 	DB( g_print ("\n[lst_accview] destroy\n") );
592 
593 	lst_accview_columns_prefs_get(GTK_TREE_VIEW(data->treeview));
594 
595 	gtk_widget_destroy (data->menu);
596 }
597 
598 
lst_accview_new(void)599 GtkWidget *lst_accview_new(void)
600 {
601 struct lst_accview_data *data;
602 GtkTreeStore *store;
603 GtkWidget *treeview;
604 GtkCellRenderer    *renderer;
605 GtkTreeViewColumn  *column;
606 
607 	DB( g_print ("\n[lst_accview] create\n") );
608 
609 	data = g_malloc0(sizeof(struct lst_accview_data));
610 	if(!data) return NULL;
611 
612 
613 	/* create list store */
614 	store = gtk_tree_store_new(
615 	  	NUM_LST_DSPACC,
616 		G_TYPE_INT,		/* datatype */
617 		G_TYPE_INT,		/* pos */
618 		G_TYPE_POINTER  /* datas*/
619 		);
620 
621 	//treeview
622 	treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
623 	data->treeview = treeview;
624 	g_object_unref(store);
625 
626 	//store our window private data
627 	g_object_set_data(G_OBJECT(treeview), "inst_data", (gpointer)data);
628 	DB( g_print(" - treeview=%p, inst_data=%p\n", treeview, data) );
629 
630 	g_signal_connect (treeview, "destroy", G_CALLBACK (lst_accview_destroy), NULL);
631 
632 
633 	gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview), PREFS->grid_lines);
634 	//gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview),
635 	//			       COLUMN_DESCRIPTION);
636 
637 	//gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW (view), TRUE);
638 
639 	gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_SINGLE);
640 
641     /* Status */
642 	column = gtk_tree_view_column_new();
643     //gtk_tree_view_column_set_title(column, _("Status"));
644 
645     renderer = gtk_cell_renderer_pixbuf_new ();
646     gtk_tree_view_column_pack_start(column, renderer, TRUE);
647     gtk_tree_view_column_set_cell_data_func(column, renderer, lst_accview_cell_data_func_status, GINT_TO_POINTER(1), NULL);
648 
649     renderer = gtk_cell_renderer_pixbuf_new ();
650     gtk_tree_view_column_pack_start(column, renderer, TRUE);
651     gtk_tree_view_column_set_cell_data_func(column, renderer, lst_accview_cell_data_func_status, GINT_TO_POINTER(2), NULL);
652 
653 	gtk_tree_view_column_set_alignment (column, 0.5);
654     gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
655 
656 	//add system icon to 1st column
657 	gtk_tree_view_column_set_clickable(column, TRUE);
658 	GtkWidget *img = gtk_image_new_from_icon_name (ICONNAME_EMBLEM_SYSTEM, GTK_ICON_SIZE_BUTTON);
659 	gtk_widget_show(img);
660 	gtk_tree_view_column_set_widget(column, img);
661 
662 	/* Account */
663 	renderer = gtk_cell_renderer_text_new ();
664 	g_object_set(renderer,
665 		"ellipsize", PANGO_ELLIPSIZE_END,
666 		"ellipsize-set", TRUE,
667 		//taken from nemo, not exactly a resize to content, but good compromise
668 	    "width-chars", 40,
669 		NULL);
670 
671 	column = gtk_tree_view_column_new();
672 	g_object_set_data(G_OBJECT(column), "uid", GUINT_TO_POINTER(COL_DSPACC_ACCOUNTS));
673 	gtk_tree_view_column_set_title(column, _("Accounts"));
674 	gtk_tree_view_column_pack_start(column, renderer, TRUE);
675 	gtk_tree_view_column_set_cell_data_func(column, renderer, lst_accview_cell_data_func_text, NULL, NULL);
676 	gtk_tree_view_column_set_alignment (column, 0.5);
677 	gtk_tree_view_column_set_min_width(column, HB_MINWIDTH_LIST/2);
678 	gtk_tree_view_column_set_resizable(column, TRUE);
679 	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
680 
681 	gtk_tree_view_column_set_fixed_width(column, PREFS->pnl_acc_col_acc_width);
682 	gtk_tree_view_set_expander_column(GTK_TREE_VIEW (treeview), column);
683 
684     /* Reconciled */
685 	column = lst_accview_column_amount_new(_("Reconciled"), COL_DSPACC_RECON);
686 	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
687 
688     /* Cleared */
689 	column = lst_accview_column_amount_new(_("Cleared"), COL_DSPACC_CLEAR);
690 	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
691 
692     /* Today */
693 	column = lst_accview_column_amount_new(_("Today"), COL_DSPACC_TODAY);
694 	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
695 
696     /* Future */
697 	column = lst_accview_column_amount_new(_("Future"), COL_DSPACC_FUTURE);
698 	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
699 
700     /* column 7: empty */
701 	column = gtk_tree_view_column_new();
702 	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
703 
704 
705 	/* disable selection for level 1 of the tree */
706 
707 	gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), lst_accview_func_selection, NULL, NULL);
708 
709 	//sort etc
710 	gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), lst_accview_func_compare, NULL, NULL);
711 	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
712 
713 	lst_accview_columns_prefs_set(GTK_TREE_VIEW(treeview), PREFS->lst_acc_columns);
714 
715 	GtkWidget *popmenu = lst_accview_popmenu_new(GTK_TREE_VIEW(treeview));
716 	data->menu = popmenu;
717 
718 	//add tooltip
719 	gtk_widget_set_has_tooltip (GTK_WIDGET (treeview), TRUE);
720 
721 	g_signal_connect (treeview, "button-press-event", G_CALLBACK (lst_accview_cb_button_pressed_event), popmenu);
722 
723 	g_signal_connect (treeview, "query-tooltip",
724 		            G_CALLBACK (gtk_tree_view_set_tooltip_query_cb), NULL);
725 
726 
727 	return(treeview);
728 }
729 
730