1 /*
2  * GNT - The GLib Ncurses Toolkit
3  *
4  * GNT is the legal property of its developers, whose names are too numerous
5  * to list here.  Please refer to the COPYRIGHT file distributed with this
6  * source distribution.
7  *
8  * This library 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., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
21  */
22 
23 #ifndef GNT_TREE_H
24 #define GNT_TREE_H
25 /**
26  * SECTION:gnttree
27  * @section_id: libgnt-gnttree
28  * @title: GntTree
29  * @short_description: A widget that shows a tree of items
30  */
31 
32 #include "gnt.h"
33 #include "gntcolors.h"
34 #include "gntkeys.h"
35 #include "gnttextview.h"
36 #include "gntwidget.h"
37 
38 #define GNT_TYPE_TREE				(gnt_tree_get_gtype())
39 #define GNT_TREE(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_TREE, GntTree))
40 #define GNT_TREE_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_TREE, GntTreeClass))
41 #define GNT_IS_TREE(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_TREE))
42 #define GNT_IS_TREE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_TREE))
43 #define GNT_TREE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_TREE, GntTreeClass))
44 
45 typedef struct _GntTree			GntTree;
46 typedef struct _GntTreeClass		GntTreeClass;
47 #ifndef GNT_DISABLE_DEPRECATED
48 /**
49  * GntTreePriv:
50  *
51  * Deprecated: 2.14.0: This is an internal implementation detail.
52  */
53 typedef struct _GntTreePriv GntTreePriv;
54 #endif
55 
56 typedef struct _GntTreeRow		GntTreeRow;
57 #ifndef GNT_DISABLE_DEPRECATED
58 /**
59  * GntTreeCol:
60  *
61  * Deprecated: 2.14.0: This is an internal implementation detail.
62  */
63 typedef struct _GntTreeCol		GntTreeCol;
64 
65 /**
66  * GntTreeColumnFlag:
67  *
68  * Deprecated: 2.14.0: This is an internal implementation detail.
69  */
70 typedef enum _GntTreeColumnFlag {
71 	GNT_TREE_COLUMN_INVISIBLE    = 1 << 0,
72 	GNT_TREE_COLUMN_FIXED_SIZE   = 1 << 1,
73 	GNT_TREE_COLUMN_BINARY_DATA  = 1 << 2,
74 	GNT_TREE_COLUMN_RIGHT_ALIGNED = 1 << 3,
75 } GntTreeColumnFlag;
76 #else
77 typedef enum {
78 	GNT_TREE_COLUMN_SEALED__DO_NOT_USE
79 } GntTreeColumnFlag;
80 #endif
81 
82 /**
83  * GntTree:
84  *
85  * Access to any fields is deprecated. See inline comments for replacements.
86  */
87 struct _GntTree
88 {
89 	GntWidget parent;
90 
91 	GntTreeRow *GNTSEAL(current);    /* current selection */
92 
93 	GntTreeRow *GNTSEAL(top);        /* The topmost visible item */
94 	GntTreeRow *GNTSEAL(bottom);     /* The bottommost visible item */
95 
96 	GntTreeRow *GNTSEAL(root);       /* The root of all evil */
97 
98 	GList *GNTSEAL(list);            /* List of GntTreeRow s */
99 	GHashTable *GNTSEAL(hash);       /* We need this for quickly referencing the rows */
100 	guint (*GNTSEAL(hash_func))(gconstpointer);
101 	gboolean (*GNTSEAL(hash_eq_func))(gconstpointer, gconstpointer);
102 	GDestroyNotify GNTSEAL(key_destroy);
103 	GDestroyNotify GNTSEAL(value_destroy);
104 
105 	int GNTSEAL(ncol);               /* No. of columns */
106 	struct _GntTreeColInfo
107 	{
108 		int GNTSEAL(width);
109 		char *GNTSEAL(title);
110 		int GNTSEAL(width_ratio);
111 		GntTreeColumnFlag GNTSEAL(flags);
112 	} *GNTSEAL(columns);             /* Would a GList be better? */
113 	gboolean GNTSEAL(show_title);
114 	gboolean GNTSEAL(show_separator); /* Whether to show column separators */
115 
116 	struct _GntTreePriv *GNTSEAL(priv);
117 };
118 
119 struct _GntTreeClass
120 {
121 	GntWidgetClass parent;
122 
123 	void (*selection_changed)(GntTreeRow *old, GntTreeRow * current);
124 	void (*toggled)(GntTree *tree, gpointer key);
125 
126 	/*< private >*/
127 	void (*gnt_reserved1)(void);
128 	void (*gnt_reserved2)(void);
129 	void (*gnt_reserved3)(void);
130 	void (*gnt_reserved4)(void);
131 };
132 
133 G_BEGIN_DECLS
134 
135 /**
136  * gnt_tree_get_gtype:
137  *
138  * Returns: The GType for GntTree
139  */
140 GType gnt_tree_get_gtype(void);
141 
142 /**
143  * gnt_tree_new:
144  *
145  * Create a tree with one column.
146  *
147  * See gnt_tree_new_with_columns().
148  *
149  * Returns: The newly created tree
150  */
151 GntWidget * gnt_tree_new(void);
152 
153 /**
154  * gnt_tree_new_with_columns:
155  * @columns:  Number of columns
156  *
157  * Create a tree with a specified number of columns.
158  *
159  * See gnt_tree_new().
160  *
161  * Returns:  The newly created tree
162  */
163 GntWidget * gnt_tree_new_with_columns(int columns);
164 
165 /**
166  * gnt_tree_set_visible_rows:
167  * @tree:  The tree
168  * @rows:  The number of rows
169  *
170  * The number of rows the tree should display at a time.
171  */
172 void gnt_tree_set_visible_rows(GntTree *tree, int rows);
173 
174 /**
175  * gnt_tree_get_visible_rows:
176  * @tree:  The tree
177  *
178  * Get the number visible rows.
179  *
180  * Returns:  The number of visible rows
181  */
182 int gnt_tree_get_visible_rows(GntTree *tree);
183 
184 /**
185  * gnt_tree_scroll:
186  * @tree:   The tree
187  * @count:  If positive, the tree will be scrolled down by count rows,
188  *               otherwise, it will be scrolled up by count rows.
189  *
190  * Scroll the contents of the tree.
191  */
192 void gnt_tree_scroll(GntTree *tree, int count);
193 
194 /**
195  * gnt_tree_add_row_after:
196  * @tree:    The tree
197  * @key:     The key for the row
198  * @row:     The row to insert
199  * @parent:  The key for the parent row
200  * @bigbro:  The key for the row to insert the new row after.
201  *
202  * Insert a row in the tree.
203  *
204  * See gnt_tree_create_row(), gnt_tree_add_row_last(), gnt_tree_add_choice().
205  *
206  * Returns:  The inserted row
207  */
208 GntTreeRow * gnt_tree_add_row_after(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro);
209 
210 /**
211  * gnt_tree_add_row_last:
212  * @tree:    The tree
213  * @key:     The key for the row
214  * @row:     The row to insert
215  * @parent:  The key for the parent row
216  *
217  * Insert a row at the end of the tree.
218  *
219  * See gnt_tree_create_row(), gnt_tree_add_row_after(), gnt_tree_add_choice().
220  *
221  * Returns: The inserted row
222  */
223 GntTreeRow * gnt_tree_add_row_last(GntTree *tree, void *key, GntTreeRow *row, void *parent);
224 
225 /**
226  * gnt_tree_get_selection_data:
227  * @tree:  The tree
228  *
229  * Get the key for the selected row.
230  *
231  * Returns: (transfer none): The key for the selected row
232  */
233 gpointer gnt_tree_get_selection_data(GntTree *tree);
234 
235 /**
236  * gnt_tree_get_selection_text:
237  * @tree:  The tree
238  *
239  * Get the text displayed for the selected row.
240  *
241  * See gnt_tree_get_row_text_list(), gnt_tree_get_selection_text_list().
242  *
243  * Returns:  The text, which needs to be freed by the caller
244  */
245 char * gnt_tree_get_selection_text(GntTree *tree);
246 
247 /**
248  * gnt_tree_get_row_text_list:
249  * @tree:  The tree
250  * @key:   A key corresponding to the row in question. If key
251  *         is %NULL, the text list for the selected row will
252  *         be returned.
253  *
254  * Get a list of text for a row.
255  *
256  * See gnt_tree_get_selection_text_list(), gnt_tree_get_selection_text().
257  *
258  * Returns: (transfer container) (element-type utf8): A list of texts of a row.
259  *          The list and its data should be freed by the caller. The caller
260  *          should make sure that if any column of the tree contains binary
261  *          data, it's not freed.
262  */
263 /* TODO This leaks when used from introspection. The transfer mode for the
264         return type here should be 'full', but that would free binary data as
265         well. */
266 GList * gnt_tree_get_row_text_list(GntTree *tree, gpointer key);
267 
268 /**
269  * gnt_tree_row_get_key:
270  * @tree:   The tree
271  * @row:    The GntTreeRow object
272  *
273  * Get the key of a row.
274  *
275  * Returns: (transfer none): The key of the row.
276  *
277  * Since: 2.7.3
278  */
279 gpointer gnt_tree_row_get_key(GntTree *tree, GntTreeRow *row);
280 
281 /**
282  * gnt_tree_row_get_next:
283  * @tree: The tree
284  * @row:  The GntTreeRow object
285  *
286  * Get the next row.
287  *
288  * Returns: The next row.
289  *
290  * Since: 2.7.3
291  */
292 GntTreeRow * gnt_tree_row_get_next(GntTree *tree, GntTreeRow *row);
293 
294 /**
295  * gnt_tree_row_get_prev:
296  * @tree: The tree
297  * @row:  The GntTreeRow object
298  *
299  * Get the previous row.
300  *
301  * Returns: The previous row.
302  *
303  * Since: 2.7.3
304  */
305 GntTreeRow * gnt_tree_row_get_prev(GntTree *tree, GntTreeRow *row);
306 
307 /**
308  * gnt_tree_row_get_child:
309  * @tree: The tree
310  * @row:  The GntTreeRow object
311  *
312  * Get the child row.
313  *
314  * Returns: The child row.
315  *
316  * Since: 2.7.3
317  */
318 GntTreeRow * gnt_tree_row_get_child(GntTree *tree, GntTreeRow *row);
319 
320 /**
321  * gnt_tree_row_get_parent:
322  * @tree: The tree
323  * @row:  The GntTreeRow object
324  *
325  * Get the parent row.
326  *
327  * Returns: The parent row.
328  *
329  * Since: 2.7.3
330  */
331 GntTreeRow * gnt_tree_row_get_parent(GntTree *tree, GntTreeRow *row);
332 
333 /**
334  * gnt_tree_get_selection_text_list:
335  * @tree:  The tree
336  *
337  * Get a list of text of the current row.
338  *
339  * See gnt_tree_get_row_text_list(), gnt_tree_get_selection_text().
340  *
341  * Returns: (transfer container) (element-type utf8): A list of texts of the
342  *          currently selected row. The list and its data should be freed by
343  *          the caller. The caller should make sure that if any column of the
344  *          tree contains binary data, it's not freed.
345  */
346 /* TODO This leaks when used from introspection. The transfer mode for the
347         return type here should be 'full', but that would free binary data as
348         well. */
349 GList * gnt_tree_get_selection_text_list(GntTree *tree);
350 
351 /**
352  * gnt_tree_get_rows:
353  * @tree:  The tree
354  *
355  * Returns the list of rows in the tree.
356  *
357  * Returns: (transfer none) (element-type Gnt.TreeRow): The list of the rows.
358  *          The list should not be modified by the caller.
359  */
360 GList *gnt_tree_get_rows(GntTree *tree);
361 
362 /**
363  * gnt_tree_remove:
364  * @tree:  The tree
365  * @key:   The key for the row to remove
366  *
367  * Remove a row from the tree.
368  */
369 void gnt_tree_remove(GntTree *tree, gpointer key);
370 
371 /**
372  * gnt_tree_remove_all:
373  * @tree:  The tree
374  *
375  * Remove all the item from the tree.
376  */
377 void gnt_tree_remove_all(GntTree *tree);
378 
379 /**
380  * gnt_tree_get_selection_visible_line:
381  * @tree:  The tree
382  *
383  * Get the visible line number of the selected row.
384  *
385  * Returns:  The line number of the currently selected row
386  */
387 int gnt_tree_get_selection_visible_line(GntTree *tree);
388 
389 /**
390  * gnt_tree_change_text:
391  * @tree:   The tree
392  * @key:    The key for the row
393  * @colno:  The index of the column
394  * @text:   The new text
395  *
396  * Change the text of a column in a row.
397  */
398 void gnt_tree_change_text(GntTree *tree, gpointer key, int colno, const char *text);
399 
400 /**
401  * gnt_tree_add_choice:
402  * @tree:    The tree
403  * @key:     The key for the row
404  * @row:     The row to add
405  * @parent:  The parent of the row, or %NULL
406  * @bigbro:  The row to insert after, or %NULL
407  *
408  * Add a checkable item in the tree.
409  *
410  * See gnt_tree_create_row(), gnt_tree_create_row_from_list(),
411  *     gnt_tree_add_row_last(), gnt_tree_add_row_after().
412  *
413  * Returns:  The row inserted.
414  */
415 GntTreeRow * gnt_tree_add_choice(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro);
416 
417 /**
418  * gnt_tree_set_choice:
419  * @tree:   The tree
420  * @key:    The key for the row
421  * @set:    %TRUE if the item should be checked, %FALSE if not
422  *
423  * Set whether a checkable item is checked or not.
424  */
425 void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set);
426 
427 /**
428  * gnt_tree_get_choice:
429  * @tree:  The tree
430  * @key:   The key for the row
431  *
432  * Return whether a row is selected or not, where the row is a checkable item.
433  *
434  * Returns:    %TRUE if the row is checked, %FALSE otherwise.
435  */
436 gboolean gnt_tree_get_choice(GntTree *tree, void *key);
437 
438 /**
439  * gnt_tree_set_row_flags:
440  * @tree:   The tree
441  * @key:    The key for the row
442  * @flags:  The flags to set
443  *
444  * Set flags for the text in a row in the tree.
445  */
446 void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags);
447 
448 /**
449  * gnt_tree_set_row_color:
450  * @tree:   The tree
451  * @key:    The key for the row
452  * @color:  The color
453  *
454  * Set color for the text in a row in the tree.
455  *
456  * Since: 2.4.0
457  */
458 void gnt_tree_set_row_color(GntTree *tree, void *key, int color);
459 
460 /**
461  * gnt_tree_set_selected:
462  * @tree:  The tree
463  * @key:   The key of the row to select
464  *
465  * Select a row.
466  */
467 void gnt_tree_set_selected(GntTree *tree , void *key);
468 
469 /**
470  * gnt_tree_create_row:
471  * @tree: The tree
472  * @...:  A string for each column in the tree
473  *
474  * Create a row to insert in the tree.
475  *
476  * See gnt_tree_create_row_from_list(), gnt_tree_add_row_after(),
477  *     gnt_tree_add_row_last(), gnt_tree_add_choice().
478  *
479  * Returns:   The row
480  */
481 GntTreeRow * gnt_tree_create_row(GntTree *tree, ...);
482 
483 /**
484  * gnt_tree_create_row_from_list:
485  * @tree: The tree
486  * @list: (element-type utf8): The list containing the text for each column
487  *
488  * Create a row from a list of text.
489  *
490  * See gnt_tree_create_row(), gnt_tree_add_row_after(), gnt_tree_add_row_last(),
491  *     gnt_tree_add_choice().
492  *
493  * Returns: (transfer full): The row
494  */
495 GntTreeRow * gnt_tree_create_row_from_list(GntTree *tree, GList *list);
496 
497 /**
498  * gnt_tree_set_col_width:
499  * @tree:   The tree
500  * @col:    The index of the column
501  * @width:  The width for the column
502  *
503  * Set the width of a column in the tree.
504  *
505  * See gnt_tree_set_column_width_ratio(), gnt_tree_set_column_resizable()
506  */
507 void gnt_tree_set_col_width(GntTree *tree, int col, int width);
508 
509 /**
510  * gnt_tree_set_column_title:
511  * @tree:   The tree
512  * @index:  The index of the column
513  * @title:  The title for the column
514  *
515  * Set the title for a column.
516  *
517  * See gnt_tree_set_column_titles(), gnt_tree_set_show_title().
518  *
519  * Since: 2.1.0
520  */
521 void gnt_tree_set_column_title(GntTree *tree, int index, const char *title);
522 
523 /**
524  * gnt_tree_set_column_titles:
525  * @tree:  The tree
526  * @...:   One title for each column in the tree
527  *
528  * Set the titles of the columns
529  *
530  * See gnt_tree_set_column_title(), gnt_tree_set_show_title().
531  */
532 void gnt_tree_set_column_titles(GntTree *tree, ...);
533 
534 /**
535  * gnt_tree_set_show_title:
536  * @tree:  The tree
537  * @set:   If %TRUE, the column titles are displayed
538  *
539  * Set whether to display the title of the columns.
540  *
541  * See gnt_tree_set_column_title(), gnt_tree_set_column_titles().
542  */
543 void gnt_tree_set_show_title(GntTree *tree, gboolean set);
544 
545 /**
546  * gnt_tree_set_compare_func:
547  * @tree: The tree
548  * @func: (scope call): The comparison function, which is used to compare
549  *        the keys
550  *
551  * Set the compare function for sorting the data.
552  *
553  * See gnt_tree_sort_row().
554  */
555 void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func);
556 
557 /**
558  * gnt_tree_set_expanded:
559  * @tree:      The tree
560  * @key:       The key of the row
561  * @expanded:  Whether to expand the child rows
562  *
563  * Set whether a row, which has child rows, should be expanded.
564  */
565 void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded);
566 
567 /**
568  * gnt_tree_set_show_separator:
569  * @tree:  The tree
570  * @set:   If %TRUE, the column separators are displayed
571  *
572  * Set whether to show column separators.
573  */
574 void gnt_tree_set_show_separator(GntTree *tree, gboolean set);
575 
576 /**
577  * gnt_tree_sort_row:
578  * @tree:  The tree
579  * @row:   The row to sort
580  *
581  * Sort a row in the tree.
582  *
583  * See gnt_tree_set_compare_func().
584  */
585 void gnt_tree_sort_row(GntTree *tree, void *row);
586 
587 /**
588  * gnt_tree_adjust_columns:
589  * @tree:  The tree
590  *
591  * Automatically adjust the width of the columns in the tree.
592  */
593 void gnt_tree_adjust_columns(GntTree *tree);
594 
595 /**
596  * gnt_tree_set_hash_fns:
597  * @tree:  The tree
598  * @hash:  The hashing function
599  * @eq:    The function to compare keys
600  * @kd:    The function to use to free the keys when a row is removed
601  *              from the tree
602  *
603  * Set the hash functions to use to hash, compare and free the keys.
604  */
605 void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd);
606 
607 /**
608  * gnt_tree_set_column_visible:
609  * @tree:  The tree
610  * @col:   The index of the column
611  * @vis:   If %FALSE, the column will not be displayed
612  *
613  * Set whether a column is visible or not.
614  * This can be useful when, for example, we want to store some data
615  * which we don't want/need to display.
616  */
617 void gnt_tree_set_column_visible(GntTree *tree, int col, gboolean vis);
618 
619 /**
620  * gnt_tree_set_column_resizable:
621  * @tree:  The tree
622  * @col:   The index of the column
623  * @res:   If %FALSE, the column will not be resized when the
624  *              tree is resized
625  *
626  * Set whether a column can be resized to keep the same ratio when the
627  * tree is resized.
628  *
629  * See gnt_tree_set_col_width(), gnt_tree_set_column_width_ratio().
630  *
631  * Since: 2.1.0
632  */
633 void gnt_tree_set_column_resizable(GntTree *tree, int col, gboolean res);
634 
635 /**
636  * gnt_tree_set_column_is_binary:
637  * @tree:  The tree
638  * @col:   The index of the column
639  * @bin:   %TRUE if the data for the column is binary
640  *
641  * Set whether data in a column should be considered as binary data, and
642  * not as strings. A column containing binary data will be display empty text.
643  */
644 void gnt_tree_set_column_is_binary(GntTree *tree, int col, gboolean bin);
645 
646 /**
647  * gnt_tree_set_column_is_right_aligned:
648  * @tree:  The tree
649  * @col:   The index of the column
650  * @right: %TRUE if the text in the column should be right aligned
651  *
652  * Set whether text in a column should be right-aligned.
653  *
654  * Since: 2.1.0
655  */
656 void gnt_tree_set_column_is_right_aligned(GntTree *tree, int col, gboolean right);
657 
658 /**
659  * gnt_tree_set_column_width_ratio:
660  * @tree:   The tree
661  * @cols:   Array of widths. The width must have the same number
662  *               of entries as the number of columns in the tree, or
663  *               end with a negative value for a column-width.
664  *
665  * Set column widths to use when calculating column widths after a tree
666  * is resized.
667  *
668  * See gnt_tree_set_col_width(), gnt_tree_set_column_resizable().
669  *
670  * Since: 2.1.0
671  */
672 void gnt_tree_set_column_width_ratio(GntTree *tree, int cols[]);
673 
674 /**
675  * gnt_tree_set_search_column:
676  * @tree:   The tree
677  * @col:    The index of the column
678  *
679  * Set the column to use for typeahead searching.
680  *
681  * Since: 2.1.0
682  */
683 void gnt_tree_set_search_column(GntTree *tree, int col);
684 
685 /**
686  * gnt_tree_is_searching:
687  * @tree:   The tree
688  *
689  * Check whether the user is currently in the middle of a search.
690  *
691  * Returns:  %TRUE if the user is searching, %FALSE otherwise.
692  *
693  * Since: 2.1.0
694  */
695 gboolean gnt_tree_is_searching(GntTree *tree);
696 
697 /**
698  * gnt_tree_set_search_function:
699  * @tree:  The tree
700  * @func:  The custom search function. The search function is
701  *              sent the tree itself, the key of a row, the search
702  *              string and the content of row in the search column.
703  *              If the function returns %TRUE, the row is dislayed,
704  *              otherwise it's not.
705  *
706  * Set a custom search function.
707  *
708  * Since: 2.1.0
709  */
710 void gnt_tree_set_search_function(GntTree *tree,
711 		gboolean (*func)(GntTree *tree, gpointer key, const char *search, const char *current));
712 
713 /**
714  * gnt_tree_get_parent_key:
715  * @tree:  The tree
716  * @key:   The key for the row.
717  *
718  * Get the parent key for a row.
719  *
720  * Returns: (transfer none): The key of the parent row.
721  *
722  * Since: 2.4.0
723  */
724 gpointer gnt_tree_get_parent_key(GntTree *tree, gpointer key);
725 
726 G_END_DECLS
727 
728 #endif /* GNT_TREE_H */
729