]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/treectrl.cpp
made pre-compiling the python files optional
[wxWidgets.git] / src / gtk1 / treectrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: treectrl.cpp
3 // Purpose:
4 // Author: Denis Pershin
5 // Created: 07/05/98
6 // Id: $Id$
7 // Copyright: (c) 1998 Denis Pershin and Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation "treectrl.h"
13 #endif
14
15 #include "wx/gtk/treectrl.h"
16 #include "wx/settings.h"
17 #include "wx/log.h"
18
19 #ifdef USE_GDK_IMLIB
20 #include "../gdk_imlib/gdk_imlib.h"
21 #endif
22
23 //-----------------------------------------------------------------------------
24 // wxTreeItem
25 //-----------------------------------------------------------------------------
26
27 // clicked
28
29 void gtk_treeitem_expand_callback(GtkWidget *WXUNUSED(widget), wxTreeItem *treeitem) {
30 treeitem->SendExpanding(treeitem->m_owner);
31 treeitem->SendExpand(treeitem->m_owner);
32 };
33
34 void gtk_treeitem_collapse_callback( GtkWidget *WXUNUSED(widget), wxTreeItem *treeitem) {
35 treeitem->SendCollapsing(treeitem->m_owner);
36 treeitem->SendCollapse(treeitem->m_owner);
37 };
38
39 void gtk_treeitem_select_callback( GtkWidget *WXUNUSED(widget), wxTreeItem *treeitem) {
40 treeitem->SendSelChanging(treeitem->m_owner);
41 treeitem->m_state |= wxTREE_STATE_SELECTED;
42 treeitem->SendSelChanged(treeitem->m_owner);
43 }
44
45 void gtk_treeitem_deselect_callback( GtkWidget *WXUNUSED(widget), wxTreeItem *treeitem) {
46 treeitem->SendSelChanging(treeitem->m_owner);
47 treeitem->m_state &= !wxTREE_STATE_SELECTED;
48 treeitem->SendSelChanged(treeitem->m_owner);
49 }
50
51 IMPLEMENT_DYNAMIC_CLASS(wxTreeItem, wxObject)
52
53 wxTreeItem::wxTreeItem() {
54 m_mask = 0;
55 m_itemId = 0;
56 m_state = 0;
57 m_stateMask = 0;
58 m_image = -1;
59 m_children = 0;
60 m_selectedImage = -1;
61 m_tree = NULL;
62 m_parentwidget = NULL;
63 m_widget = NULL;
64 m_data = 0;
65 m_owner = 0;
66 expand_handler = 0;
67 collapse_handler = 0;
68 };
69
70 wxTreeItem::wxTreeItem(GtkWidget *parent, const wxTreeItem &item) {
71 m_mask = item.m_mask;
72 m_text = item.m_text;
73 m_itemId = item.m_itemId;
74 m_state = item.m_state;
75 m_stateMask = item.m_stateMask;
76 m_image = item.m_image;
77 m_tree = NULL;
78 m_owner = 0;
79 m_selectedImage = item.m_selectedImage;
80 m_children = item.m_children;
81 m_childlist = item.m_childlist;
82 m_data = item.m_data;
83 m_parentwidget = parent;
84 expand_handler = 0;
85 collapse_handler = 0;
86
87 Create();
88 }
89
90 void wxTreeItem::Create() {
91 wxASSERT(m_parentwidget != NULL);
92
93 m_widget = GTK_TREE_ITEM(gtk_tree_item_new_with_label ((char *)(const char *)m_text));
94 gtk_container_add (GTK_CONTAINER(m_parentwidget), GTK_WIDGET(m_widget));
95 gtk_widget_show(GTK_WIDGET(m_widget));
96
97 gtk_signal_connect(GTK_OBJECT(m_widget), "select",
98 GTK_SIGNAL_FUNC(gtk_treeitem_select_callback), (gpointer)this );
99
100 gtk_signal_connect(GTK_OBJECT(m_widget), "deselect",
101 GTK_SIGNAL_FUNC(gtk_treeitem_deselect_callback), (gpointer)this );
102
103 if ((m_mask & wxTREE_MASK_CHILDREN) != 0)
104 AddSubtree();
105 }
106
107 wxTreeItem::~wxTreeItem() {
108 if (m_owner != NULL)
109 SendDelete(m_owner);
110 DeleteChildren();
111 if ((m_widget != NULL) && (m_parentwidget != NULL))
112 gtk_container_remove(GTK_CONTAINER(m_parentwidget),
113 GTK_WIDGET(m_widget));
114 // if (m_tree != NULL) {
115 // gtk_widget_destroy(GTK_WIDGET(m_tree));
116 // m_tree = NULL;
117 // }
118
119 // if (m_widget != NULL)
120 // gtk_widget_destroy(GTK_WIDGET(m_widget));
121 }
122
123 void wxTreeItem::AddSubtree() {
124 if (m_widget == NULL)
125 return;
126
127 m_tree = GTK_TREE(gtk_tree_new());
128
129 if (expand_handler == 0)
130 expand_handler = gtk_signal_connect(GTK_OBJECT(m_widget), "expand",
131 GTK_SIGNAL_FUNC(gtk_treeitem_expand_callback), (gpointer)this );
132
133 if (collapse_handler == 0)
134 collapse_handler = gtk_signal_connect( GTK_OBJECT(m_widget), "collapse",
135 GTK_SIGNAL_FUNC(gtk_treeitem_collapse_callback), (gpointer)this );
136
137 gtk_tree_item_set_subtree(GTK_TREE_ITEM(m_widget), GTK_WIDGET(m_tree));
138 gtk_widget_show(GTK_WIDGET(m_tree));
139 }
140
141 void wxTreeItem::AddChild(wxTreeItem *child) {
142 wxASSERT(child != NULL);
143
144 m_childlist.Append(child);
145 }
146
147 bool wxTreeItem::HasChildren() {
148 return (m_childlist.Number() != 0);
149 }
150
151 void wxTreeItem::DeleteChildren() {
152 wxTreeItem *item;
153 long no = GetChildrenNumber();
154 for (long i=0; i<no; i++)
155 if ((item = GetChild(i)) != 0)
156 delete item;
157 m_childlist.Clear();
158 m_tree = NULL;
159
160 if ((m_mask & wxTREE_MASK_CHILDREN) != 0)
161 if (m_widget != NULL)
162 if (m_widget->subtree == 0)
163 AddSubtree();
164 }
165
166 int wxTreeItem::NumberOfVisibleDescendents() {
167 wxTreeItem *item;
168 long no = GetChildrenNumber();
169 long num = 0;
170 for (long i=0; i<no; i++)
171 if ((item = GetChild(i)) != 0)
172 num += item->NumberOfVisibleDescendents();
173
174 num+=no;
175
176 return num;
177 }
178
179 wxTreeItem *wxTreeItem::FindItem(long itemId) const {
180 if (m_itemId == itemId) return (wxTreeItem*)(this);
181 wxNode *node = m_childlist.First();
182 while (node) {
183 wxTreeItem *item = (wxTreeItem*)node->Data();
184 wxTreeItem *res = item->FindItem( itemId );
185 if (res) return (wxTreeItem*)(res);
186 node = node->Next();
187 };
188 return NULL;
189 };
190
191 wxTreeItem *wxTreeItem::FindItem(GtkTreeItem *item) const {
192 if (m_widget == item)
193 return (wxTreeItem*)(this);
194 wxNode *node = m_childlist.First();
195 while (node) {
196 wxTreeItem *i = (wxTreeItem*)node->Data();
197 wxTreeItem *res = i->FindItem(item);
198 if (res) return (wxTreeItem*)(res);
199 node = node->Next();
200 };
201 return NULL;
202 };
203
204 void wxTreeItem::PrepareEvent(wxTreeEvent &event) {
205 event.m_item.m_itemId = m_itemId;
206 event.m_item.m_state = m_state;
207 event.m_item.m_text = m_text;
208 event.m_item.m_image = m_image;
209 event.m_item.m_selectedImage = m_selectedImage;
210 event.m_item.m_children = (GetChildrenNumber() > 0);
211 event.m_item.m_data = m_data;
212 event.m_oldItem = 0;
213 event.m_code = 0;
214 // event.m_pointDrag.x = 0;
215 // event.m_pointDrag.y = 0;
216 };
217
218 void wxTreeItem::SendDelete(wxWindow *target) {
219 wxTreeEvent event(wxEVT_COMMAND_TREE_DELETE_ITEM, target->GetId());
220 PrepareEvent(event);
221 event.SetEventObject(target);
222 target->ProcessEvent(event);
223 };
224
225 void wxTreeItem::SendExpand(wxWindow *target) {
226 wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_EXPANDED, target->GetId());
227 PrepareEvent(event);
228 event.SetEventObject(target);
229 target->ProcessEvent(event);
230 };
231
232 void wxTreeItem::SendExpanding(wxWindow *target) {
233 wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_EXPANDING, target->GetId());
234 PrepareEvent(event);
235 event.SetEventObject(target);
236 target->ProcessEvent(event);
237 };
238
239 void wxTreeItem::SendCollapse(wxWindow *target) {
240 wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_COLLAPSED, target->GetId());
241 PrepareEvent(event);
242 event.SetEventObject(target);
243 target->ProcessEvent(event);
244 };
245
246 void wxTreeItem::SendCollapsing(wxWindow *target) {
247 wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_COLLAPSING, target->GetId());
248 PrepareEvent(event);
249 event.SetEventObject(target);
250 target->ProcessEvent(event);
251 };
252
253 void wxTreeItem::SendSelChanged(wxWindow *target) {
254 wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGED, target->GetId());
255 PrepareEvent(event);
256 event.SetEventObject(target);
257 target->ProcessEvent(event);
258 };
259
260 void wxTreeItem::SendSelChanging(wxWindow *target) {
261 wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, target->GetId());
262 PrepareEvent(event);
263 event.SetEventObject(target);
264 target->ProcessEvent(event);
265 };
266
267 //-----------------------------------------------------------------------------
268 // wxTreeCtrl
269 //-----------------------------------------------------------------------------
270
271 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxScrolledWindow)
272
273 wxTreeCtrl::wxTreeCtrl() {
274 m_current = NULL;
275 m_lastId = 0;
276 m_isCreated = FALSE;
277 m_imageList = NULL;
278 m_smallImageList = NULL;
279 };
280
281 wxTreeCtrl::wxTreeCtrl(wxWindow *parent, wxWindowID id,
282 const wxPoint& pos, const wxSize& size,
283 long style, const wxString& name ) {
284 m_current = NULL;
285 m_lastId = 0;
286 m_isCreated = FALSE;
287 m_imageList = NULL;
288 m_smallImageList = NULL;
289 Create( parent, id, pos, size, style, name );
290 };
291
292 wxTreeCtrl::~wxTreeCtrl() {
293 DeleteAllItems();
294 };
295
296 bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id,
297 const wxPoint& pos, const wxSize& size,
298 long style, const wxString& name ) {
299 m_needParent = TRUE;
300
301 PreCreation( parent, id, pos, size, style, name );
302
303 m_widget = gtk_scrolled_window_new(NULL, NULL);
304 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(m_widget),
305 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
306
307 m_tree = GTK_TREE(gtk_tree_new());
308
309 /*
310 gtk_signal_connect( GTK_OBJECT(m_tree), "selection_changed",
311 GTK_SIGNAL_FUNC(gtk_treectrl_selection_changed_callback), (gpointer)this);
312 gtk_signal_connect( GTK_OBJECT(m_tree), "select_child",
313 GTK_SIGNAL_FUNC(gtk_treectrl_select_child_callback), (gpointer)this);
314 gtk_signal_connect( GTK_OBJECT(m_tree), "unselect_child",
315 GTK_SIGNAL_FUNC(gtk_treectrl_unselect_child_callback), (gpointer)this);
316 */
317
318 gtk_container_add(GTK_CONTAINER(m_widget), GTK_WIDGET(m_tree));
319 gtk_widget_show(GTK_WIDGET(m_tree));
320
321 PostCreation();
322
323 gtk_widget_realize(GTK_WIDGET(m_tree));
324
325 Show(TRUE);
326
327 return TRUE;
328 };
329
330 int wxTreeCtrl::GetCount() const
331 {
332 if (!m_anchor) return 0;
333 return m_anchor->NumberOfVisibleDescendents();
334 };
335
336 long wxTreeCtrl::InsertItem(long parent, const wxString& label, long data,
337 int image, int selImage, long insertAfter) {
338 wxTreeItem item;
339 item.m_data = data;
340 if (!label.IsNull() || (label == "")) {
341 item.m_text = label;
342 item.m_mask |= wxTREE_MASK_TEXT;
343 };
344
345 if (image >= 0) {
346 item.m_image = image;
347 item.m_mask |= wxTREE_MASK_IMAGE;
348 };
349
350 if (selImage >= 0) {
351 item.m_selectedImage = selImage;
352 item.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
353 };
354
355 return InsertItem(parent, item, insertAfter);
356 };
357
358 long wxTreeCtrl::InsertItem( long parent, wxTreeItem &info, long WXUNUSED(insertAfter) ) {
359 int oldMask = info.m_mask;
360 long ret = 0;
361 wxTreeItem *p = NULL;
362 wxTreeItem *new_child;
363
364 if (parent == 0) {
365 if (m_anchor)
366 return -1;
367 } else {
368 p = FindItem(parent);
369 if (!p) return -1;
370 };
371
372 if ((info.m_mask & wxTREE_MASK_HANDLE) == 0) {
373 m_lastId++;
374 info.m_itemId = m_lastId;
375 info.m_mask |= wxTREE_MASK_HANDLE;
376 ret = m_lastId;
377 } else
378 ret = info.m_itemId;
379
380 if (p) {
381 if (p->m_tree == NULL)
382 p->AddSubtree();
383
384 new_child = new wxTreeItem(GTK_WIDGET(p->m_tree), info);
385 p->AddChild(new_child);
386 } else {
387 new_child = new wxTreeItem(GTK_WIDGET(m_tree), info);
388 m_anchor = new_child;
389 }
390
391 /* Disabled until wxImageList q solved
392 if ((info.m_mask & wxTREE_MASK_IMAGE) == 0) {
393 wxBitmap *bmp;
394
395 if ((bmp = m_imageList->GetItem(info.m_image))->Ok()) {
396 GdkBitmap *mask = NULL;
397 if (bmp->GetMask()) mask = bmp->GetMask()->GetBitmap();
398 GtkWidget *pixmap = gtk_pixmap_new( bmp->GetPixmap(), mask );
399
400 gtk_widget_set_parent(pixmap, GTK_WIDGET(new_child->m_widget));
401 gtk_widget_show(pixmap);
402 GTK_TREE_ITEM(new_child->m_widget)->pixmaps_box = pixmap;
403 }
404 }
405 */
406
407 new_child->m_owner = this;
408
409 info.m_mask = oldMask;
410 return ret;
411 };
412
413
414 bool wxTreeCtrl::ExpandItem( long item, int action ) {
415 wxTreeItem *i = FindItem( item );
416 if (!i)
417 return FALSE;
418
419 switch (action) {
420 case wxTREE_EXPAND_EXPAND:
421 gtk_tree_item_expand(GTK_TREE_ITEM(i->m_widget));
422 break;
423
424 case wxTREE_EXPAND_COLLAPSE_RESET:
425 case wxTREE_EXPAND_COLLAPSE:
426 gtk_tree_item_collapse(GTK_TREE_ITEM(i->m_widget));
427 break;
428
429 case wxTREE_EXPAND_TOGGLE:
430 if ((i->GetState() & wxTREE_STATE_EXPANDED) == 0)
431 gtk_tree_item_expand(GTK_TREE_ITEM(i->m_widget));
432 else
433 gtk_tree_item_collapse(GTK_TREE_ITEM(i->m_widget));
434 break;
435 }
436
437 return TRUE;
438 };
439
440 void wxTreeCtrl::DeleteItem( long item )
441 {
442 wxTreeItem *pItem = FindItem( item );
443 wxCHECK_RET( pItem != NULL, "wxTreeCtrl::DeleteItem: no such pItem." );
444
445 // pItem->m_parent->m_childlist.DeleteObject(pItem);
446 }
447
448 void wxTreeCtrl::DeleteChildren( long item )
449 {
450 wxTreeItem *pItem = FindItem( item );
451 wxCHECK_RET( pItem != NULL, "wxTreeCtrl::DeleteChildren: no such pItem." );
452
453 pItem->DeleteChildren();
454 }
455
456 bool wxTreeCtrl::DeleteAllItems()
457 {
458 delete m_anchor;
459 m_anchor = NULL;
460 return TRUE;
461 };
462
463 /*
464 bool wxTreeCtrl::GetItem( wxTreeItem &info ) const
465 {
466 wxTreeItem *i = FindItem( info.m_itemId );
467 if (!i) return FALSE;
468 i->GetItem( info );
469 return TRUE;
470 };
471 */
472
473 long wxTreeCtrl::GetItemData( long item ) const
474 {
475 wxTreeItem *i = FindItem( item );
476 if (!i) return 0;
477 return i->m_data;
478 };
479
480 wxString wxTreeCtrl::GetItemText( long item ) const
481 {
482 wxTreeItem *i = FindItem( item );
483 if (!i) return "";
484 return i->m_text;
485 };
486
487 int wxTreeCtrl::GetItemImage(long item) const
488 {
489 wxTreeItem *i = FindItem( item );
490 return i == 0 ? -1 : i->GetImage();
491 }
492
493 long wxTreeCtrl::GetParent( long item ) const
494 {
495 wxTreeItem *i = FindItem( item );
496 if (!i) return -1;
497 /*
498 i = i->m_parent;
499 if (!i) return -1;
500 return i->m_parent->m_itemId;
501 */
502 return -1;
503 };
504
505 long wxTreeCtrl::GetRootItem() const
506 {
507 if (m_anchor) return m_anchor->m_itemId;
508 return -1;
509 };
510
511 /*
512 long wxTreeCtrl::GetSelection() const
513 {
514 return m_current ? m_current->GetItemId() : -1;
515 };
516
517 bool wxTreeCtrl::SelectItem(long itemId)
518 {
519 wxTreeItem *pItem = FindItem(itemId);
520 if ( !pItem ) {
521 wxLogDebug("Can't select an item %d which doesn't exist.", itemId);
522
523 return FALSE;
524 }
525
526 SelectItem(pItem);
527
528 return TRUE;
529 };
530
531 void wxTreeCtrl::SelectItem(wxTreeItem *item, bool bDoEvents )
532 {
533 if (m_current != item)
534 {
535 if (m_current)
536 {
537 m_current->SetHilight( FALSE );
538 // RefreshLine( m_current );
539 };
540 m_current = item;
541 m_current->SetHilight( TRUE );
542 // RefreshLine( m_current );
543
544 if (bDoEvents) m_current->SendSelected( this );
545 }
546 }
547 */
548
549 bool wxTreeCtrl::ItemHasChildren( long item ) const
550 {
551 wxTreeItem *i = FindItem( item );
552 if (!i) return FALSE;
553 return i->HasChildren();
554 };
555
556 void wxTreeCtrl::SetIndent( int indent )
557 {
558 m_indent = indent;
559 Refresh();
560 };
561
562 int wxTreeCtrl::GetIndent() const
563 {
564 return m_indent;
565 };
566
567 /*
568 bool wxTreeCtrl::SetItem( wxTreeItem &info )
569 {
570 wxTreeItem *i = FindItem( info.m_itemId );
571 if (!i) return FALSE;
572 wxClientDC dc(this);
573 i->SetItem( info, &dc );
574 Refresh();
575 return TRUE;
576 };
577
578 bool wxTreeCtrl::SetItemData( long item, long data )
579 {
580 wxTreeItem *i = FindItem( item );
581 if (!i) return FALSE;
582 i->m_data = data;
583 return TRUE;
584 };
585
586 bool wxTreeCtrl::SetItemText( long item, const wxString &text )
587 {
588 wxTreeItem *i = FindItem( item );
589 if (!i) return FALSE;
590 wxClientDC dc(this);
591 i->SetText( text, &dc );
592 return TRUE;
593 };
594
595 void wxTreeCtrl::SetItemImage(long item, int image, int imageSel) const
596 {
597 wxTreeItem *i = FindItem( item );
598 if ( i != 0 ) {
599 i->SetImage(image);
600 i->SetSelectedImage(imageSel);
601 }
602 }
603
604 long wxTreeCtrl::HitTest( const wxPoint& point, int &flags )
605 {
606 flags = 0;
607 if (!m_anchor) return -1;
608 return m_anchor->HitTest( point, flags );
609 };
610 */
611
612 wxImageList *wxTreeCtrl::GetImageList( int which ) const
613 {
614 if (which == wxIMAGE_LIST_NORMAL) return m_imageList;
615 return m_smallImageList;
616 };
617
618 void wxTreeCtrl::SetImageList( wxImageList *imageList, int which )
619 {
620 if (which == wxIMAGE_LIST_NORMAL)
621 {
622 if (m_imageList) delete m_imageList;
623 m_imageList = imageList;
624 }
625 else
626 {
627 if (m_smallImageList) delete m_smallImageList;
628 m_smallImageList = imageList;
629 };
630 };
631
632 wxTreeItem *wxTreeCtrl::FindItem( long itemId ) const {
633 if (!m_anchor) return NULL;
634 return m_anchor->FindItem( itemId );
635 return 0;
636 };
637
638 wxTreeItem *wxTreeCtrl::FindItem(GtkTreeItem *item) const {
639 if (!m_anchor) return NULL;
640 return m_anchor->FindItem(item);
641 return 0;
642 };
643
644 //-----------------------------------------------------------------------------
645 // wxTreeEvent
646 //-----------------------------------------------------------------------------
647
648 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent,wxCommandEvent)
649
650 wxTreeEvent::wxTreeEvent( wxEventType commandType, int id ) :
651 wxCommandEvent( commandType, id )
652 {
653 m_code = 0;
654 m_oldItem = 0;
655 };
656
657 /* Bunch of old code might be useful */
658 /*
659 wxBitmap *bmp;
660
661 if ((bmp = m_imageList->GetItem(0))->Ok()) {
662 GdkBitmap *mask = NULL;
663 if (bmp->GetMask()) mask = bmp->GetMask()->GetBitmap();
664 GtkWidget *pixmap = gtk_pixmap_new( bmp->GetPixmap(), mask );
665
666 gtk_widget_set_parent(pixmap, GTK_WIDGET(new_child->m_widget));
667 gtk_widget_show(pixmap);
668 GTK_TREE_ITEM(new_child->m_widget)->pixmaps_box = pixmap;
669 }
670
671 if ((bmp = m_imageList->GetItem(1))->Ok()) {
672 GdkBitmap *mask = NULL;
673 if (bmp->GetMask()) mask = bmp->GetMask()->GetBitmap();
674 GtkWidget *pixmap = gtk_pixmap_new( bmp->GetPixmap(), mask );
675
676 gtk_widget_set_parent(pixmap, GTK_WIDGET(new_child->m_widget));
677 gtk_widget_show(pixmap);
678 GTK_TREE_ITEM(new_child->m_widget)->plus_pix_widget = pixmap;
679 }
680
681 if ((bmp = m_imageList->GetItem(2))->Ok()) {
682 GdkBitmap *mask = NULL;
683 if (bmp->GetMask()) mask = bmp->GetMask()->GetBitmap();
684 GtkWidget *pixmap = gtk_pixmap_new( bmp->GetPixmap(), mask );
685
686 gtk_widget_set_parent(pixmap, GTK_WIDGET(new_child->m_widget));
687 gtk_widget_show(pixmap);
688 GTK_TREE_ITEM(new_child->m_widget)->minus_pix_widget = pixmap;
689 }
690
691 if (p)
692 if (p->m_childlist.Number() == 1) {
693 gtk_tree_item_collapse(GTK_TREE_ITEM(p->m_widget));
694 gtk_tree_item_expand(GTK_TREE_ITEM(p->m_widget));
695 }
696 */