2009-12-07 Rolf Bjarne Kvinge <RKvinge@novell.com>
[moon.git] / plugin / plugin-debug.cpp
blob74274d7b2687990d57d1950cda1771b0e43a99f9
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * plugin-debug.cpp:
5 * Contact:
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2008 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
13 #include <config.h>
15 #include <gtk/gtkmessagedialog.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <errno.h>
23 #include "plugin-debug.h"
24 #include "utils.h"
25 #include "uri.h"
26 #include "grid.h"
28 enum TreeColumns {
29 COL_NAME,
30 COL_TYPE_NAME,
31 COL_VALUE,
32 COL_ELEMENT_PTR,
33 NUM_COLUMNS
36 #ifdef DEBUG
38 static void reflect_dependency_object_in_tree (DependencyObject *obj, GtkTreeStore *store,
39 GtkTreeIter *node, bool node_is_self);
41 struct AddNamescopeItemData {
42 GtkTreeStore *store;
43 GtkTreeIter *node;
45 AddNamescopeItemData (GtkTreeStore *store, GtkTreeIter *node)
47 this->store = store;
48 this->node = node;
52 static void
53 add_namescope_item (gpointer key, gpointer value, gpointer user_data);
55 static char *
56 timespan_to_str (TimeSpan ts)
58 bool negative;
59 int days;
60 int hours;
61 int minutes;
62 double seconds;
64 double ts_frac = (double)ts;
66 negative = (ts < 0);
68 ts_frac /= 10000000.0;
70 days = (int)(ts_frac / 86400);
71 ts_frac -= days * 86400;
72 hours = (int)(ts_frac / 3600);
73 ts_frac -= hours * 3600;
74 minutes = (int)(ts_frac / 60);
75 ts_frac -= minutes * 60;
76 seconds = ts_frac;
78 // XXX someone who can remember printf specifiers should
79 // remove that %s from in there in such a way that we get a
80 // float zero padded to 2 spaces to the left of the decimal.
81 return g_strdup_printf ("%02d:%02d:%02d:%s%.4f", days, hours, minutes, seconds < 10.0 ? "0" : "", seconds);
84 static void
85 reflect_value (GtkTreeStore *store, GtkTreeIter *node, const char *name, const char *type_name, Value *value)
87 DependencyObject *dobj;
88 const char *str = NULL;
89 char *buf = NULL;
90 Deployment *deployment = Deployment::GetCurrent ();
92 if (value && value->Is (deployment, Type::DEPENDENCY_OBJECT)) {
93 dobj = value->AsDependencyObject ();
95 gtk_tree_store_set (store, node,
96 COL_NAME, name,
97 COL_TYPE_NAME, dobj ? dobj->GetTypeName () : "null",
98 COL_VALUE, "",
99 COL_ELEMENT_PTR, NULL,
100 -1);
102 if (dobj)
103 reflect_dependency_object_in_tree (dobj, store, node, true);
104 return;
107 if (value != NULL) {
108 Type *type = Type::Find (deployment, value->GetKind ());
109 type_name = type->GetName ();
111 switch (value->GetKind()) {
112 case Type::DOUBLE:
113 str = buf = g_strdup_printf ("<b>%g</b>", value->AsDouble ());
114 break;
115 case Type::INT32:
116 str = buf = g_strdup_printf ("<b>%d</b>", value->AsInt32 ());
117 break;
118 case Type::INT64:
119 str = buf = g_strdup_printf ("<b>%lld</b>", (long long int) value->AsInt64 ());
120 break;
121 case Type::TIMESPAN: {
122 char *ts_string = timespan_to_str (value->AsTimeSpan());
123 str = buf = g_strdup_printf ("<b>%s</b>", ts_string);
124 g_free (ts_string);
125 break;
127 case Type::UINT64:
128 str = buf = g_strdup_printf ("<b>%llu</b>", (unsigned long long int) value->AsUInt64 ());
129 break;
130 case Type::STRING:
131 str = buf = g_strdup_printf ("<b>%s</b>", value->AsString ());
132 break;
133 case Type::RECT: {
134 Rect *rect = value->AsRect();
135 str = buf = g_strdup_printf ("<b>%g, %g, %g, %g</b>", rect->x, rect->y, rect->width, rect->height);
136 break;
138 case Type::SIZE:
139 str = buf = g_strdup_printf ("<b>%g, %g</b>", value->AsSize()->width, value->AsSize()->height);
140 break;
141 case Type::REPEATBEHAVIOR: {
142 RepeatBehavior *rb = value->AsRepeatBehavior();
143 if (rb->IsForever ())
144 str = "<b>Forever</b>";
145 else if (rb->HasCount())
146 str = buf = g_strdup_printf ("<b>%gx</b>", rb->GetCount());
147 else /*if (rb->HasDuration())*/ {
148 char *ts_string = timespan_to_str (rb->GetDuration());
149 str = buf = g_strdup_printf ("<b>%s</b>", ts_string);
150 g_free (ts_string);
152 break;
154 case Type::DURATION: {
155 Duration *d = value->AsDuration();
156 if (d->IsForever ())
157 str = "<b>Forever</b>";
158 else if (d->IsAutomatic())
159 str = "<b>Automatic</b>";
160 else /*if (d->HasTimeSpan())*/ {
161 char *ts_string = timespan_to_str (d->GetTimeSpan());
162 str = buf = g_strdup_printf ("<b>%s</b>", ts_string);
163 g_free (ts_string);
165 break;
167 case Type::COLOR: {
168 Color *color = value->AsColor();
169 str = buf = g_strdup_printf ("<b>r=%g, g=%g, b=%g, a=%g</b>", color->r, color->g, color->b, color->a);
170 break;
172 case Type::BOOL:
173 str = value->AsBool () ? "<b>true</b>" : "<b>false</b>";
174 break;
175 case Type::GRIDLENGTH: {
176 GridLength *length = value->AsGridLength ();
177 str = buf = g_strdup_printf ("<b>%g (%s)</b>", length->val, length->type == GridUnitTypeAuto ?
178 "Auto" : length->type == GridUnitTypeStar ? "*" : "Pixel");
179 break;
181 case Type::THICKNESS: {
182 Thickness *thickness = value->AsThickness ();
183 str = buf = g_strdup_printf ("<b>%g, %g, %g, %g</b>",
184 thickness->left,
185 thickness->top,
186 thickness->right,
187 thickness->bottom);
188 break;
190 case Type::POINT: {
191 Point *point = value->AsPoint ();
192 str = buf = g_strdup_printf ("<b>(%g, %g)</b>", point->x, point->y);
193 break;
195 case Type::CORNERRADIUS: {
196 CornerRadius *CornerRadius = value->AsCornerRadius ();
197 str = buf = g_strdup_printf ("<b>%g, %g, %g, %g</b>",
198 CornerRadius->topLeft,
199 CornerRadius->topRight,
200 CornerRadius->bottomLeft,
201 CornerRadius->bottomRight);
202 break;
204 case Type::KEYTIME:
205 default:
206 str = "<i>(unknown)</i>";
207 break;
209 } else {
210 str = "<b><i>null</i></b>";
213 gtk_tree_store_set (store, node,
214 COL_NAME, name,
215 COL_TYPE_NAME, type_name,
216 COL_VALUE, str,
217 COL_ELEMENT_PTR, NULL,
218 -1);
220 g_free (buf);
223 static void
224 reflect_dependency_object_in_tree (DependencyObject *obj, GtkTreeStore *store, GtkTreeIter *node, bool node_is_self)
226 if (obj == NULL)
227 return;
229 GtkTreeIter iter;
231 if (!node_is_self) {
232 gtk_tree_store_append (store, &iter, node);
234 char *markup = g_strdup_printf ("<b>%s</b>", obj->GetName() ? obj->GetName() : "");
235 gtk_tree_store_set (store, &iter,
236 COL_NAME, markup,
237 COL_TYPE_NAME, obj->GetTypeName(),
238 COL_ELEMENT_PTR, obj,
239 -1);
240 g_free (markup);
242 node = &iter;
245 DependencyProperty **properties = obj->GetProperties (true);
247 if (properties[0] != NULL) {
248 GtkTreeIter prop_iter, iter;
249 Type *owner_type;
250 Type *prop_type;
251 char *markup;
252 Value *value;
254 gtk_tree_store_append (store, &prop_iter, node);
256 gtk_tree_store_set (store, &prop_iter,
257 COL_NAME, "Properties",
258 COL_TYPE_NAME, "",
259 COL_ELEMENT_PTR, obj,
260 -1);
262 for (int i = 0; properties[i]; i++) {
263 owner_type = Type::Find (obj->GetDeployment (), properties[i]->GetOwnerType ());
264 markup = g_strdup_printf ("<i>%s.%s</i>", owner_type ? owner_type->GetName () : "(unknown)",
265 properties[i]->GetName ());
267 gtk_tree_store_append (store, &iter, &prop_iter);
269 prop_type = Type::Find (obj->GetDeployment (), properties[i]->GetPropertyType ());
270 value = obj->GetValue (properties[i]);
272 reflect_value (store, &iter, markup, prop_type ? prop_type->GetName () : "(unknown)", value);
274 g_free (markup);
278 g_free (properties);
280 if (obj->Is(Type::COLLECTION)) {
281 Collection *col = (Collection*)obj;
283 if (col->GetCount() > 0) {
284 GtkTreeIter elements_iter;
286 gtk_tree_store_append (store, &elements_iter, node);
288 gtk_tree_store_set (store, &elements_iter,
289 COL_NAME, "Elements",
290 COL_TYPE_NAME, "",
291 COL_ELEMENT_PTR, obj,
292 -1);
294 for (int i = 0; i < col->GetCount(); i ++) {
295 Value *v = col->GetValueAt (i);
296 char *markup;
298 if (v->Is (col->GetDeployment (), Type::DEPENDENCY_OBJECT))
299 markup = g_strdup_printf ("<i>[%d]</i> <b>%s</b>", i, v->AsDependencyObject()->GetName() ? v->AsDependencyObject()->GetName() : "");
300 else
301 markup = g_strdup_printf ("<i>[%d]</i>", i);
303 GtkTreeIter child_iter;
305 gtk_tree_store_append (store, &child_iter, &elements_iter);
307 reflect_value (store, &child_iter, markup, NULL, v);
309 g_free (markup);
314 if (obj->Is(Type::FRAMEWORKELEMENT) && !obj->Is(Type::PANEL) && !obj->Is (Type::BORDER)) {
315 GtkTreeIter subobject_iter;
317 gtk_tree_store_append (store, &subobject_iter, node);
319 Value v(((Control*)obj)->GetSubtreeObject());
321 reflect_value (store, &subobject_iter, "Visual Child", NULL, &v);
324 if (obj->Is (Type::NAMESCOPE)) {
325 NameScope *scope = (NameScope *) obj;
327 GHashTable *names = scope->GetNames ();
328 if (names && g_hash_table_size (names) > 0) {
330 AddNamescopeItemData *anid = new AddNamescopeItemData (store, node);
332 g_hash_table_foreach (names, add_namescope_item, anid);
333 delete anid;
339 static void
340 add_namescope_item (gpointer key, gpointer value, gpointer user_data)
342 AddNamescopeItemData *anid = (AddNamescopeItemData *) user_data;
343 char *name = (char *) key;
344 DependencyObject *dob = (DependencyObject *) value;
346 GtkTreeIter elements_iter;
347 gtk_tree_store_append (anid->store, &elements_iter, anid->node);
349 char *markup = g_strdup_printf (" <b>%s</b>", name);
351 gtk_tree_store_set (anid->store, &elements_iter,
352 COL_NAME, markup,
353 COL_TYPE_NAME, dob->GetType ()->GetName (),
354 COL_VALUE, "",
355 COL_ELEMENT_PTR, dob,
356 -1);
358 g_free (markup);
361 static void
362 selection_changed (GtkTreeSelection *selection, PluginInstance *plugin)
364 GtkTreeModel *model;
365 GtkTreeIter iter;
366 DependencyObject *el;
368 Deployment::SetCurrent (plugin->GetDeployment ());
370 if (plugin->GetSurface()->debug_selected_element) {
371 UIElement *el = plugin->GetSurface()->debug_selected_element;
372 el->Invalidate (el->GetSubtreeBounds().GrowBy(1).RoundOut());
373 el->unref ();
374 plugin->GetSurface()->debug_selected_element = NULL;
377 if (!gtk_tree_selection_get_selected (selection,
378 &model,
379 &iter)) {
380 return;
383 gtk_tree_model_get (model, &iter,
384 COL_ELEMENT_PTR, &el,
385 -1);
387 if (el && el->Is(Type::UIELEMENT)) {
388 UIElement *ui = (UIElement*)el;
389 ui->Invalidate (ui->GetSubtreeBounds().GrowBy(1).RoundOut());
390 ui->ref ();
391 plugin->GetSurface()->debug_selected_element = ui;
394 Deployment::SetCurrent (NULL);
397 static void
398 surface_destroyed (EventObject *sender, EventArgs *args, gpointer closure)
400 gtk_widget_destroy ((GtkWidget *) closure);
403 static void
404 remove_destroyed_handler (PluginInstance *plugin, GObject *window)
406 Deployment::SetCurrent (plugin->GetDeployment ());
407 plugin->GetSurface ()->RemoveHandler (EventObject::DestroyedEvent, surface_destroyed, window);
408 Deployment::SetCurrent (NULL);
411 void
412 plugin_debug (PluginInstance *plugin)
414 Surface *surface = plugin->GetSurface ();
416 if (!surface) {
417 GtkWidget *d = gtk_message_dialog_new (NULL,
418 GTK_DIALOG_NO_SEPARATOR,
419 GTK_MESSAGE_ERROR,
420 GTK_BUTTONS_CLOSE,
421 "The plugin hasn't been initialized with xaml content yet");
422 gtk_dialog_run (GTK_DIALOG (d));
423 g_object_unref (d);
424 return;
427 GtkWidget *tree_win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
428 gtk_window_set_title (GTK_WINDOW (tree_win), "Xaml contents");
429 gtk_window_set_default_size (GTK_WINDOW (tree_win), 300, 400);
431 Deployment::SetCurrent (plugin->GetDeployment ());
433 surface->AddHandler (EventObject::DestroyedEvent, surface_destroyed, tree_win);
434 g_object_weak_ref (G_OBJECT (tree_win), (GWeakNotify) remove_destroyed_handler, plugin);
436 GtkTreeStore *tree_store = gtk_tree_store_new (NUM_COLUMNS,
437 G_TYPE_STRING,
438 G_TYPE_STRING,
439 G_TYPE_STRING,
440 G_TYPE_POINTER);
442 reflect_dependency_object_in_tree (plugin->GetSurface()->GetToplevel (), tree_store, NULL, false);
444 #if false
445 GtkTreeModel *sorted_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree_store));
447 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sorted_model),
448 COL_NAME, GTK_SORT_ASCENDING);
450 GtkWidget* tree_view = gtk_tree_view_new_with_model (sorted_model);
451 #else
452 GtkWidget* tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
453 #endif
455 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
457 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
459 g_signal_connect (G_OBJECT (selection), "changed",
460 G_CALLBACK (selection_changed), plugin);
462 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
463 GtkTreeViewColumn *col;
465 /* The Name column */
466 col = gtk_tree_view_column_new();
467 gtk_tree_view_column_set_title(col, "Name");
468 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);
470 gtk_tree_view_column_pack_start(col, renderer, TRUE);
471 gtk_tree_view_column_add_attribute (col, renderer, "markup", COL_NAME);
472 gtk_tree_view_column_set_resizable (col, TRUE);
474 gtk_tree_view_column_set_sort_column_id (col, COL_NAME);
476 /* The Type column */
477 col = gtk_tree_view_column_new();
478 gtk_tree_view_column_set_title(col, "Type");
479 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);
481 gtk_tree_view_column_pack_start(col, renderer, TRUE);
482 gtk_tree_view_column_add_attribute (col, renderer, "markup", COL_TYPE_NAME);
483 gtk_tree_view_column_set_resizable (col, TRUE);
485 /* The Value column */
486 col = gtk_tree_view_column_new();
487 gtk_tree_view_column_set_title(col, "Value");
488 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);
490 gtk_tree_view_column_pack_start(col, renderer, TRUE);
491 gtk_tree_view_column_add_attribute (col, renderer, "markup", COL_VALUE);
492 gtk_tree_view_column_set_resizable (col, TRUE);
494 GtkWidget *scrolled = gtk_scrolled_window_new (NULL, NULL);
495 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
496 GTK_POLICY_AUTOMATIC,
497 GTK_POLICY_AUTOMATIC);
499 gtk_container_add (GTK_CONTAINER (scrolled), tree_view);
500 gtk_container_add (GTK_CONTAINER (tree_win), scrolled);
502 gtk_widget_show_all (tree_win);
504 Deployment::SetCurrent (NULL);
507 static void
508 populate_tree_from_surface (PluginInstance *plugin, GtkTreeStore *store, GtkTreeIter *parent)
510 if (plugin == NULL)
511 return;
513 GtkTreeIter iter;
514 List *sources;
515 PluginInstance::moon_source *src;
517 sources = plugin->GetSources ();
519 if (sources == NULL)
520 return;
522 src = (PluginInstance::moon_source*) sources->First ();
523 for (; src != NULL; src = (PluginInstance::moon_source*) src->next) {
524 gtk_tree_store_append (store, &iter, parent);
526 gtk_tree_store_set (store, &iter,
527 0, src->uri,
528 1, src->filename,
529 2, src,
530 -1);
535 PluginInstance::moon_source *selected_source = NULL;
537 static void
538 selection_changed_sources (GtkTreeSelection *selection, PluginInstance *plugin)
540 GtkTreeModel *model;
541 GtkTreeIter iter;
543 selected_source = NULL;
545 if (!gtk_tree_selection_get_selected (selection,
546 &model,
547 &iter)) {
548 return;
551 gtk_tree_model_get (model, &iter,
552 2, &selected_source,
553 -1);
556 static void clicked_callback (GtkWidget *widget, gpointer data)
558 if (selected_source == NULL) {
559 printf ("Select a source first.\n");
560 } else {
561 gchar* argv [3];
562 argv [0] = (gchar*) "xdg-open";
563 argv [1] = (gchar*) selected_source->filename;
564 argv [2] = NULL;
565 g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
569 static void unxap_callback (GtkWidget *widget, gpointer data)
571 if (selected_source == NULL) {
572 printf ("Select a source first.\n");
573 } else {
574 gchar* argv [3];
575 argv [0] = (gchar*) "munxap";
576 argv [1] = (gchar*) selected_source->filename;
577 argv [2] = NULL;
578 g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
583 static size_t
584 get_common_prefix_len (GtkTreeModel *model)
586 char *filename, *path, *url, *buf, *p, *q;
587 size_t max = (size_t) -1;
588 GtkTreeIter iter;
589 Uri *uri;
591 if (!gtk_tree_model_get_iter_first (model, &iter))
592 return 0;
594 gtk_tree_model_get (model, &iter, 0, &url, 1, &filename, -1);
596 uri = new Uri ();
597 if (!uri->Parse (url)) {
598 buf = g_strdup (filename);
599 } else {
600 buf = (char*)uri->GetPath();
601 uri->path = NULL;
604 if ((p = strrchr (buf, '/')))
605 max = (p - buf);
606 else
607 max = 0;
609 delete uri;
611 while (gtk_tree_model_iter_next (model, &iter)) {
612 gtk_tree_model_get (model, &iter, 0, &url, 1, &filename, -1);
614 uri = new Uri ();
615 if (!uri->Parse (url))
616 path = filename;
617 else
618 path = (char*)uri->GetPath();
620 for (p = buf, q = path; *p && *q; p++, q++) {
621 if (*p != *q)
622 break;
625 if ((size_t) (p - buf) < max)
626 max = p - buf;
628 delete uri;
631 g_free (buf);
633 return max;
636 static void
637 save_callback (GtkWidget *widget, gpointer data)
639 GtkTreeModel *model = (GtkTreeModel *) data;
640 char *filename, *dirname, *url, *path;
641 GtkTreeIter iter;
642 size_t prelen;
643 Uri *uri;
644 int fd;
646 if (mkdir ("/tmp/moon-dump", 0777) == -1 && errno != EEXIST)
647 return;
649 prelen = get_common_prefix_len (model);
651 if (!gtk_tree_model_get_iter_first (model, &iter))
652 return;
654 do {
655 gtk_tree_model_get (model, &iter, 0, &url, 1, &filename, -1);
657 uri = new Uri ();
658 if (uri->Parse (url))
659 path = (char*)uri->GetPath();
660 else
661 path = filename;
663 path = g_build_filename ("/tmp/moon-dump", path + prelen, NULL);
664 delete uri;
666 dirname = g_path_get_dirname (path);
667 g_mkdir_with_parents (dirname, 0777);
668 g_free (dirname);
670 if ((fd = open (path, O_CREAT | O_WRONLY | O_EXCL, 0644)) != -1) {
671 if (CopyFileTo (filename, fd) == -1)
672 printf (" Failed: Could not copy file `%s' to `%s': %s\n", filename, path, g_strerror (errno));
673 } else if (errno != EEXIST) {
674 printf (" Failed: Could not create file `%s': %s\n", path, g_strerror (errno));
677 g_free (path);
678 } while (gtk_tree_model_iter_next (model, &iter));
681 void
682 plugin_sources (PluginInstance *plugin)
684 GtkWidget *tree_win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
685 gtk_window_set_title (GTK_WINDOW (tree_win), "Sources");
686 gtk_window_set_default_size (GTK_WINDOW (tree_win), 600, 400);
687 GtkBox *vbox = GTK_BOX (gtk_vbox_new (false, 0));
689 GtkTreeStore *tree_store = gtk_tree_store_new (3,
690 G_TYPE_STRING,
691 G_TYPE_STRING,
692 G_TYPE_POINTER);
694 populate_tree_from_surface (plugin, tree_store, NULL);
696 GtkWidget *tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
698 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
700 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
702 g_signal_connect (G_OBJECT (selection), "changed",
703 G_CALLBACK (selection_changed_sources), plugin);
705 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
706 GtkTreeViewColumn *col;
708 /* The Name column */
709 col = gtk_tree_view_column_new();
710 gtk_tree_view_column_set_title(col, "Uri");
711 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);
713 gtk_tree_view_column_pack_start(col, renderer, TRUE);
714 gtk_tree_view_column_add_attribute (col, renderer, "text", 0);
716 /* The Type column */
717 col = gtk_tree_view_column_new();
718 gtk_tree_view_column_set_title(col, "Filename");
719 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);
721 gtk_tree_view_column_pack_start(col, renderer, TRUE);
722 gtk_tree_view_column_add_attribute (col, renderer, "text", 1);
724 GtkWidget *scrolled = gtk_scrolled_window_new (NULL, NULL);
725 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
726 GTK_POLICY_AUTOMATIC,
727 GTK_POLICY_AUTOMATIC);
729 gtk_container_add (GTK_CONTAINER (scrolled), tree_view);
730 //gtk_container_add (GTK_CONTAINER (tree_win), scrolled);
731 gtk_box_pack_start (vbox, scrolled, TRUE, TRUE, 0);
733 GtkWidget *button;
734 button = gtk_button_new_with_label ("Open file");
735 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (clicked_callback), NULL);
736 gtk_box_pack_start (vbox, button, FALSE, FALSE, 0);
738 button = gtk_button_new_with_label ("Unxap");
739 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (unxap_callback), tree_store);
740 gtk_box_pack_start (vbox, button, FALSE, FALSE, 0);
742 button = gtk_button_new_with_label ("Save (to /tmp/moon-dump/)");
743 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (save_callback), tree_store);
744 gtk_box_pack_start (vbox, button, FALSE, FALSE, 0);
746 gtk_container_add (GTK_CONTAINER (tree_win), GTK_WIDGET (vbox));
748 gtk_widget_show_all (tree_win);
751 #endif