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