]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/treemodel.cpp
uncrustify iqmmodel code
[xonotic/netradiant.git] / radiant / treemodel.cpp
1 /*
2    Copyright (C) 2001-2006, William Joseph.
3    All Rights Reserved.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "treemodel.h"
23 #include "globaldefs.h"
24
25 #include "debugging/debugging.h"
26
27 #include <map>
28 #include <gtk/gtk.h>
29 #include <uilib/uilib.h>
30
31 #include "iscenegraph.h"
32 #include "nameable.h"
33
34 #include "generic/callback.h"
35 #include "scenelib.h"
36 #include "string/string.h"
37 #include "generic/reference.h"
38
39 inline Nameable *Node_getNameable(scene::Node &node)
40 {
41     return NodeTypeCast<Nameable>::cast(node);
42 }
43
44 #if 0
45
46 #include "gtkutil/gtktreestore.h"
47
48 template<typename value_type>
49 inline void gtk_tree_model_get_pointer( ui::TreeModel model, GtkTreeIter* iter, gint column, value_type** pointer ){
50     GValue value = GValue_default();
51     gtk_tree_model_get_value( model, iter, column, &value );
52     *pointer = (value_type*)g_value_get_pointer( &value );
53 }
54
55
56 typedef GtkTreeStore GraphTreeModel;
57
58 ui::TreeStore graph_tree_model_new( graph_type* graph ){
59     return gtk_tree_store_new( 2, G_TYPE_POINTER, G_TYPE_POINTER );
60 }
61
62 void graph_tree_model_delete( GraphTreeModel* model ){
63     g_object_unref( G_OBJECT( model ) );
64 }
65
66
67 bool graph_tree_model_subtree_find_node( GraphTreeModel* model, GtkTreeIter* parent, const scene::Node& node, GtkTreeIter* iter ){
68     for ( gboolean success = gtk_tree_model_iter_children( model, iter, parent );
69           success != FALSE;
70           success = gtk_tree_model_iter_next( model, iter ) )
71     {
72         scene::Node* current;
73         gtk_tree_model_get_pointer( model, iter, 0, &current );
74         if ( current == node ) {
75             return true;
76         }
77     }
78     return false;
79 }
80
81 typedef GtkTreeIter DoubleGtkTreeIter[2];
82
83 bool graph_tree_model_find_top( GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter ){
84     int swap = 0;
85     GtkTreeIter* parent_pointer = NULL;
86     GtkTreeIter parent;
87     for ( scene::Path::const_iterator i = path.begin(); i != path.end(); ++i )
88     {
89         if ( !graph_tree_model_subtree_find_node( model, parent_pointer, *i, &iter ) ) {
90             return false;
91         }
92         parent = iter;
93         parent_pointer = &parent;
94     }
95     return true;
96 }
97
98 bool graph_tree_model_find_parent( GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter ){
99     int swap = 0;
100     GtkTreeIter* parent_pointer = NULL;
101     ASSERT_MESSAGE( path.size() > 1, "path too short" );
102     for ( scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i )
103     {
104         GtkTreeIter child;
105         if ( !graph_tree_model_subtree_find_node( model, parent_pointer, *i, &child ) ) {
106             return false;
107         }
108         iter = child;
109         parent_pointer = &iter;
110     }
111     return true;
112 }
113
114 void node_attach_name_changed_callback( scene::Node& node, const Callback<void()>& callback ){
115     if ( node != 0 ) {
116         Nameable* nameable = Node_getNameable( node );
117         if ( nameable != 0 ) {
118             nameable->attach( callback );
119         }
120     }
121 }
122 void node_detach_name_changed_callback( scene::Node& node, const Callback<void()>& callback ){
123     if ( node != 0 ) {
124         Nameable* nameable = Node_getNameable( node );
125         if ( nameable != 0 ) {
126             nameable->detach( callback );
127         }
128     }
129 }
130
131 GraphTreeModel* scene_graph_get_tree_model(); // temp hack
132
133 void graph_tree_model_row_changed( const scene::Instance& instance ){
134     GraphTreeModel* model = scene_graph_get_tree_model();
135
136     GtkTreeIter child;
137     ASSERT_MESSAGE( graph_tree_model_find_top( model, instance.path(), child ), "RUNTIME ERROR" );
138
139     gtk_tree_store_set( GTK_TREE_STORE( model ), &child, 0, instance.path().top(), -1 );
140 }
141
142 void graph_tree_model_row_inserted( GraphTreeModel* model, const scene::Instance& instance ){
143     GtkTreeIter parent;
144     GtkTreeIter* parent_pointer = NULL;
145     if ( instance.path().size() != 1 ) {
146         ASSERT_MESSAGE( graph_tree_model_find_parent( model, instance.path(), parent ), "RUNTIME ERROR" );
147         parent_pointer = &parent;
148     }
149
150     gpointer node = instance.path().top();
151     gconstpointer selectable = Instance_getSelectable( instance );
152
153     GtkTreeIter child;
154     gtk_tree_store_append( GTK_TREE_STORE( model ), &child, parent_pointer );
155     gtk_tree_store_set( GTK_TREE_STORE( model ), &child, 0, node, 1, selectable, -1 );
156
157     node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller<scene::Instance, void(), graph_tree_model_row_changed>( instance ) );
158 }
159
160 void graph_tree_model_row_deleted( GraphTreeModel* model, const scene::Instance& instance ){
161     GtkTreeIter child;
162     ASSERT_MESSAGE( graph_tree_model_find_top( model, instance.path(), child ), "RUNTIME ERROR" );
163
164     node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller<scene::Instance, void(), graph_tree_model_row_changed>( instance ) );
165
166     gtk_tree_store_remove( GTK_TREE_STORE( model ), &child );
167 }
168
169 #elif 0
170
171 const char* node_get_name( scene::Node& node );
172
173 typedef scene::Node* NodePointer;
174
175 class NodeNameLess
176 {
177 public:
178 bool operator()( const NodePointer& self, const NodePointer& other ) const {
179     if ( self == 0 ) {
180         return true;
181     }
182     if ( other == 0 ) {
183         return false;
184     }
185     int result = string_compare( node_get_name( self ), node_get_name( other ) );
186     if ( result == 0 ) {
187         return self < other;
188     }
189     return result < 0;
190 }
191 };
192
193 class PathNameLess
194 {
195 public:
196 bool operator()( const PathConstReference& self, const PathConstReference& other ) const {
197     return std::lexicographical_compare( self.get().begin(), self.get().end(), other.get().begin(), other.get().end(), NodeNameLess() );
198 }
199 };
200
201 typedef std::map<PathConstReference, scene::Instance*, PathNameLess> graph_type;
202
203 struct GraphTreeModel
204 {
205     GObject parent;
206
207     graph_type* graph;
208 };
209
210 struct GraphTreeModelClass
211 {
212     GObjectClass parent_class;
213 };
214
215 #define GRAPH_TREE_MODEL( p ) ( reinterpret_cast<GraphTreeModel*>( p ) )
216
217 static GtkTreeModelFlags graph_tree_model_get_flags( GtkTreeModel* tree_model ){
218     return GTK_TREE_MODEL_ITERS_PERSIST;
219 }
220
221 static gint graph_tree_model_get_n_columns( ui::TreeModel tree_model ){
222     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
223     GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model;
224
225     return 2;
226 }
227
228 static const gint c_stamp = 0xabcdef;
229
230 inline graph_type::iterator graph_iterator_read_tree_iter( GtkTreeIter* iter ){
231     ASSERT_MESSAGE( iter != 0,  "tree model error" );
232     ASSERT_MESSAGE( iter->user_data != 0,  "tree model error" );
233     ASSERT_MESSAGE( iter->stamp == c_stamp,  "tree model error" );
234     return *reinterpret_cast<graph_type::iterator*>( &iter->user_data );
235 }
236
237 inline void graph_iterator_write_tree_iter( graph_type::iterator i, GtkTreeIter* iter ){
238     ASSERT_MESSAGE( iter != 0,  "tree model error" );
239     iter->stamp = c_stamp;
240     *reinterpret_cast<graph_type::iterator*>( &iter->user_data ) = i;
241     ASSERT_MESSAGE( iter->user_data != 0,  "tree model error" );
242 }
243
244 static GType graph_tree_model_get_column_type( ui::TreeModel tree_model, gint index ){
245     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
246     GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model;
247
248     return G_TYPE_POINTER;
249 }
250
251 static gboolean graph_tree_model_get_iter( ui::TreeModel tree_model, GtkTreeIter* iter, ui::TreePath path ){
252     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
253     gint* indices = gtk_tree_path_get_indices( path );
254     gint depth = gtk_tree_path_get_depth( path );
255
256     g_return_val_if_fail( depth > 0, FALSE );
257
258     graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph;
259
260     if ( graph.empty() ) {
261         return FALSE;
262     }
263
264     GtkTreeIter tmp;
265     GtkTreeIter* parent = 0;
266
267     for ( gint i = 0; i < depth; i++ )
268     {
269         if ( !gtk_tree_model_iter_nth_child( tree_model, iter, parent, indices[i] ) ) {
270             return FALSE;
271         }
272         tmp = *iter;
273         parent = &tmp;
274     }
275
276     return TRUE;
277 }
278
279 static ui::TreePath graph_tree_model_get_path( ui::TreeModel tree_model, GtkTreeIter* iter ){
280     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
281     graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph;
282     graph_type::iterator i = graph_iterator_read_tree_iter( iter );
283
284     auto path = ui::TreePath();
285
286     for ( std::size_t depth = ( *i ).first.get().size(); depth != 0; --depth )
287     {
288         std::size_t index = 0;
289
290         while ( i != graph.begin() && ( *i ).first.get().size() >= depth )
291         {
292             --i;
293             if ( ( *i ).first.get().size() == depth ) {
294                 ++index;
295             }
296         }
297
298         gtk_tree_path_prepend_index( path, index );
299     }
300
301     return path;
302 }
303
304
305 static void graph_tree_model_get_value( ui::TreeModel tree_model, GtkTreeIter  *iter, gint column, GValue *value ){
306     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
307     ASSERT_MESSAGE( column == 0 || column == 1, "tree model error" );
308
309     graph_type::iterator i = graph_iterator_read_tree_iter( iter );
310
311     g_value_init( value, G_TYPE_POINTER );
312
313     if ( column == 0 ) {
314         g_value_set_pointer( value, reinterpret_cast<gpointer>( ( *i ).first.get().top() ) );
315     }
316     else{
317         g_value_set_pointer( value, reinterpret_cast<gpointer>( Instance_getSelectable( *( *i ).second ) ) );
318     }
319 }
320
321 static gboolean graph_tree_model_iter_next( ui::TreeModel  tree_model, GtkTreeIter   *iter ){
322     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
323     graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph;
324     graph_type::iterator i = graph_iterator_read_tree_iter( iter );
325     std::size_t depth = ( *i ).first.get().size();
326
327     ++i;
328
329     while ( i != graph.end() && ( *i ).first.get().size() > depth )
330     {
331         ++i;
332     }
333
334     if ( i == graph.end() || ( *i ).first.get().size() != depth ) {
335         return FALSE;
336     }
337
338     graph_iterator_write_tree_iter( i, iter );
339
340     return TRUE;
341 }
342
343 static gboolean graph_tree_model_iter_children( ui::TreeModel tree_model, GtkTreeIter  *iter, GtkTreeIter  *parent ){
344     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
345     graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph;
346     graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent );
347     std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1;
348
349     if ( parent != 0 ) {
350         ++i;
351     }
352
353     if ( i != graph.end() && ( *i ).first.get().size() == depth ) {
354         graph_iterator_write_tree_iter( i, iter );
355         return TRUE;
356     }
357
358     return FALSE;
359 }
360
361 static gboolean graph_tree_model_iter_has_child( ui::TreeModel tree_model, GtkTreeIter  *iter ){
362     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
363     graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph;
364     graph_type::iterator i = graph_iterator_read_tree_iter( iter );
365     std::size_t depth = ( *i ).first.get().size() + 1;
366
367     return ++i != graph.end() && ( *i ).first.get().size() == depth;
368 }
369
370 static gint graph_tree_model_iter_n_children( ui::TreeModel tree_model, GtkTreeIter *parent ){
371     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
372     graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph;
373     graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent );
374     std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1;
375
376     if ( parent != 0 ) {
377         ++i;
378     }
379
380     gint count = 0;
381     while ( i != graph.end() && ( *i ).first.get().size() >= depth )
382     {
383         ++count;
384         ++i;
385     }
386
387     return count;
388 }
389
390 static gboolean graph_tree_model_iter_nth_child( ui::TreeModel tree_model, GtkTreeIter  *iter, GtkTreeIter  *parent, gint n ){
391     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
392     graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph;
393     graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent );
394     std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1;
395
396     if ( parent != 0 ) {
397         ++i;
398     }
399
400     while ( i != graph.end() && ( *i ).first.get().size() >= depth )
401     {
402         if ( ( *i ).first.get().size() == depth && n-- == 0 ) {
403             graph_iterator_write_tree_iter( i, iter );
404             return TRUE;
405         }
406         ++i;
407     }
408
409     return FALSE;
410 }
411
412 static gboolean graph_tree_model_iter_parent( ui::TreeModel tree_model, GtkTreeIter  *iter, GtkTreeIter  *child ){
413     ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" );
414     graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph;
415     graph_type::iterator i = graph_iterator_read_tree_iter( child );
416     std::size_t depth = ( *i ).first.get().size();
417     if ( depth == 1 ) {
418         return FALSE;
419     }
420     else
421     {
422         do
423         {
424             --i;
425         }
426         while ( ( *i ).first.get().size() >= depth );
427         graph_iterator_write_tree_iter( i, iter );
428         return TRUE;
429     }
430 }
431
432 static GObjectClass *g_parent_class = 0;
433
434 static void graph_tree_model_init( GraphTreeModel *graph_tree_model ){
435     graph_tree_model->graph = 0;
436 }
437
438 static void graph_tree_model_finalize( GObject* object ){
439     GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( object );
440
441     /* must chain up */
442     ( *g_parent_class->finalize )( object );
443 }
444
445 static void graph_tree_model_class_init( GraphTreeModelClass *class_ ){
446     GObjectClass *object_class;
447
448     g_parent_class = (GObjectClass*)g_type_class_peek_parent( class_ );
449     object_class = (GObjectClass *) class_;
450
451     object_class->finalize = graph_tree_model_finalize;
452 }
453
454 static void graph_tree_model_tree_model_init( GtkTreeModelIface *iface ){
455     iface->get_flags = graph_tree_model_get_flags;
456     iface->get_n_columns = graph_tree_model_get_n_columns;
457     iface->get_column_type = graph_tree_model_get_column_type;
458     iface->get_iter = graph_tree_model_get_iter;
459     iface->get_path = graph_tree_model_get_path;
460     iface->get_value = graph_tree_model_get_value;
461     iface->iter_next = graph_tree_model_iter_next;
462     iface->iter_children = graph_tree_model_iter_children;
463     iface->iter_has_child = graph_tree_model_iter_has_child;
464     iface->iter_n_children = graph_tree_model_iter_n_children;
465     iface->iter_nth_child = graph_tree_model_iter_nth_child;
466     iface->iter_parent = graph_tree_model_iter_parent;
467 }
468
469 static gboolean graph_tree_model_row_draggable( GtkTreeDragSource *drag_source, ui::TreePath path ){
470 #if GDEF_DEBUG
471     gint depth = gtk_tree_path_get_depth( path );
472 #endif
473     return gtk_tree_path_get_depth( path ) > 1;
474 }
475
476 static gboolean graph_tree_model_drag_data_delete( GtkTreeDragSource *drag_source, ui::TreePath path ){
477     GtkTreeIter iter;
478
479     if ( gtk_tree_model_get_iter( drag_source, &iter, path ) ) {
480         graph_type::iterator i = graph_iterator_read_tree_iter( &iter );
481         Path_deleteTop( ( *i ).first );
482         return TRUE;
483     }
484     else
485     {
486         return FALSE;
487     }
488 }
489
490 static gboolean graph_tree_model_drag_data_get( GtkTreeDragSource *drag_source, ui::TreePath path, GtkSelectionData *selection_data ){
491     if ( gtk_tree_set_row_drag_data( selection_data, drag_source, path ) ) {
492         return TRUE;
493     }
494     else
495     {
496         /* FIXME handle text targets at least. */
497     }
498
499     return FALSE;
500 }
501
502 static void graph_tree_model_drag_source_init( GtkTreeDragSourceIface *iface ){
503     iface->row_draggable = graph_tree_model_row_draggable;
504     iface->drag_data_delete = graph_tree_model_drag_data_delete;
505     iface->drag_data_get = graph_tree_model_drag_data_get;
506 }
507
508 static gboolean graph_tree_model_drag_data_received( GtkTreeDragDest *drag_dest, ui::TreePath dest, GtkSelectionData *selection_data ){
509     auto tree_model = drag_dest;
510
511     GtkTreeModel *src_model = 0;
512     GtkTreePath *src_path = 0;
513     if ( gtk_tree_get_row_drag_data( selection_data, &src_model, &src_path )
514          && src_model == tree_model ) {
515         /* Copy the given row to a new position */
516         GtkTreeIter iter;
517
518         if ( gtk_tree_model_get_iter( src_model, &iter, src_path ) ) {
519             int bleh = 0;
520         }
521     }
522     else
523     {
524         /* FIXME maybe add some data targets eventually, or handle text
525          * targets in the simple case.
526          */
527     }
528
529     return FALSE;
530 }
531
532 static gboolean graph_tree_model_row_drop_possible( GtkTreeDragDest *drag_dest, ui::TreePath dest_path, GtkSelectionData *selection_data ){
533     gboolean retval = FALSE;
534
535     GtkTreeModel *src_model = 0;
536     GtkTreePath *src_path = 0;
537     if ( gtk_tree_get_row_drag_data( selection_data, &src_model, &src_path ) != FALSE ) {
538         /* can only drag to ourselves */
539         if ( src_model == drag_dest ) {
540             /* Can't drop into ourself. */
541             if ( !gtk_tree_path_is_ancestor( src_path, dest_path ) ) {
542                 /* Can't drop if dest_path's parent doesn't exist */
543                 if ( gtk_tree_path_get_depth( dest_path ) > 1 ) {
544                     auto tmp = gtk_tree_path_copy( dest_path );
545                     gtk_tree_path_up( tmp );
546
547                     GtkTreeIter iter;
548                     retval = gtk_tree_model_get_iter( drag_dest, &iter, tmp );
549
550                     gtk_tree_path_free( tmp );
551                 }
552             }
553         }
554
555         gtk_tree_path_free( src_path );
556     }
557
558     return retval;
559 }
560
561 static void graph_tree_model_drag_dest_init( GtkTreeDragDestIface *iface ){
562     iface->drag_data_received = graph_tree_model_drag_data_received;
563     iface->row_drop_possible = graph_tree_model_row_drop_possible;
564 }
565
566 GType graph_tree_model_get_type( void ){
567     static GType graph_tree_model_type = 0;
568
569     if ( !graph_tree_model_type ) {
570         static const GTypeInfo graph_tree_model_info =
571         {
572             sizeof( GraphTreeModelClass ),
573             0, /* base_init */
574             0, /* base_finalize */
575             (GClassInitFunc) graph_tree_model_class_init,
576             0, /* class_finalize */
577             0, /* class_data */
578             sizeof( GraphTreeModel ),
579             0,        /* n_preallocs */
580             (GInstanceInitFunc) graph_tree_model_init
581         };
582
583         static const GInterfaceInfo tree_model_info =
584         {
585             (GInterfaceInitFunc) graph_tree_model_tree_model_init,
586             0,
587             0
588         };
589
590         static const GInterfaceInfo drag_source_info =
591         {
592             (GInterfaceInitFunc) graph_tree_model_drag_source_init,
593             0,
594             0
595         };
596
597         static const GInterfaceInfo drag_dest_info =
598         {
599             (GInterfaceInitFunc) graph_tree_model_drag_dest_init,
600             0,
601             0
602         };
603
604         graph_tree_model_type = g_type_register_static( G_TYPE_OBJECT, "GraphTreeModel",
605                                                         &graph_tree_model_info, (GTypeFlags)0 );
606
607         g_type_add_interface_static( graph_tree_model_type,
608                                      GTK_TYPE_TREE_MODEL,
609                                      &tree_model_info );
610         g_type_add_interface_static( graph_tree_model_type,
611                                      GTK_TYPE_TREE_DRAG_SOURCE,
612                                      &drag_source_info );
613         g_type_add_interface_static( graph_tree_model_type,
614                                      GTK_TYPE_TREE_DRAG_DEST,
615                                      &drag_dest_info );
616     }
617
618     return graph_tree_model_type;
619 }
620
621 GraphTreeModel* graph_tree_model_new(){
622     GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( g_object_new( graph_tree_model_get_type(), 0 ) );
623
624     graph_tree_model->graph = new graph_type;
625
626     return graph_tree_model;
627 }
628
629 void graph_tree_model_delete( GraphTreeModel* model ){
630     delete model->graph;
631     g_object_unref( G_OBJECT( model ) );
632 }
633
634
635 class TempNameable : public Nameable
636 {
637 const char* m_name;
638 public:
639 TempNameable( const char* name ) : m_name( name ){
640 }
641 const char* name() const {
642     return m_name;
643 }
644 void attach( const NameCallback& callback ){
645 }
646 void detach( const NameCallback& callback ){
647 }
648 };
649
650 void node_attach_name_changed_callback( scene::Node& node, const NameCallback& callback ){
651     // Reference cannot be bound to dereferenced null pointer in well-defined
652     // C++ code, and Clang will assume that comparison below always evaluates
653     // to true, resulting in a segmentation fault.  Use a dirty hack to force
654     // Clang to check those "bad" references for null nonetheless.
655     volatile intptr_t n = (intptr_t)&node;
656
657     if ( n != 0 ) {
658         Nameable* nameable = Node_getNameable( node );
659         if ( nameable != 0 ) {
660             nameable->attach( callback );
661         }
662     }
663 }
664 void node_detach_name_changed_callback( scene::Node& node, const NameCallback& callback ){
665     volatile intptr_t n = (intptr_t)&node;  // see the comment on line 650
666
667     if ( n != 0 ) {
668         Nameable* nameable = Node_getNameable( node );
669         if ( nameable != 0 ) {
670             nameable->detach( callback );
671         }
672     }
673 }
674
675 GraphTreeModel* scene_graph_get_tree_model(); // temp hack
676
677 void graph_tree_model_row_inserted( GraphTreeModel* model, graph_type::iterator i ){
678     GtkTreeIter iter;
679     graph_iterator_write_tree_iter( i, &iter );
680
681     auto tree_path = graph_tree_model_get_path( model, &iter );
682
683     gint depth = gtk_tree_path_get_depth( tree_path );
684     gint* indices = gtk_tree_path_get_indices( tree_path );
685
686     gtk_tree_model_row_inserted( model, tree_path, &iter );
687
688     gtk_tree_path_free( tree_path );
689 }
690
691 void graph_tree_model_row_deleted( GraphTreeModel* model, graph_type::iterator i ){
692     GtkTreeIter iter;
693     graph_iterator_write_tree_iter( i, &iter );
694
695     auto tree_path = graph_tree_model_get_path( model, &iter );
696
697     gtk_tree_model_row_deleted( model, tree_path );
698
699     gtk_tree_path_free( tree_path );
700 }
701
702 #include "generic/referencecounted.h"
703
704 void graph_tree_model_set_name( const scene::Instance& instance, const char* name ){
705     GraphTreeModel* model = scene_graph_get_tree_model();
706
707     if ( string_empty( name ) ) { // hack!
708         graph_type::iterator i = model->graph->find( PathConstReference( instance.path() ) );
709         ASSERT_MESSAGE( i != model->graph->end(), "ERROR" );
710
711         graph_tree_model_row_deleted( model, i );
712
713         model->graph->erase( i );
714     }
715     else
716     {
717         graph_type::iterator i = model->graph->insert( graph_type::value_type( PathConstReference( instance.path() ), &const_cast<scene::Instance&>( instance ) ) ).first;
718
719         graph_tree_model_row_inserted( model, i );
720     }
721 }
722
723 void graph_tree_model_insert( GraphTreeModel* model, const scene::Instance& instance ){
724     graph_type::iterator i = model->graph->insert( graph_type::value_type( PathConstReference( instance.path() ), &const_cast<scene::Instance&>( instance ) ) ).first;
725
726     graph_tree_model_row_inserted( model, i );
727
728     node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller<scene::Instance, void(const char*), graph_tree_model_set_name>( instance ) );
729 }
730
731 void graph_tree_model_erase( GraphTreeModel* model, const scene::Instance& instance ){
732     node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller<scene::Instance, void(const char*), graph_tree_model_set_name>( instance ) );
733
734     graph_type::iterator i = model->graph->find( PathConstReference( instance.path() ) );
735     ASSERT_MESSAGE( i != model->graph->end(), "ERROR" );
736
737     graph_tree_model_row_deleted( model, i );
738
739     model->graph->erase( i );
740 }
741
742 #elif 1
743
744 class GraphTreeNode;
745
746 void graph_tree_model_row_changed(GraphTreeNode &node);
747
748 class GraphTreeNode {
749     typedef std::map<std::pair<CopiedString, scene::Node *>, GraphTreeNode *> ChildNodes;
750     ChildNodes m_childnodes;
751 public:
752     Reference<scene::Instance> m_instance;
753     GraphTreeNode *m_parent;
754
755     typedef ChildNodes::iterator iterator;
756     typedef ChildNodes::key_type key_type;
757     typedef ChildNodes::value_type value_type;
758     typedef ChildNodes::size_type size_type;
759
760     GraphTreeNode(scene::Instance &instance) : m_instance(instance), m_parent(0)
761     {
762         m_instance.get().setChildSelectedChangedCallback(RowChangedCaller(*this));
763     }
764
765     ~GraphTreeNode()
766     {
767         m_instance.get().setChildSelectedChangedCallback(Callback<void()>());
768         ASSERT_MESSAGE(empty(), "GraphTreeNode::~GraphTreeNode: memory leak");
769     }
770
771     iterator begin()
772     {
773         return m_childnodes.begin();
774     }
775
776     iterator end()
777     {
778         return m_childnodes.end();
779     }
780
781     size_type size() const
782     {
783         return m_childnodes.size();
784     }
785
786     bool empty() const
787     {
788         return m_childnodes.empty();
789     }
790
791     iterator insert(const value_type &value)
792     {
793         iterator i = m_childnodes.insert(value).first;
794         (*i).second->m_parent = this;
795         return i;
796     }
797
798     void erase(iterator i)
799     {
800         m_childnodes.erase(i);
801     }
802
803     iterator find(const key_type &key)
804     {
805         return m_childnodes.find(key);
806     }
807
808     void swap(GraphTreeNode &other)
809     {
810         std::swap(m_parent, other.m_parent);
811         std::swap(m_childnodes, other.m_childnodes);
812         std::swap(m_instance, other.m_instance);
813     }
814
815     void rowChanged()
816     {
817         graph_tree_model_row_changed(*this);
818     }
819
820     typedef MemberCaller<GraphTreeNode, void(), &GraphTreeNode::rowChanged> RowChangedCaller;
821 };
822
823 struct GraphTreeModel {
824     GObject parent;
825
826     GraphTreeNode *m_graph;
827 };
828
829 struct GraphTreeModelClass {
830     GObjectClass parent_class;
831 };
832
833 static GtkTreeModelFlags graph_tree_model_get_flags(ui::TreeModel tree_model)
834 {
835     return GTK_TREE_MODEL_ITERS_PERSIST;
836 }
837
838 static gint graph_tree_model_get_n_columns(ui::TreeModel tree_model)
839 {
840     ASSERT_MESSAGE(tree_model, "RUNTIME ERROR");
841     //GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model;
842
843     return 2;
844 }
845
846 static const gint c_stamp = 0xabcdef;
847
848 inline GraphTreeNode::iterator graph_iterator_read_tree_iter(GtkTreeIter *iter)
849 {
850     ASSERT_MESSAGE(iter != 0, "tree model error");
851     ASSERT_MESSAGE(iter->user_data != 0, "tree model error");
852     ASSERT_MESSAGE(iter->stamp == c_stamp, "tree model error");
853     return *reinterpret_cast<GraphTreeNode::iterator *>( &iter->user_data );
854 }
855
856 inline void graph_iterator_write_tree_iter(GraphTreeNode::iterator i, GtkTreeIter *iter)
857 {
858     ASSERT_MESSAGE(iter != 0, "tree model error");
859     iter->stamp = c_stamp;
860     *reinterpret_cast<GraphTreeNode::iterator *>( &iter->user_data ) = i;
861     ASSERT_MESSAGE(iter->user_data != 0, "tree model error");
862 }
863
864 static GType graph_tree_model_get_column_type(ui::TreeModel tree_model, gint index)
865 {
866     ASSERT_MESSAGE(tree_model, "RUNTIME ERROR");
867     //GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model;
868
869     return G_TYPE_POINTER;
870 }
871
872 static gboolean graph_tree_model_get_iter(GraphTreeModel *tree_model, GtkTreeIter *iter, ui::TreePath path)
873 {
874     ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
875     gint *indices = gtk_tree_path_get_indices(path);
876     gint depth = gtk_tree_path_get_depth(path);
877
878     g_return_val_if_fail(depth > 0, FALSE);
879
880     GraphTreeNode *graph = tree_model->m_graph;
881
882     if (graph->empty()) {
883         return FALSE;
884     }
885
886     GtkTreeIter tmp;
887     GtkTreeIter *parent = 0;
888
889     for (gint i = 0; i < depth; i++) {
890         if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(tree_model), iter, parent, indices[i])) {
891             return FALSE;
892         }
893         tmp = *iter;
894         parent = &tmp;
895     }
896
897     return TRUE;
898 }
899
900 static ui::TreePath graph_tree_model_get_path(GraphTreeModel *tree_model, GtkTreeIter *iter)
901 {
902     ASSERT_MESSAGE(tree_model, "RUNTIME ERROR");
903     GraphTreeNode *graph = tree_model->m_graph;
904
905     auto path = ui::TreePath(ui::New);
906
907     for (GraphTreeNode *node = (*graph_iterator_read_tree_iter(iter)).second; node != graph; node = node->m_parent) {
908         std::size_t index = 0;
909         for (GraphTreeNode::iterator i = node->m_parent->begin(); i != node->m_parent->end(); ++i, ++index) {
910             if ((*i).second == node) {
911                 gtk_tree_path_prepend_index(path, gint(index));
912                 break;
913             }
914         }
915         ASSERT_MESSAGE(index != node->m_parent->size(), "error resolving tree path");
916     }
917
918     return path;
919 }
920
921
922 static void graph_tree_model_get_value(ui::TreeModel tree_model, GtkTreeIter *iter, gint column, GValue *value)
923 {
924     ASSERT_MESSAGE(tree_model, "RUNTIME ERROR");
925     ASSERT_MESSAGE(column == 0 || column == 1, "tree model error");
926
927     GraphTreeNode::iterator i = graph_iterator_read_tree_iter(iter);
928
929     g_value_init(value, G_TYPE_POINTER);
930
931     if (column == 0) {
932         g_value_set_pointer(value, reinterpret_cast<gpointer>((*i).first.second ));
933     } else {
934         g_value_set_pointer(value, reinterpret_cast<gpointer>( &(*i).second->m_instance.get()));
935     }
936 }
937
938 static gboolean graph_tree_model_iter_next(ui::TreeModel tree_model, GtkTreeIter *iter)
939 {
940     ASSERT_MESSAGE(tree_model, "RUNTIME ERROR");
941     GraphTreeNode::iterator i = graph_iterator_read_tree_iter(iter);
942     GraphTreeNode &parent = *(*i).second->m_parent;
943
944     ASSERT_MESSAGE(i != parent.end(), "RUNTIME ERROR");
945
946     if (++i == parent.end()) {
947         return FALSE;
948     }
949
950     graph_iterator_write_tree_iter(i, iter);
951
952     return TRUE;
953 }
954
955 static gboolean graph_tree_model_iter_children(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
956 {
957     ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
958     GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second;
959     if (!node.empty()) {
960         graph_iterator_write_tree_iter(node.begin(), iter);
961         return TRUE;
962     }
963
964     return FALSE;
965 }
966
967 static gboolean graph_tree_model_iter_has_child(ui::TreeModel tree_model, GtkTreeIter *iter)
968 {
969     ASSERT_MESSAGE(tree_model, "RUNTIME ERROR");
970     GraphTreeNode &node = *(*graph_iterator_read_tree_iter(iter)).second;
971     return !node.empty();
972 }
973
974 static gint graph_tree_model_iter_n_children(GraphTreeModel *tree_model, GtkTreeIter *parent)
975 {
976     ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
977     GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second;
978     return static_cast<gint>( node.size());
979 }
980
981 static gboolean
982 graph_tree_model_iter_nth_child(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
983 {
984     ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
985     GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second;
986     if (static_cast<std::size_t>( n ) < node.size()) {
987         GraphTreeNode::iterator i = node.begin();
988         std::advance(i, n);
989         graph_iterator_write_tree_iter(i, iter);
990         return TRUE;
991     }
992
993     return FALSE;
994 }
995
996 static gboolean graph_tree_model_iter_parent(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
997 {
998     ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
999     GraphTreeNode &node = *(*graph_iterator_read_tree_iter(child)).second;
1000     if (node.m_parent != tree_model->m_graph) {
1001         GraphTreeNode &parentParent = *node.m_parent->m_parent;
1002         for (GraphTreeNode::iterator i = parentParent.begin(); i != parentParent.end(); ++i) {
1003             if ((*i).second == node.m_parent) {
1004                 graph_iterator_write_tree_iter(i, iter);
1005                 return TRUE;
1006             }
1007         }
1008     }
1009     return FALSE;
1010 }
1011
1012 static GObjectClass *g_parent_class = 0;
1013
1014 namespace {
1015     scene::Node *g_null_node = 0;
1016 }
1017
1018 class NullInstance : public scene::Instance {
1019 public:
1020     NullInstance() : scene::Instance(scene::Path(makeReference(*g_null_node)), 0, 0,
1021                                      Static<InstanceTypeCastTable>::instance())
1022     {
1023     }
1024 };
1025
1026 namespace {
1027     NullInstance g_null_instance;
1028 }
1029
1030 static void graph_tree_model_init(GraphTreeModel *graph_tree_model)
1031 {
1032     graph_tree_model->m_graph = new GraphTreeNode(g_null_instance);
1033 }
1034
1035 static void graph_tree_model_finalize(GObject *object)
1036 {
1037     auto graph_tree_model = reinterpret_cast<GraphTreeModel *>(object);
1038
1039     delete graph_tree_model->m_graph;
1040
1041     /* must chain up */
1042     (*g_parent_class->finalize)(object);
1043 }
1044
1045 static void graph_tree_model_class_init(GraphTreeModelClass *class_)
1046 {
1047     GObjectClass *object_class;
1048
1049     g_parent_class = (GObjectClass *) g_type_class_peek_parent(class_);
1050     object_class = (GObjectClass *) class_;
1051
1052     object_class->finalize = graph_tree_model_finalize;
1053 }
1054
1055 static void graph_tree_model_tree_model_init(GtkTreeModelIface *iface)
1056 {
1057     iface->get_flags = reinterpret_cast<GtkTreeModelFlags (*)(GtkTreeModel *)>(graph_tree_model_get_flags);
1058     iface->get_n_columns = reinterpret_cast<gint (*)(GtkTreeModel *)>(graph_tree_model_get_n_columns);
1059     iface->get_column_type = reinterpret_cast<GType (*)(GtkTreeModel *, gint)>(graph_tree_model_get_column_type);
1060     iface->get_iter = reinterpret_cast<gboolean (*)(GtkTreeModel *, GtkTreeIter *,
1061                                                     GtkTreePath *)>(graph_tree_model_get_iter);
1062     iface->get_path = reinterpret_cast<GtkTreePath *(*)(GtkTreeModel *, GtkTreeIter *)>(graph_tree_model_get_path);
1063     iface->get_value = reinterpret_cast<void (*)(GtkTreeModel *, GtkTreeIter *, gint,
1064                                                  GValue *)>(graph_tree_model_get_value);
1065     iface->iter_next = reinterpret_cast<gboolean (*)(GtkTreeModel *, GtkTreeIter *)>(graph_tree_model_iter_next);
1066     iface->iter_children = reinterpret_cast<gboolean (*)(GtkTreeModel *, GtkTreeIter *,
1067                                                          GtkTreeIter *)>(graph_tree_model_iter_children);
1068     iface->iter_has_child = reinterpret_cast<gboolean (*)(GtkTreeModel *,
1069                                                           GtkTreeIter *)>(graph_tree_model_iter_has_child);
1070     iface->iter_n_children = reinterpret_cast<gint (*)(GtkTreeModel *,
1071                                                        GtkTreeIter *)>(graph_tree_model_iter_n_children);
1072     iface->iter_nth_child = reinterpret_cast<gboolean (*)(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *,
1073                                                           gint)>(graph_tree_model_iter_nth_child);
1074     iface->iter_parent = reinterpret_cast<gboolean (*)(GtkTreeModel *, GtkTreeIter *,
1075                                                        GtkTreeIter *)>(graph_tree_model_iter_parent);
1076 }
1077
1078 GType graph_tree_model_get_type(void)
1079 {
1080     static GType graph_tree_model_type = 0;
1081
1082     if (!graph_tree_model_type) {
1083         static const GTypeInfo graph_tree_model_info =
1084                 {
1085                         sizeof(GraphTreeModelClass),
1086                         0, /* base_init */
1087                         0, /* base_finalize */
1088                         (GClassInitFunc) graph_tree_model_class_init,
1089                         0, /* class_finalize */
1090                         0, /* class_data */
1091                         sizeof(GraphTreeModel),
1092                         0,        /* n_preallocs */
1093                         (GInstanceInitFunc) graph_tree_model_init,
1094                         0
1095                 };
1096
1097         static const GInterfaceInfo tree_model_info =
1098                 {
1099                         (GInterfaceInitFunc) graph_tree_model_tree_model_init,
1100                         0,
1101                         0
1102                 };
1103
1104         graph_tree_model_type = g_type_register_static(G_TYPE_OBJECT, "GraphTreeModel",
1105                                                        &graph_tree_model_info, (GTypeFlags) 0);
1106
1107         g_type_add_interface_static(graph_tree_model_type,
1108                                     GTK_TYPE_TREE_MODEL,
1109                                     &tree_model_info);
1110     }
1111
1112     return graph_tree_model_type;
1113 }
1114
1115 GraphTreeModel *graph_tree_model_new()
1116 {
1117     auto graph_tree_model = reinterpret_cast<GraphTreeModel *>(g_object_new(graph_tree_model_get_type(), 0));
1118
1119     return graph_tree_model;
1120 }
1121
1122 void graph_tree_model_delete(GraphTreeModel *model)
1123 {
1124     g_object_unref(G_OBJECT(model));
1125 }
1126
1127 void graph_tree_model_row_changed(GraphTreeModel *model, GraphTreeNode::iterator i)
1128 {
1129     GtkTreeIter iter;
1130     graph_iterator_write_tree_iter(i, &iter);
1131
1132     auto tree_path = graph_tree_model_get_path(model, &iter);
1133
1134     gtk_tree_model_row_changed(GTK_TREE_MODEL(model), tree_path, &iter);
1135
1136     gtk_tree_path_free(tree_path);
1137 }
1138
1139 void graph_tree_model_row_inserted(GraphTreeModel *model, GraphTreeNode::iterator i)
1140 {
1141     GtkTreeIter iter;
1142     graph_iterator_write_tree_iter(i, &iter);
1143
1144     auto tree_path = graph_tree_model_get_path(model, &iter);
1145
1146     gtk_tree_model_row_inserted(GTK_TREE_MODEL(model), tree_path, &iter);
1147
1148     gtk_tree_path_free(tree_path);
1149 }
1150
1151 void graph_tree_model_row_deleted(GraphTreeModel *model, GraphTreeNode::iterator i)
1152 {
1153     GtkTreeIter iter;
1154     graph_iterator_write_tree_iter(i, &iter);
1155
1156     auto tree_path = graph_tree_model_get_path(model, &iter);
1157
1158     gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), tree_path);
1159
1160     gtk_tree_path_free(tree_path);
1161 }
1162
1163 void graph_tree_model_row_inserted(GraphTreeModel &model, GraphTreeNode::iterator i)
1164 {
1165     graph_tree_model_row_inserted(&model, i);
1166 }
1167
1168 void graph_tree_model_row_deleted(GraphTreeModel &model, GraphTreeNode::iterator i)
1169 {
1170     graph_tree_model_row_deleted(&model, i);
1171 }
1172
1173 const char *node_get_name(scene::Node &node);
1174
1175 const char *node_get_name_safe(scene::Node &node)
1176 {
1177     volatile intptr_t n = (intptr_t) &node;  // see the comment on line 650
1178     if (n == 0) {
1179         return "";
1180     }
1181     return node_get_name(node);
1182 }
1183
1184 GraphTreeNode *graph_tree_model_find_parent(GraphTreeModel *model, const scene::Path &path)
1185 {
1186     GraphTreeNode *parent = model->m_graph;
1187     for (scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i) {
1188         GraphTreeNode::iterator child = parent->find(
1189                 GraphTreeNode::key_type(node_get_name_safe((*i).get()), (*i).get_pointer()));
1190         ASSERT_MESSAGE(child != parent->end(), "ERROR");
1191         parent = (*child).second;
1192     }
1193     return parent;
1194 }
1195
1196 void node_attach_name_changed_callback(scene::Node &node, const NameCallback &callback)
1197 {
1198     volatile intptr_t n = (intptr_t) &node;  // see the comment on line 650
1199     if (n != 0) {
1200         Nameable *nameable = Node_getNameable(node);
1201         if (nameable != 0) {
1202             nameable->attach(callback);
1203         }
1204     }
1205 }
1206
1207 void node_detach_name_changed_callback(scene::Node &node, const NameCallback &callback)
1208 {
1209     volatile intptr_t n = (intptr_t) &node;  // see the comment on line 650
1210     if (n != 0) {
1211         Nameable *nameable = Node_getNameable(node);
1212         if (nameable != 0) {
1213             nameable->detach(callback);
1214         }
1215     }
1216 }
1217
1218 GraphTreeModel *scene_graph_get_tree_model(); // temp hack
1219
1220 void graph_tree_node_foreach_pre(GraphTreeNode::iterator root, const Callback<void(GraphTreeNode::iterator)> &callback)
1221 {
1222     callback(root);
1223     for (GraphTreeNode::iterator i = (*root).second->begin(); i != (*root).second->end(); ++i) {
1224         graph_tree_node_foreach_pre(i, callback);
1225     }
1226 }
1227
1228 void graph_tree_node_foreach_post(GraphTreeNode::iterator root, const Callback<void(GraphTreeNode::iterator)> &callback)
1229 {
1230     for (GraphTreeNode::iterator i = (*root).second->begin(); i != (*root).second->end(); ++i) {
1231         graph_tree_node_foreach_post(i, callback);
1232     }
1233     callback(root);
1234 }
1235
1236 void graph_tree_model_row_changed(GraphTreeNode &node)
1237 {
1238     GraphTreeModel *model = scene_graph_get_tree_model();
1239     const scene::Instance &instance = node.m_instance.get();
1240
1241     GraphTreeNode::iterator i = node.m_parent->find(
1242             GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()),
1243                                     instance.path().top().get_pointer()));
1244
1245     graph_tree_model_row_changed(model, i);
1246 }
1247
1248 void graph_tree_model_set_name(const scene::Instance &instance, const char *name)
1249 {
1250     GraphTreeModel *model = scene_graph_get_tree_model();
1251     GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path());
1252
1253     GraphTreeNode::iterator oldNode = parent->find(
1254             GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()),
1255                                     instance.path().top().get_pointer()));
1256     graph_tree_node_foreach_post(oldNode, ReferenceCaller<GraphTreeModel, void(
1257             GraphTreeNode::iterator), graph_tree_model_row_deleted>(*model));
1258     GraphTreeNode *node((*oldNode).second);
1259     parent->erase(oldNode);
1260
1261     GraphTreeNode::iterator newNode = parent->insert(
1262             GraphTreeNode::value_type(GraphTreeNode::key_type(name, &instance.path().top().get()), node));
1263     graph_tree_node_foreach_pre(newNode, ReferenceCaller<GraphTreeModel, void(
1264             GraphTreeNode::iterator), graph_tree_model_row_inserted>(*model));
1265 }
1266
1267 void graph_tree_model_insert(GraphTreeModel *model, const scene::Instance &instance)
1268 {
1269     GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path());
1270
1271     GraphTreeNode::iterator i = parent->insert(GraphTreeNode::value_type(
1272             GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()),
1273                                     instance.path().top().get_pointer()),
1274             new GraphTreeNode(const_cast<scene::Instance &>( instance ))));
1275
1276     graph_tree_model_row_inserted(model, i);
1277
1278     node_attach_name_changed_callback(instance.path().top(), ConstReferenceCaller<scene::Instance, void(
1279             const char *), graph_tree_model_set_name>(instance));
1280 }
1281
1282 void graph_tree_model_erase(GraphTreeModel *model, const scene::Instance &instance)
1283 {
1284     node_detach_name_changed_callback(instance.path().top(), ConstReferenceCaller<scene::Instance, void(
1285             const char *), graph_tree_model_set_name>(instance));
1286
1287     GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path());
1288
1289     GraphTreeNode::iterator i = parent->find(GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()),
1290                                                                      instance.path().top().get_pointer()));
1291
1292     graph_tree_model_row_deleted(model, i);
1293
1294     GraphTreeNode *node((*i).second);
1295     parent->erase(i);
1296     delete node;
1297 }
1298
1299
1300 #endif
1301
1302
1303 #if 0
1304 class TestGraphTreeModel
1305 {
1306 public:
1307 TestGraphTreeModel(){
1308     gtk_init( 0, 0 );
1309
1310     graph_type graph;
1311
1312     scene::Node* root = *(scene::Node*)0xa0000000;
1313     scene::Node* node1 = (scene::Node*)0xa0000001;
1314     scene::Node* node2 = (scene::Node*)0xa0000002;
1315     scene::Node* node3 = (scene::Node*)0xa0000003;
1316     scene::Node* node4 = (scene::Node*)0xa0000004;
1317     scene::Instance* instance = (scene::Instance*)0xaaaaaaaa;
1318
1319     scene::Path rootpath( root );
1320
1321     graph.insert( graph_type::value_type( rootpath, instance ) );
1322
1323     rootpath.push( node1 );
1324     graph.insert( graph_type::value_type( rootpath, instance ) );
1325     rootpath.pop();
1326
1327     rootpath.push( node2 );
1328     graph.insert( graph_type::value_type( rootpath, instance ) );
1329     rootpath.push( node3 );
1330     graph.insert( graph_type::value_type( rootpath, instance ) );
1331     rootpath.pop();
1332     rootpath.push( node4 );
1333     graph.insert( graph_type::value_type( rootpath, instance ) );
1334     rootpath.pop();
1335     rootpath.pop();
1336
1337     auto model = graph_tree_model_new( &graph );
1338
1339     {
1340         gint n_columns = gtk_tree_model_get_n_columns( model );
1341         ASSERT_MESSAGE( n_columns == 2, "test failed!" );
1342     }
1343
1344     {
1345         GType type = gtk_tree_model_get_column_type( model, 0 );
1346         ASSERT_MESSAGE( type == G_TYPE_POINTER, "test failed!" );
1347     }
1348
1349     {
1350         GType type = gtk_tree_model_get_column_type( model, 1 );
1351         ASSERT_MESSAGE( type == G_TYPE_POINTER, "test failed!" );
1352     }
1353
1354
1355     {
1356         GtkTreeIter iter;
1357         gtk_tree_model_get_iter_first( model, &iter );
1358
1359         graph_type::iterator i = graph_iterator_read_tree_iter( &iter );
1360         ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node1, "test failed!" );
1361     }
1362
1363     {
1364         GtkTreeIter iter;
1365         gtk_tree_model_get_iter_first( model, &iter );
1366
1367         ASSERT_MESSAGE( gtk_tree_model_iter_has_child( model, &iter ) == FALSE, "test failed!" );
1368
1369         ASSERT_MESSAGE( gtk_tree_model_iter_n_children( model, &iter ) == 0, "test failed!" );
1370
1371         gtk_tree_model_iter_next( model, &iter );
1372
1373         ASSERT_MESSAGE( gtk_tree_model_iter_has_child( model, &iter ) != FALSE, "test failed!" );
1374
1375         ASSERT_MESSAGE( gtk_tree_model_iter_n_children( model, &iter ) == 2, "test failed!" );
1376
1377         {
1378             GtkTreeIter child;
1379             gtk_tree_model_iter_nth_child( model, &child, &iter, 0 );
1380
1381             scene::Node* test;
1382             gtk_tree_model_get_value( model, &child, 0, (GValue*)&test );
1383             ASSERT_MESSAGE( test == node3, "test failed!" );
1384
1385             {
1386                 GtkTreeIter parent;
1387                 gtk_tree_model_iter_parent( model, &parent, &child );
1388
1389                 scene::Node* test;
1390                 gtk_tree_model_get_value( model, &parent, 0, (GValue*)&test );
1391                 ASSERT_MESSAGE( test == node2, "test failed!" );
1392             }
1393         }
1394
1395         {
1396             GtkTreeIter child;
1397             gtk_tree_model_iter_nth_child( model, &child, &iter, 1 );
1398
1399             scene::Node* test;
1400             gtk_tree_model_get_value( model, &child, 0, (GValue*)&test );
1401             ASSERT_MESSAGE( test == node4, "test failed!" );
1402         }
1403     }
1404
1405     {
1406         GtkTreeIter iter;
1407         std::size_t count = 0;
1408         for ( gboolean good = gtk_tree_model_get_iter_first( model, &iter ); good; good = gtk_tree_model_iter_next( model, &iter ) )
1409         {
1410             scene::Node* test;
1411             gtk_tree_model_get_value( model, &iter, 0, (GValue*)&test );
1412
1413             ASSERT_MESSAGE( ( count == 0 && test == node1 ) || ( count == 1 && test == node2 ), "test failed!" );
1414             ++count;
1415         }
1416
1417         ASSERT_MESSAGE( count == 2, "test failed!" );
1418
1419     }
1420
1421     {
1422         GtkTreeIter iter;
1423         gtk_tree_model_get_iter_first( model, &iter );
1424
1425         scene::Node* test;
1426         gtk_tree_model_get_value( model, &iter, 0, (GValue*)&test );
1427         ASSERT_MESSAGE( test == node1, "test failed!" );
1428     }
1429
1430     {
1431         GtkTreeIter iter;
1432         auto path = ui::TreePath( "0" );
1433         gtk_tree_model_get_iter( model, &iter, path );
1434         gtk_tree_path_free( path );
1435
1436         graph_type::iterator i = graph_iterator_read_tree_iter( &iter );
1437         ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node1, "test failed!" );
1438     }
1439
1440     {
1441         GtkTreeIter iter;
1442         auto path = ui::TreePath( "1" );
1443         gtk_tree_model_get_iter( model, &iter, path );
1444         gtk_tree_path_free( path );
1445
1446         graph_type::iterator i = graph_iterator_read_tree_iter( &iter );
1447         ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node2, "test failed!" );
1448     }
1449
1450     {
1451         GtkTreeIter iter;
1452         graph_type::iterator i = graph.begin();
1453         ++i;
1454         graph_iterator_write_tree_iter( i, &iter );
1455
1456         auto path = gtk_tree_model_get_path( model, &iter );
1457
1458         gint depth = gtk_tree_path_get_depth( path );
1459         gint* indices = gtk_tree_path_get_indices( path );
1460
1461         ASSERT_MESSAGE( depth == 1 && indices[0] == 0, "test failed!" );
1462
1463         gtk_tree_path_free( path );
1464     }
1465
1466     {
1467         GtkTreeIter iter;
1468         graph_type::iterator i = graph.begin();
1469         ++i;
1470         ++i;
1471         graph_iterator_write_tree_iter( i, &iter );
1472
1473         auto path = gtk_tree_model_get_path( model, &iter );
1474
1475         gint depth = gtk_tree_path_get_depth( path );
1476         gint* indices = gtk_tree_path_get_indices( path );
1477
1478         ASSERT_MESSAGE( depth == 1 && indices[0] == 1, "test failed!" );
1479
1480         gtk_tree_path_free( path );
1481     }
1482 }
1483 };
1484
1485
1486 TestGraphTreeModel g_TestGraphTreeModel;
1487
1488 #endif