1 /* ************************************************************************** */
2 /*                                                                            */
3 /*     Copyright (C)    2000-2008 Cédric Auger (cedric@grisbi.org)            */
4 /*          2004-2008 Benjamin Drieu (bdrieu@april.org)                       */
5 /*                      2009-2011 Pierre Biava (grisbi@pierre.biava.name)     */
6 /*          https://www.grisbi.org/                                            */
7 /*                                                                            */
8 /*  This program is free software; you can redistribute it and/or modify      */
9 /*  it under the terms of the GNU General Public License as published by      */
10 /*  the Free Software Foundation; either version 2 of the License, or         */
11 /*  (at your option) any later version.                                       */
12 /*                                                                            */
13 /*  This program is distributed in the hope that it will be useful,           */
14 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of            */
15 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
16 /*  GNU General Public License for more details.                              */
17 /*                                                                            */
18 /*  You should have received a copy of the GNU General Public License         */
19 /*  along with this program; if not, write to the Free Software               */
20 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
21 /*                                                                            */
22 /* ************************************************************************** */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include "include.h"
29 #include <glib/gi18n.h>
30 
31 /*START_INCLUDE*/
32 #include "categories_onglet.h"
33 #include "dialog.h"
34 #include "grisbi_app.h"
35 #include "gsb_autofunc.h"
36 #include "gsb_automem.h"
37 #include "gsb_data_category.h"
38 #include "gsb_data_transaction.h"
39 #include "gsb_file.h"
40 #include "gsb_file_others.h"
41 #include "gsb_transactions_list.h"
42 #include "meta_categories.h"
43 #include "metatree.h"
44 #include "mouse.h"
45 #include "structures.h"
46 #include "traitement_variables.h"
47 #include "transaction_list.h"
48 #include "utils.h"
49 #include "utils_buttons.h"
50 #include "utils_files.h"
51 #include "utils_str.h"
52 #include "erreur.h"
53 /*END_INCLUDE*/
54 
55 /*START_STATIC*/
56 static void appui_sur_ajout_category ( GtkTreeModel *model,
57                         GtkButton *button );
58 static gboolean categ_drag_data_get ( GtkTreeDragSource *drag_source,
59                         GtkTreePath *path,
60                         GtkSelectionData *selection_data );
61 static gboolean category_list_button_press ( GtkWidget *tree_view,
62                         GdkEventButton *ev,
63                         gpointer null );
64 static void category_list_popup_context_menu ( void );
65 static GtkWidget *creation_barre_outils_categ ( void );
66 static gboolean edit_category ( GtkTreeView *tree_view );
67 static gboolean popup_category_view_mode_menu ( GtkWidget *button );
68 static void selectionne_sub_category ( GtkTreeModel *model );
69 /*END_STATIC*/
70 
71 
72 /* Category toolbar, tree model & tree view */
73 static GtkWidget *category_toolbar = NULL;
74 static GtkTreeStore *categ_tree_model = NULL;
75 static GtkWidget *arbre_categ = NULL;
76 
77 /* variable for the management of the cancelled edition */
78 static gboolean sortie_edit_category = FALSE;
79 
80 /* structure pour la sauvegarde de la position */
81 struct MetatreeHoldPosition *category_hold_position;
82 
83 
84 /*START_EXTERN*/
85 /*END_EXTERN*/
86 
87 
88 /**
89  * réinitialisation des variables globales
90  *
91  * \param
92  *
93  * \return
94  * */
categories_init_variables_list(void)95 void categories_init_variables_list ( void )
96 {
97 	GrisbiWinEtat *w_etat;
98 
99 	w_etat = (GrisbiWinEtat *) grisbi_win_get_w_etat ();
100     categ_tree_model = NULL;
101     category_toolbar = NULL;
102     arbre_categ = NULL;
103     w_etat->no_devise_totaux_categ = 1;
104     sortie_edit_category = FALSE;
105 }
106 
107 
108 /**
109  * Create and return contents of the "Category" notebook page.
110  *
111  * \return A newly allocated hbox.
112  */
categories_create_list(void)113 GtkWidget *categories_create_list ( void )
114 {
115 	GtkWidget *window;
116     GtkWidget *scroll_window, *vbox;
117     GtkWidget *frame;
118     GtkTreeViewColumn *column;
119     GtkCellRenderer *cell;
120     GtkTreeDragDestIface * dst_iface;
121     GtkTreeDragSourceIface * src_iface;
122     static GtkTargetEntry row_targets[] = {{(gchar*)"GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, 0 }};
123     MetatreeInterface *category_interface;
124 
125 	window = GTK_WIDGET (grisbi_app_get_active_window (NULL));
126 
127 	/* We create the main vbox */
128     vbox = gtk_box_new ( GTK_ORIENTATION_VERTICAL, MARGIN_BOX );
129 
130     /* frame pour la barre d'outils */
131     frame = gtk_frame_new ( NULL );
132     gtk_box_pack_start ( GTK_BOX ( vbox ), frame, FALSE, FALSE, 0 );
133 
134     category_interface = category_get_metatree_interface ( );
135 
136     /* We create the gtktreeview and model early so that they can be referenced. */
137     arbre_categ = gtk_tree_view_new();
138 
139     /* set the color of selected row */
140 	gtk_widget_set_name (arbre_categ, "colorized_tree_view");
141 
142     /* Create model */
143     categ_tree_model = gtk_tree_store_new ( META_TREE_NUM_COLUMNS, META_TREE_COLUMN_TYPES );
144     gtk_tree_sortable_set_sort_column_id ( GTK_TREE_SORTABLE(categ_tree_model),
145 					   META_TREE_TEXT_COLUMN, GTK_SORT_ASCENDING );
146     gtk_tree_sortable_set_sort_func ( GTK_TREE_SORTABLE(categ_tree_model),
147 				      META_TREE_TEXT_COLUMN, metatree_sort_column,
148 				      NULL, NULL );
149     g_object_set_data ( G_OBJECT (categ_tree_model), "metatree-interface", category_interface );
150 
151     /* on y ajoute la barre d'outils après la création du model */
152     category_toolbar = creation_barre_outils_categ ();
153     gtk_container_add ( GTK_CONTAINER ( frame ), category_toolbar );
154 
155     /* création de l'arbre principal */
156     scroll_window = gtk_scrolled_window_new ( NULL, NULL );
157     gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scroll_window ),
158 				     GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
159     gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW(scroll_window),
160 					  GTK_SHADOW_IN );
161     gtk_box_pack_start ( GTK_BOX ( vbox ), scroll_window, TRUE, TRUE, 0 );
162     gtk_widget_show ( scroll_window );
163 
164     /* Create container + TreeView */
165     gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(arbre_categ),
166 					   GDK_BUTTON1_MASK, row_targets, 1,
167 					   GDK_ACTION_MOVE | GDK_ACTION_COPY );
168     gtk_tree_view_enable_model_drag_dest ( GTK_TREE_VIEW(arbre_categ), row_targets,
169 					   1, GDK_ACTION_MOVE | GDK_ACTION_COPY );
170     gtk_tree_view_set_reorderable (GTK_TREE_VIEW(arbre_categ), TRUE);
171     gtk_tree_selection_set_mode ( gtk_tree_view_get_selection ( GTK_TREE_VIEW(arbre_categ)),
172 				  GTK_SELECTION_SINGLE );
173     gtk_tree_view_set_model (GTK_TREE_VIEW (arbre_categ),
174 			     GTK_TREE_MODEL (categ_tree_model));
175     g_object_unref (G_OBJECT(categ_tree_model));
176     g_object_set_data ( G_OBJECT(categ_tree_model), "tree-view", arbre_categ );
177 
178     /* Make category column */
179     cell = gtk_cell_renderer_text_new ();
180     column = gtk_tree_view_column_new_with_attributes (_("Category"), cell,
181 						       "text", META_TREE_TEXT_COLUMN,
182 						       "weight", META_TREE_FONT_COLUMN,
183                                "cell-background-rgba", META_TREE_BACKGROUND_COLOR,
184 						       NULL);
185     gtk_tree_view_append_column ( GTK_TREE_VIEW ( arbre_categ ),
186 				  GTK_TREE_VIEW_COLUMN ( column ) );
187 
188     /* Make account column */
189     cell = gtk_cell_renderer_text_new ();
190     column = gtk_tree_view_column_new_with_attributes (_("Account"), cell,
191 						       "text", META_TREE_ACCOUNT_COLUMN,
192 						       "weight", META_TREE_FONT_COLUMN,
193                                "cell-background-rgba", META_TREE_BACKGROUND_COLOR,
194 						       NULL);
195     gtk_tree_view_append_column ( GTK_TREE_VIEW ( arbre_categ ),
196 				  GTK_TREE_VIEW_COLUMN ( column ) );
197 
198     /* Make amount column */
199     cell = gtk_cell_renderer_text_new ();
200 	gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (cell), MARGIN_BOX, 0);
201     column = gtk_tree_view_column_new_with_attributes (_("Amount"), cell,
202 						       "text", META_TREE_BALANCE_COLUMN,
203 						       "weight", META_TREE_FONT_COLUMN,
204 						       "xalign", META_TREE_XALIGN_COLUMN,
205                                "cell-background-rgba", META_TREE_BACKGROUND_COLOR,
206 						       NULL);
207     gtk_tree_view_column_set_alignment ( column, 1.0 );
208     gtk_tree_view_append_column ( GTK_TREE_VIEW ( arbre_categ ),
209 				  GTK_TREE_VIEW_COLUMN ( column ) );
210 
211     gtk_container_add ( GTK_CONTAINER ( scroll_window ), arbre_categ );
212     gtk_widget_show ( arbre_categ );
213 
214     /* Connect to signals */
215     g_signal_connect ( G_OBJECT ( arbre_categ ),
216                         "row-collapsed",
217                         G_CALLBACK ( division_column_collapsed ),
218                         NULL );
219 
220     g_signal_connect ( G_OBJECT ( arbre_categ ),
221                         "row-expanded",
222                         G_CALLBACK ( division_column_expanded ),
223                         NULL );
224 
225     g_signal_connect( G_OBJECT ( arbre_categ ),
226                         "row-activated",
227                         G_CALLBACK ( division_activated ),
228                         NULL);
229 
230     g_signal_connect ( G_OBJECT ( arbre_categ ),
231                         "button-press-event",
232                         G_CALLBACK ( category_list_button_press ),
233                         NULL );
234 
235     dst_iface = GTK_TREE_DRAG_DEST_GET_IFACE (categ_tree_model);
236     if ( dst_iface )
237     {
238 	dst_iface -> drag_data_received = &division_drag_data_received;
239 	dst_iface -> row_drop_possible = &division_row_drop_possible;
240     }
241 
242     src_iface = GTK_TREE_DRAG_SOURCE_GET_IFACE (categ_tree_model);
243     if ( src_iface )
244     {
245 	gtk_selection_add_target (window,
246 				  GDK_SELECTION_PRIMARY,
247 				  GDK_SELECTION_TYPE_ATOM,
248 				  1);
249 	src_iface -> drag_data_get = &categ_drag_data_get;
250     }
251 
252     g_signal_connect ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( arbre_categ ) ),
253                         "changed",
254                         G_CALLBACK ( metatree_selection_changed ),
255                         categ_tree_model );
256 
257     /* création de la structure de sauvegarde de la position */
258     category_hold_position = g_malloc0 ( sizeof ( struct MetatreeHoldPosition ) );
259 
260     gtk_widget_show_all ( vbox );
261 
262     return ( vbox );
263 }
264 
265 
266 
267 /**
268  * Fill category tree with data.
269  */
categories_fill_list(void)270 void categories_fill_list ( void )
271 {
272     GSList *category_list;
273     GtkTreeIter iter_categ, iter_sous_categ;
274     MetatreeInterface *category_interface;
275 
276     devel_debug (NULL);
277 
278     /* Model might be empty because we are importing categories
279      * before file is opened.  So don't do anything. */
280     if ( ! categ_tree_model || ! GTK_IS_TREE_STORE(categ_tree_model) )
281 	return;
282 
283     /** First, remove previous tree */
284     gtk_tree_store_clear ( GTK_TREE_STORE (categ_tree_model) );
285 
286     /* Compute category balances. */
287     gsb_data_category_update_counters ();
288 
289     /** Then, populate tree with categories. */
290     category_list = gsb_data_category_get_categories_list ();
291 
292     /* add first the empty category */
293     category_list = g_slist_prepend ( category_list, gsb_data_category_get_empty_category ());
294 
295     category_interface = category_get_metatree_interface ( );
296 
297     while ( category_list )
298     {
299 	gint category_number;
300 
301 	category_number = gsb_data_category_get_no_category (category_list -> data);
302 
303 	gtk_tree_store_append (GTK_TREE_STORE (categ_tree_model), &iter_categ, NULL);
304 	fill_division_row ( GTK_TREE_MODEL(categ_tree_model), category_interface,
305 			    &iter_categ, category_number);
306 
307 	/** Each category has subcategories. */
308 	if ( category_number )
309 	{
310 	    GSList *sub_category_list;
311 
312 	    sub_category_list = gsb_data_category_get_sub_category_list ( category_number );
313 
314 	    while ( sub_category_list )
315 	    {
316 		gint sub_category_number;
317 
318 		sub_category_number = gsb_data_category_get_no_sub_category (sub_category_list -> data);
319 
320 		gtk_tree_store_append (GTK_TREE_STORE (categ_tree_model),
321 				       &iter_sous_categ, &iter_categ);
322 		fill_sub_division_row ( GTK_TREE_MODEL(categ_tree_model), category_interface,
323 					&iter_sous_categ,
324 					category_number,
325 					sub_category_number);
326 
327 		sub_category_list = sub_category_list -> next;
328 	    }
329 	}
330 
331 	/* add the no sub category only if category */
332 	if (category_number)
333 	{
334 	    gtk_tree_store_append (GTK_TREE_STORE (categ_tree_model),
335 				   &iter_sous_categ, &iter_categ);
336 	    fill_sub_division_row ( GTK_TREE_MODEL(categ_tree_model), category_interface,
337 				    &iter_sous_categ, category_number, 0 );
338 	}
339 
340 	category_list = category_list -> next;
341     }
342 
343     if ( category_hold_position -> path )
344     {
345         GtkTreeSelection *selection;
346 
347         if ( category_hold_position -> expand )
348         {
349             GtkTreePath *ancestor;
350 
351             ancestor = gtk_tree_path_copy ( category_hold_position -> path );
352             gtk_tree_path_up ( ancestor );
353             gtk_tree_view_expand_to_path ( GTK_TREE_VIEW ( arbre_categ ), ancestor );
354             gtk_tree_path_free (ancestor );
355         }
356         /* on colorise les lignes du tree_view */
357         utils_set_tree_store_background_color ( arbre_categ, META_TREE_BACKGROUND_COLOR );
358         selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( arbre_categ ) );
359         gtk_tree_selection_select_path ( selection, category_hold_position -> path );
360         gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW ( arbre_categ ),
361                         category_hold_position -> path,
362                         NULL, TRUE, 0.5, 0.5 );
363     }
364     else
365     {
366         gchar *title;
367 
368         /* on colorise les lignes du tree_view */
369         utils_set_tree_store_background_color ( arbre_categ, META_TREE_BACKGROUND_COLOR );
370 	    title = g_strdup(_("Categories"));
371         grisbi_win_headings_update_title ( title );
372         g_free ( title );
373         grisbi_win_headings_update_suffix ( "" );
374     }
375 }
376 
377 
378 /**
379  * Fill the drag & drop structure with the path of selected column.
380  * This is an interface function called from GTK, much like a callback.
381  *
382  * \param drag_source		Not used.
383  * \param path			Original path for the gtk selection.
384  * \param selection_data	A pointer to the drag & drop structure.
385  *
386  * \return FALSE, to allow future processing by the callback chain.
387  */
categ_drag_data_get(GtkTreeDragSource * drag_source,GtkTreePath * path,GtkSelectionData * selection_data)388 gboolean categ_drag_data_get ( GtkTreeDragSource *drag_source,
389                         GtkTreePath *path,
390                         GtkSelectionData *selection_data )
391 {
392     if ( path )
393     {
394 	gtk_tree_set_row_drag_data (selection_data,
395 				    GTK_TREE_MODEL(categ_tree_model), path);
396     }
397 
398     return FALSE;
399 }
400 
401 
402 
403 /**
404  *
405  *
406  */
categories_exporter_list(void)407 void categories_exporter_list ( void )
408 {
409     GtkWidget *dialog;
410     gint resultat;
411     gchar *nom_categ;
412     gchar *tmp_last_directory;
413 
414     dialog = gtk_file_chooser_dialog_new ( _("Export categories"),
415 					   GTK_WINDOW ( grisbi_app_get_active_window (NULL) ),
416 					   GTK_FILE_CHOOSER_ACTION_SAVE,
417 					   "gtk-cancel", GTK_RESPONSE_CANCEL,
418 					   "gtk-save", GTK_RESPONSE_OK,
419 					   NULL);
420 
421     gtk_file_chooser_set_current_name ( GTK_FILE_CHOOSER ( dialog ),  _("Categories.cgsb"));
422     gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER ( dialog ), gsb_file_get_last_path () );
423     gtk_file_chooser_set_do_overwrite_confirmation ( GTK_FILE_CHOOSER ( dialog ), TRUE);
424     gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
425 
426     resultat = gtk_dialog_run ( GTK_DIALOG ( dialog ));
427 
428     if ( resultat != GTK_RESPONSE_OK )
429     {
430         gtk_widget_destroy ( dialog );
431         return;
432     }
433 
434     nom_categ = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER ( dialog ));
435     tmp_last_directory = utils_files_selection_get_last_directory ( GTK_FILE_CHOOSER ( dialog ), TRUE );
436     gsb_file_update_last_path ( tmp_last_directory );
437     g_free ( tmp_last_directory );
438     gtk_widget_destroy ( GTK_WIDGET ( dialog ));
439 
440     gsb_file_others_save_category ( nom_categ );
441 }
442 
443 
444 
445 /**
446  *
447  *
448  */
categories_importer_list(void)449 void categories_importer_list ( void )
450 {
451     GtkWidget *dialog;
452     gint resultat;
453     gchar *category_name;
454     gint last_transaction_number;
455     GtkFileFilter * filter;
456     gchar *tmp_last_directory;
457 
458     dialog = gtk_file_chooser_dialog_new ( _("Import categories"),
459 					   GTK_WINDOW ( grisbi_app_get_active_window (NULL) ),
460 					   GTK_FILE_CHOOSER_ACTION_OPEN,
461 					   "gtk-cancel", GTK_RESPONSE_CANCEL,
462 					   "gtk-open", GTK_RESPONSE_OK,
463 					   NULL);
464 
465     gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER ( dialog ), gsb_file_get_last_path () );
466     gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
467 
468     filter = gtk_file_filter_new ();
469     gtk_file_filter_set_name ( filter, _("Grisbi category files (*.cgsb)") );
470     gtk_file_filter_add_pattern ( filter, "*.cgsb" );
471     gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog ), filter );
472     gtk_file_chooser_set_filter ( GTK_FILE_CHOOSER ( dialog ), filter );
473 
474     filter = gtk_file_filter_new ();
475     gtk_file_filter_set_name ( filter, _("All files") );
476     gtk_file_filter_add_pattern ( filter, "*" );
477     gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog ), filter );
478 
479     resultat = gtk_dialog_run ( GTK_DIALOG ( dialog ));
480 
481     if ( resultat != GTK_RESPONSE_OK  )
482     {
483 	gtk_widget_destroy ( dialog );
484 	return;
485     }
486 
487     category_name = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER ( dialog ));
488     tmp_last_directory = utils_files_selection_get_last_directory ( GTK_FILE_CHOOSER ( dialog ), TRUE );
489     gsb_file_update_last_path ( tmp_last_directory );
490     g_free ( tmp_last_directory );
491     gtk_widget_destroy ( GTK_WIDGET ( dialog ));
492 
493     last_transaction_number = gsb_data_transaction_get_last_number();
494 
495     /* on permet de remplacer/fusionner la liste */
496 
497     dialog = dialogue_special_no_run ( GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
498 				       ( last_transaction_number ?
499 				         _("File already contains categories.  If you decide to continue, existing categories will be merged with imported ones.") :
500 				         _("File does not contain categories.  "
501 				           "If you decide to continue, existing categories will be merged with imported ones.  "
502 				           "Once performed, there is no undo for this.\n"
503 				           "You may also decide to replace existing categories with imported ones." ) ),
504 				       _("Merge imported categories with existing?") );
505 
506     if ( !last_transaction_number)
507 	gtk_dialog_add_buttons ( GTK_DIALOG(dialog),
508 				 _("Replace existing"), 2,
509 				 NULL );
510 
511     gtk_dialog_add_buttons ( GTK_DIALOG(dialog),
512 			     "gtk-cancel", 0,
513 			     "gtk-ok", 1,
514 			     NULL );
515 
516     resultat = gtk_dialog_run ( GTK_DIALOG ( dialog ));
517     gtk_widget_destroy ( GTK_WIDGET ( dialog ));
518 
519     switch ( resultat )
520     {
521 		case 1 :
522 			gsb_file_others_load_category ( category_name );
523 			return;
524 
525 		case 2 :
526 			/* we want to replace the list */
527 			if ( !last_transaction_number )
528 				gsb_data_category_init_variables (TRUE);
529 			gsb_file_others_load_category ( category_name );
530 
531 		default :
532 			return;
533     }
534 }
535 
536 
537 /**
538  * Create a button bar allowing to act on the categories list.  Some
539  * of these buttons are "linked" to the selection status of the
540  * category metatree.  That is, if nothing is selected, they will
541  * become unsensitive.
542  *
543  * \return	A newly-allocated widget.
544  */
creation_barre_outils_categ(void)545 GtkWidget *creation_barre_outils_categ ( void )
546 {
547     GtkWidget *toolbar;
548     GtkToolItem *item;
549 
550     toolbar = gtk_toolbar_new ();
551 
552     /* New category button */
553     item = utils_buttons_tool_button_new_from_image_label ("gsb-new-categ-24.png", _("New\ncategory"));
554     gtk_widget_set_tooltip_text ( GTK_WIDGET ( item ), _("Create a new category") );
555     g_object_set_data ( G_OBJECT ( item ), "type", GINT_TO_POINTER (1) );
556     g_signal_connect_swapped ( G_OBJECT ( item ),
557                         "clicked",
558                         G_CALLBACK ( appui_sur_ajout_category ),
559                         categ_tree_model );
560     gtk_toolbar_insert ( GTK_TOOLBAR ( toolbar ), item, -1 );
561 
562     /* New sub category button */
563     item = utils_buttons_tool_button_new_from_image_label ("gsb-new-sub-categ-24.png", _("New sub\ncategory"));
564     metatree_register_widget_as_linked ( GTK_TREE_MODEL ( categ_tree_model ),
565                         GTK_WIDGET ( item ),
566                         "selection" );
567     metatree_register_widget_as_linked ( GTK_TREE_MODEL ( categ_tree_model ),
568                         GTK_WIDGET ( item ),
569                         "sub-division" );
570     gtk_widget_set_tooltip_text ( GTK_WIDGET ( item ), _("Create a new sub-category") );
571     g_object_set_data ( G_OBJECT ( item ), "type", GINT_TO_POINTER (2) );
572     g_signal_connect_swapped ( G_OBJECT ( item ),
573                         "clicked",
574                         G_CALLBACK ( appui_sur_ajout_category ),
575                         categ_tree_model );
576     gtk_toolbar_insert ( GTK_TOOLBAR ( toolbar ), item, -1 );
577 
578     /* Import button */
579     item = utils_buttons_tool_button_new_from_image_label ("gsb-import-24.png", _("Import"));
580     gtk_widget_set_tooltip_text ( GTK_WIDGET ( item ), _("Import a Grisbi category file (.cgsb)") );
581     g_signal_connect ( G_OBJECT ( item ),
582                         "clicked",
583                         G_CALLBACK ( categories_importer_list ),
584                         NULL );
585     gtk_toolbar_insert ( GTK_TOOLBAR ( toolbar ), item, -1 );
586 
587     /* Export button */
588     item = utils_buttons_tool_button_new_from_image_label ("gsb-export-24.png", _("Export"));
589     gtk_widget_set_tooltip_text ( GTK_WIDGET ( item ), _("Export a Grisbi category file (.cgsb)") );
590     g_signal_connect ( G_OBJECT ( item ),
591                         "clicked",
592                         G_CALLBACK ( categories_exporter_list ),
593                         NULL );
594     gtk_toolbar_insert ( GTK_TOOLBAR ( toolbar ), item, -1 );
595 
596     /* Delete button */
597     item = utils_buttons_tool_button_new_from_image_label ("gtk-delete-24.png", _("Delete"));
598     metatree_register_widget_as_linked ( GTK_TREE_MODEL ( categ_tree_model ),
599                         GTK_WIDGET ( item ),
600                         "selection" );
601     gtk_widget_set_tooltip_text ( GTK_WIDGET ( item ), _("Delete selected category") );
602     g_signal_connect_swapped ( G_OBJECT ( item ),
603                         "clicked",
604                         G_CALLBACK ( supprimer_division ),
605                         arbre_categ );
606     gtk_toolbar_insert ( GTK_TOOLBAR ( toolbar ), item, -1 );
607 
608     /* Properties button */
609     item = utils_buttons_tool_button_new_from_image_label ("gtk-edit-24.png", _("Edit"));
610     metatree_register_widget_as_linked ( GTK_TREE_MODEL ( categ_tree_model ),
611                         GTK_WIDGET ( item ),
612                         "selection" );
613     gtk_widget_set_tooltip_text ( GTK_WIDGET ( item ), _("Edit selected category") );
614     g_signal_connect_swapped ( G_OBJECT ( item ),
615                         "clicked",
616                         G_CALLBACK ( edit_category ),
617                         arbre_categ );
618     gtk_toolbar_insert ( GTK_TOOLBAR ( toolbar ), item, -1 );
619 
620     /* View button */
621     item = utils_buttons_tool_button_new_from_image_label ("gtk-select-color-24.png", _("View"));
622     gtk_widget_set_tooltip_text ( GTK_WIDGET ( item ), _("Change view mode"));
623     g_signal_connect ( G_OBJECT ( item ),
624                         "clicked",
625                         G_CALLBACK ( popup_category_view_mode_menu ),
626                         NULL );
627     gtk_toolbar_insert ( GTK_TOOLBAR ( toolbar ), item, -1 );
628 
629     metatree_set_linked_widgets_sensitive ( GTK_TREE_MODEL ( categ_tree_model ), FALSE, "selection" );
630 
631     return ( toolbar );
632 }
633 
634 
635 /**
636  *
637  *
638  *
639  */
gsb_gui_categories_toolbar_set_style(gint toolbar_style)640 void gsb_gui_categories_toolbar_set_style ( gint toolbar_style )
641 {
642     gtk_toolbar_set_style ( GTK_TOOLBAR ( category_toolbar ), toolbar_style );
643 }
644 
645 
646 /**
647  * Popup a menu that allow changing the view mode of the category
648  * metatree.
649  *
650  * \param button	Button that triggered the signal.
651  *
652  * \return		FALSE
653  */
popup_category_view_mode_menu(GtkWidget * button)654 gboolean popup_category_view_mode_menu ( GtkWidget *button )
655 {
656     GtkWidget *menu, *menu_item;
657 
658     menu = gtk_menu_new ();
659 
660     /* Edit transaction */
661     menu_item = gtk_menu_item_new_with_label ( _("Category view") );
662     g_signal_connect ( G_OBJECT(menu_item), "activate",
663 		       G_CALLBACK(expand_arbre_division), (gpointer) 0 );
664     g_object_set_data ( G_OBJECT(menu_item), "tree-view", arbre_categ );
665     gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ), menu_item );
666 
667     menu_item = gtk_menu_item_new_with_label ( _("Subcategory view") );
668     g_signal_connect ( G_OBJECT(menu_item), "activate",
669 		       G_CALLBACK(expand_arbre_division), (gpointer) 1 );
670     g_object_set_data ( G_OBJECT(menu_item), "tree-view", arbre_categ );
671     gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ), menu_item );
672 
673     menu_item = gtk_menu_item_new_with_label ( _("Complete view") );
674     g_signal_connect ( G_OBJECT(menu_item), "activate",
675 		       G_CALLBACK(expand_arbre_division), (gpointer) 2 );
676     g_object_set_data ( G_OBJECT(menu_item), "tree-view", arbre_categ );
677     gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ), menu_item );
678 
679     gtk_widget_show_all ( menu );
680 
681 #if GTK_CHECK_VERSION (3,22,0)
682 	gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
683 #else
684     gtk_menu_popup ( GTK_MENU(menu), NULL, button, set_popup_position, button, 1,
685 		     gtk_get_current_event_time());
686 #endif
687     return FALSE;
688 }
689 
690 
691 
692 /**
693  *
694  *
695  */
edit_category(GtkTreeView * tree_view)696 gboolean edit_category ( GtkTreeView *tree_view )
697 {
698     GtkWidget * dialog, *paddingbox, *table, *label, *entry, *hbox, *radiogroup;
699     gint category_number = -1, sub_category_number = -1;
700     GtkTreeSelection * selection;
701     GtkTreeModel * model = NULL;
702     GtkTreeIter iter;
703     gchar * title;
704     GtkTreeIter *div_iter;
705     MetatreeInterface *category_interface;
706 
707     /* fill category_number and sub_category_number */
708 
709     selection = gtk_tree_view_get_selection ( tree_view );
710     if ( selection && gtk_tree_selection_get_selected ( selection, &model, &iter ) )
711     {
712 	gtk_tree_model_get ( model, &iter,
713 			     META_TREE_NO_DIV_COLUMN, &category_number,
714 			     META_TREE_NO_SUB_DIV_COLUMN, &sub_category_number,
715 			     -1 );
716     }
717 
718     if ( !selection || category_number <= 0 )
719 	return FALSE;
720 
721     if ( sub_category_number > 0 )
722 	title = g_strdup_printf ( _("Properties for %s"), gsb_data_category_get_sub_category_name ( category_number,
723 												    sub_category_number,
724 												    _("No sub-category defined" )));
725     else
726 	title = g_strdup_printf ( _("Properties for %s"), gsb_data_category_get_name ( category_number,
727 										       0,
728 										       _("No category defined") ));
729 
730     dialog = gtk_dialog_new_with_buttons ( title,
731 					   GTK_WINDOW ( grisbi_app_get_active_window (NULL) ),
732 					   GTK_DIALOG_MODAL,
733 					   "gtk-cancel", GTK_RESPONSE_NO,
734 					   "gtk-apply", GTK_RESPONSE_OK,
735 					   NULL );
736 
737     gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
738     gtk_window_set_resizable ( GTK_WINDOW ( dialog ), FALSE );
739 
740     /* Ugly dance to avoid side effects on dialog's vbox. */
741     hbox = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, 0 );
742     gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area ( dialog ) ), hbox, FALSE, FALSE, 0 );
743     paddingbox = new_paddingbox_with_title ( hbox, TRUE, title );
744     gtk_container_set_border_width ( GTK_CONTAINER(hbox), 6 );
745     gtk_container_set_border_width ( GTK_CONTAINER(paddingbox), 6 );
746     g_free ( title );
747 
748     table = gtk_grid_new ();
749     gtk_box_pack_start ( GTK_BOX ( paddingbox ), table, FALSE, FALSE, 6 );
750     gtk_grid_set_column_spacing (GTK_GRID (table), 6);
751     gtk_grid_set_row_spacing (GTK_GRID (table), 6);
752 
753     /* Name entry */
754     label = gtk_label_new ( _("Name"));
755     utils_labels_set_alignment ( GTK_LABEL ( label ), 0.0, 0.5 );
756     gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
757 
758     entry = gtk_entry_new ( );
759     if ( sub_category_number > 0 )
760     {
761 	gtk_entry_set_text ( GTK_ENTRY ( entry ),
762 			     gsb_data_category_get_sub_category_name ( category_number,
763 								       sub_category_number,
764 								       NULL ) );
765     }
766     else
767     {
768 	gtk_entry_set_text ( GTK_ENTRY ( entry ),
769 			     gsb_data_category_get_name ( category_number, 0, NULL ) );
770     }
771 
772     gtk_widget_set_size_request ( entry, 400, -1 );
773     gtk_grid_attach (GTK_GRID (table), entry, 1, 0, 1, 1);
774 
775     if ( sub_category_number <= 0 )
776     {
777 	/* Description entry */
778 	label = gtk_label_new ( _("Type"));
779 	utils_labels_set_alignment ( GTK_LABEL ( label ), 0.0, 0.5 );
780 	gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
781 
782 	radiogroup = gsb_autofunc_radiobutton_new (  _("Credit"), _("Debit"),
783 						     gsb_data_category_get_type (category_number),
784 						     NULL, NULL,
785 						     G_CALLBACK (gsb_data_category_set_type), category_number );
786 	gtk_grid_attach (GTK_GRID (table), radiogroup, 1, 1, 1, 1);
787     }
788 
789     gtk_widget_show_all ( dialog );
790 
791     while ( 1 )
792     {
793 	if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) != GTK_RESPONSE_OK )
794 	{
795         sortie_edit_category = TRUE;
796 	    gtk_widget_destroy ( GTK_WIDGET ( dialog ) );
797 	    return FALSE;
798 	}
799 
800 	if ( ( sub_category_number > 0 &&
801 	       gsb_data_category_get_sub_category_number_by_name ( category_number,
802 								   gtk_entry_get_text ( GTK_ENTRY ( entry ) ),
803 								   FALSE ) &&
804 	       gsb_data_category_get_sub_category_number_by_name ( category_number,
805 								   gtk_entry_get_text ( GTK_ENTRY ( entry ) ),
806 								   FALSE ) != sub_category_number ) ||
807 	     ( sub_category_number <= 0 &&
808 	       gsb_data_category_get_number_by_name ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ),
809 						      FALSE, 0 ) &&
810 	       gsb_data_category_get_number_by_name ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ),
811 						      FALSE, 0 ) != category_number ) )
812 	{
813 	    gchar * message;
814 	    if ( sub_category_number > 0 )
815 	    {
816 		message = g_strdup_printf ( _("You tried to rename current sub-category to '%s' "
817 					      "but this sub-category already exists. Please "
818 					      "choose another name."),
819 					    gtk_entry_get_text ( GTK_ENTRY ( entry ) ) );
820 	    }
821 	    else
822 	    {
823 		message = g_strdup_printf ( _("You tried to rename current category to '%s' "
824 					      "but this category already exists. Please "
825 					      "choose another name."),
826 					    gtk_entry_get_text ( GTK_ENTRY ( entry ) ) );
827 	    }
828 	    dialogue_warning_hint ( message, _("Category already exists") );
829 	    g_free ( message );
830 	}
831 	else
832 	{
833 	    if ( sub_category_number > 0 )
834 	    {
835 		gsb_data_category_set_sub_category_name ( category_number,
836 							  sub_category_number,
837 							  gtk_entry_get_text ( GTK_ENTRY (entry)));
838 	    }
839 	    else
840 	    {
841 		gsb_data_category_set_name ( category_number,
842 					     gtk_entry_get_text ( GTK_ENTRY (entry)));
843 	    }
844 	    break;
845 	}
846     }
847 
848     gtk_widget_destroy ( dialog );
849 
850     category_interface = category_get_metatree_interface ( );
851 
852     if ( sub_category_number > 0 )
853     {
854 	div_iter = get_iter_from_div ( model, category_number, sub_category_number );
855 	fill_sub_division_row ( model, category_interface,
856 				div_iter,
857 				category_number,
858 				sub_category_number);
859     }
860     else
861     {
862 	div_iter = get_iter_from_div ( model, category_number, 0 );
863 	fill_division_row ( model, category_interface,
864 			    div_iter,
865 			    category_number );
866     }
867     gtk_tree_iter_free (div_iter);
868 
869     /* update the transactions list */
870     transaction_list_update_element (ELEMENT_CATEGORY);
871 
872     gsb_file_set_modified ( TRUE );
873 
874     return TRUE;
875 }
876 
877 
878 /**
879  * function to create and editing a new category.
880  *
881  * \param the model for the division
882  */
appui_sur_ajout_category(GtkTreeModel * model,GtkButton * button)883 void appui_sur_ajout_category ( GtkTreeModel *model,
884                         GtkButton *button )
885 {
886     gint type;
887 
888     type = GPOINTER_TO_INT ( g_object_get_data ( G_OBJECT (button), "type" ) );
889 
890     if ( type == 1 )
891         metatree_new_division ( model );
892     else
893     {
894         appui_sur_ajout_sub_division ( model );
895         selectionne_sub_category ( model );
896     }
897     sortie_edit_category = FALSE;
898     edit_category ( GTK_TREE_VIEW ( arbre_categ ) );
899     if ( sortie_edit_category )
900         supprimer_division ( GTK_TREE_VIEW ( arbre_categ ) );
901     sortie_edit_category = FALSE;
902 }
903 
904 
905 /**
906  * function to expand category and select new sub-category.
907  *
908  * \param the model for the division
909  */
selectionne_sub_category(GtkTreeModel * model)910 void selectionne_sub_category ( GtkTreeModel *model )
911 {
912     GtkTreeSelection * selection;
913     GtkTreeIter parent;
914     GtkTreeIter iter;
915 	GtkTreePath * path;
916     gchar * name;
917     gint category_number = -1, sub_category_number = -1;
918     gint i = 0,j = 0;
919 
920     selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (arbre_categ) );
921     if ( selection && gtk_tree_selection_get_selected (
922                         selection, &model, &parent ) )
923     {
924 	gtk_tree_model_get ( model, &parent,
925                         META_TREE_NO_DIV_COLUMN, &category_number,
926                         META_TREE_NO_SUB_DIV_COLUMN, &sub_category_number,
927                         -1 );
928     }
929 
930     if ( !selection || category_number <= 0 )
931         return;
932 
933     if ( sub_category_number > 0 )
934         return;
935 
936     name =  my_strdup (_("New sub-category"));
937     sub_category_number = gsb_data_category_get_sub_category_number_by_name (
938                         category_number, name, FALSE );
939     j = gtk_tree_model_iter_n_children ( model, &parent );
940     for (i = 0; i < j; i++ )
941     {
942         gint numero;
943 
944         gtk_tree_model_iter_nth_child ( model, &iter, &parent, i );
945         gtk_tree_model_get ( model, &iter,
946                         META_TREE_NO_SUB_DIV_COLUMN, &numero,
947                         -1 );
948         if ( numero == sub_category_number )
949             break;
950     }
951     path = gtk_tree_model_get_path ( model, &iter );
952     gtk_tree_view_expand_to_path ( GTK_TREE_VIEW (arbre_categ), path );
953     selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (arbre_categ) );
954     gtk_tree_selection_select_path ( selection, path );
955     gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW (arbre_categ), path,
956                         NULL, TRUE, 0.5, 0.5 );
957     gtk_tree_path_free ( path );
958     g_free ( name );
959 }
960 
961 
962 /**
963  * renvoie le chemin de la dernière categorie sélectionnée.
964  *
965  * \return une copie de category_hold_position -> path
966  */
categories_hold_position_get_path(void)967 GtkTreePath *categories_hold_position_get_path ( void )
968 {
969     return gtk_tree_path_copy ( category_hold_position -> path );
970 }
971 
972 /**
973  * sauvegarde le chemin de la dernière categorie sélectionnée.
974  *
975  * \param path
976  */
categories_hold_position_set_path(GtkTreePath * path)977 gboolean categories_hold_position_set_path ( GtkTreePath *path )
978 {
979     category_hold_position -> path = gtk_tree_path_copy ( path );
980 
981     return TRUE;
982 }
983 
984 
985 /**
986  * sauvegarde l'attribut expand.
987  *
988  * \param expand
989  */
categories_hold_position_set_expand(gboolean expand)990 gboolean categories_hold_position_set_expand ( gboolean expand )
991 {
992     category_hold_position -> expand = expand;
993 
994     return TRUE;
995 }
996 
997 
998 /**
999  * called when we press a button on the list
1000  *
1001  * \param tree_view
1002  * \param ev
1003  *
1004  * \return FALSE
1005  * */
category_list_button_press(GtkWidget * tree_view,GdkEventButton * ev,gpointer null)1006 gboolean category_list_button_press ( GtkWidget *tree_view,
1007                         GdkEventButton *ev,
1008                         gpointer null )
1009 {
1010     if ( ev -> button == RIGHT_BUTTON )
1011     {
1012         category_list_popup_context_menu ( );
1013 
1014         return TRUE;
1015     }
1016     else if ( ev -> type == GDK_2BUTTON_PRESS )
1017     {
1018         GtkTreeSelection *selection;
1019         GtkTreeModel *model = NULL;
1020         GtkTreeIter iter;
1021         GtkTreePath *path = NULL;
1022         enum MetaTreeRowType type_division;
1023 		GrisbiAppConf *a_conf;
1024 
1025         type_division = metatree_get_row_type_from_tree_view ( tree_view );
1026         if ( type_division == META_TREE_TRANSACTION )
1027             return FALSE;
1028 
1029         selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( tree_view ) );
1030         if ( selection && gtk_tree_selection_get_selected (selection, &model, &iter ) )
1031             path = gtk_tree_model_get_path  ( model, &iter);
1032 		else
1033 			return FALSE;
1034 
1035 		a_conf = (GrisbiAppConf *) grisbi_app_get_a_conf ();
1036         if ( a_conf->metatree_action_2button_press == 0 || type_division == META_TREE_DIV )
1037         {
1038             if ( gtk_tree_view_row_expanded ( GTK_TREE_VIEW ( tree_view ), path ) )
1039                 gtk_tree_view_collapse_row ( GTK_TREE_VIEW ( tree_view ), path );
1040             else
1041                 gtk_tree_view_expand_row ( GTK_TREE_VIEW ( tree_view ), path, FALSE );
1042 
1043             gtk_tree_path_free ( path );
1044             return FALSE;
1045         }
1046         else if ( a_conf->metatree_action_2button_press == 1 )
1047         {
1048             edit_category ( GTK_TREE_VIEW ( tree_view ) );
1049 
1050             gtk_tree_path_free ( path );
1051             return TRUE;
1052         }
1053         else
1054         {
1055             if ( type_division == META_TREE_SUB_DIV || type_division == META_TREE_TRANS_S_S_DIV )
1056             {
1057                     gtk_tree_view_collapse_row ( GTK_TREE_VIEW ( tree_view ), path );
1058 
1059                     gtk_tree_path_free ( path );
1060 
1061                 metatree_manage_sub_divisions ( tree_view );
1062                 return TRUE;
1063             }
1064             else
1065                 return FALSE;
1066         }
1067     }
1068 
1069     return FALSE;
1070 }
1071 
1072 
1073 /**
1074  * Pop up a menu with several actions to apply to current selection.
1075  *
1076  * \param
1077  *
1078  */
category_list_popup_context_menu(void)1079 void category_list_popup_context_menu ( void )
1080 {
1081     GtkWidget *menu;
1082     GtkWidget *menu_item;
1083     gchar *title;
1084     enum MetaTreeRowType type_division;
1085 
1086     type_division = metatree_get_row_type_from_tree_view ( arbre_categ );
1087 
1088     if ( type_division == META_TREE_INVALID )
1089         return;
1090 
1091     menu = gtk_menu_new ();
1092 
1093     if ( type_division == META_TREE_TRANSACTION )
1094     {
1095         title = g_strdup ( _("Transfers the identical transactions in another sub-category") );
1096 
1097         menu_item = utils_menu_item_new_from_image_label ("gsb-convert-16.png", title);
1098         g_signal_connect_swapped ( G_OBJECT ( menu_item ),
1099                         "activate",
1100                         G_CALLBACK ( metatree_transfer_identical_transactions ),
1101                         arbre_categ );
1102         gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ), menu_item );
1103 
1104         g_free ( title );
1105     }
1106 
1107     if ( type_division == META_TREE_DIV || type_division == META_TREE_SUB_DIV )
1108     {
1109 
1110         /* Edit transaction */
1111         if ( type_division == META_TREE_DIV )
1112             title = g_strdup ( _("Edit selected category") );
1113         else
1114             title = g_strdup ( _("Edit selected sub-category") );
1115 
1116         menu_item = utils_menu_item_new_from_image_label ("gtk-edit-16.png", title);
1117         g_signal_connect_swapped ( G_OBJECT ( menu_item ),
1118                             "activate",
1119                             G_CALLBACK ( edit_category ),
1120                             arbre_categ );
1121         gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ), menu_item );
1122 
1123         g_free ( title );
1124     }
1125 
1126     if ( type_division == META_TREE_SUB_DIV || type_division == META_TREE_TRANS_S_S_DIV )
1127     {
1128         /* Manage sub_divisions */
1129         if ( type_division == META_TREE_SUB_DIV )
1130         {
1131             /* Separator */
1132             gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ), gtk_separator_menu_item_new ( ) );
1133             title = g_strdup ( _("Manage sub-categories") );
1134         }
1135         else
1136             title = g_strdup ( _("Transfer all transactions in another sub-category") );
1137 
1138         menu_item = utils_menu_item_new_from_image_label ("gsb-convert-16.png", title);
1139         g_signal_connect_swapped ( G_OBJECT ( menu_item ),
1140                         "activate",
1141                         G_CALLBACK ( metatree_manage_sub_divisions ),
1142                         arbre_categ );
1143         gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ), menu_item );
1144 
1145         g_free ( title );
1146     }
1147 
1148     /* Finish all. */
1149     gtk_widget_show_all ( menu );
1150 
1151 #if GTK_CHECK_VERSION (3,22,0)
1152 	gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
1153 #else
1154     gtk_menu_popup ( GTK_MENU ( menu ), NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time ( ) );
1155 #endif
1156 }
1157 
1158 
1159 /**
1160  *
1161  *
1162  *
1163  */
categories_get_tree_store(void)1164 GtkTreeStore *categories_get_tree_store ( void )
1165 {
1166     return categ_tree_model;
1167 }
1168 
1169 
1170 /**
1171  *
1172  *
1173  *
1174  */
categories_get_tree_view(void)1175 GtkWidget *categories_get_tree_view ( void )
1176 {
1177     return arbre_categ;
1178 }
1179 
1180 
1181 /**
1182  *
1183  *
1184  *
1185  */
categories_new_category(void)1186 void categories_new_category ( void )
1187 {
1188     metatree_new_division ( GTK_TREE_MODEL ( categ_tree_model ) );
1189 
1190     sortie_edit_category = FALSE;
1191     edit_category ( GTK_TREE_VIEW ( arbre_categ ) );
1192     if ( sortie_edit_category )
1193     {
1194         supprimer_division ( GTK_TREE_VIEW ( arbre_categ ) );
1195         sortie_edit_category = FALSE;
1196     }
1197 }
1198 
1199 
1200 /**
1201  *
1202  *
1203  *
1204  */
categories_delete_category(void)1205 void categories_delete_category ( void )
1206 {
1207     supprimer_division ( GTK_TREE_VIEW ( arbre_categ ) );
1208 }
1209 
1210 
1211 /**
1212  *
1213  *
1214  *
1215  */
categories_edit_category(void)1216 void categories_edit_category ( void )
1217 {
1218     edit_category ( GTK_TREE_VIEW ( arbre_categ ) );
1219 }
1220 
1221 
1222 /**
1223  *
1224  *
1225  * \param
1226  *
1227  * \return
1228  * */
1229 /* Local Variables: */
1230 /* c-basic-offset: 4 */
1231 /* End: */
1232