1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2006 Sébastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 // Alloc string in DmaVariableData object, so treeview can use POINTER
23 // => no need to free data after getting the value
24 // => value can be access more easily if we have the tree viex
25 // => do the same for variable name
27 // Add a function to get all arguments
33 #include "debug_tree.h"
39 #include <libanjuta/anjuta-debug.h>
41 #include <glib/gi18n.h>
49 *---------------------------------------------------------------------------*/
63 typedef enum _DataType DataType
;
65 enum {AUTO_UPDATE_WATCH
= 1 << 0};
68 typedef struct _CommonDebugTree CommonDebugTree
;
69 typedef struct _DmaVariablePacket DmaVariablePacket
;
70 typedef struct _DmaVariableData DmaVariableData
;
72 struct _CommonDebugTree
{
79 /* The debug tree object */
81 DmaDebuggerQueue
*debugger
;
83 GtkWidget
* view
; /* the tree widget */
87 struct _DmaVariablePacket
{
88 DmaVariableData
*data
;
91 GtkTreeRowReference
* reference
;
92 DmaDebuggerQueue
*debugger
;
93 DmaVariablePacket
* next
;
96 struct _DmaVariableData
{
97 gboolean modified
; /* Set by tree update */
99 /* Value from debugger */
100 gboolean changed
; /* Set by global update */
101 gboolean exited
; /* variable outside scope */
102 gboolean deleted
; /* variable should be deleted */
104 gboolean auto_update
;
106 DmaVariablePacket
* packet
;
112 *---------------------------------------------------------------------------*/
114 #define UNKNOWN_VALUE "???"
115 #define UNKNOWN_TYPE "?"
116 #define AUTO_UPDATE 'U'
127 static gchar
*tree_title
[] = {
128 N_("Variable"), N_("Value"), N_("Type")
132 *---------------------------------------------------------------------------*/
134 static GList
* gTreeList
= NULL
;
137 *---------------------------------------------------------------------------*/
140 my_gtk_tree_model_foreach_child (GtkTreeModel
*const model
,
141 GtkTreeIter
*const parent
,
142 GtkTreeModelForeachFunc func
,
146 gboolean success
= gtk_tree_model_iter_children(model
, &iter
, parent
);
150 success
= (!func(model
, NULL
, &iter
, user_data
) &&
151 gtk_tree_model_iter_next (model
, &iter
));
156 my_gtk_tree_model_child_position (GtkTreeModel
*model
,
162 path
= gtk_tree_model_get_path (model
, iter
);
163 if (path
== NULL
) return -1;
165 for (pos
= 0; gtk_tree_path_prev (path
); pos
++);
166 gtk_tree_path_free (path
);
172 get_current_iter (GtkTreeView
*view
, GtkTreeIter
* iter
)
174 GtkTreeSelection
*selection
;
176 selection
= gtk_tree_view_get_selection (view
);
177 return gtk_tree_selection_get_selected (selection
, NULL
, iter
);
180 static DmaVariableData
*
181 dma_variable_data_new(const gchar
*const name
, gboolean auto_update
)
183 DmaVariableData
*data
;
185 data
= g_new0 (DmaVariableData
, 1);
188 data
->name
= g_strdup (name
);
191 data
->auto_update
= auto_update
;
197 dma_variable_data_free(DmaVariableData
* data
)
199 DmaVariablePacket
* pack
;
201 /* Mark the data as invalid, the packet structure will
202 * be free later in the callback */
203 for (pack
= data
->packet
; pack
!= NULL
; pack
= pack
->next
)
208 if (data
->name
!= NULL
)
216 /* ------------------------------------------------------------------ */
218 static DmaVariablePacket
*
219 dma_variable_packet_new(GtkTreeModel
*model
,
221 DmaDebuggerQueue
*debugger
,
222 DmaVariableData
*data
,
227 g_return_val_if_fail (model
, NULL
);
228 g_return_val_if_fail (iter
, NULL
);
230 DmaVariablePacket
*pack
= g_new (DmaVariablePacket
, 1);
234 pack
->model
= GTK_TREE_MODEL (model
);
235 path
= gtk_tree_model_get_path(model
, iter
);
236 pack
->reference
= gtk_tree_row_reference_new (model
, path
);
237 gtk_tree_path_free (path
);
238 pack
->debugger
= debugger
;
239 pack
->next
= data
->packet
;
246 dma_variable_packet_free (DmaVariablePacket
* pack
)
248 if (pack
->data
!= NULL
)
250 /* Remove from packet data list */
251 DmaVariablePacket
**find
;
253 for (find
= &pack
->data
->packet
; *find
!= NULL
; find
= &(*find
)->next
)
263 gtk_tree_row_reference_free (pack
->reference
);
269 dma_variable_packet_get_iter (DmaVariablePacket
* pack
, GtkTreeIter
*iter
)
274 path
= gtk_tree_row_reference_get_path (pack
->reference
);
275 ok
= gtk_tree_model_get_iter (pack
->model
, iter
, path
);
276 gtk_tree_path_free (path
);
281 /* DebugTree private functions
282 *---------------------------------------------------------------------------*/
285 debug_tree_cell_data_func (GtkTreeViewColumn
*tree_column
,
286 GtkCellRenderer
*cell
, GtkTreeModel
*tree_model
,
287 GtkTreeIter
*iter
, gpointer data
)
290 static const gchar
*colors
[] = {"black", "red"};
291 GValue gvalue
= {0, };
292 DmaVariableData
*node
= NULL
;
294 gtk_tree_model_get (tree_model
, iter
, VALUE_COLUMN
, &value
, -1);
295 g_value_init (&gvalue
, G_TYPE_STRING
);
296 g_value_set_static_string (&gvalue
, value
);
297 g_object_set_property (G_OBJECT (cell
), "text", &gvalue
);
299 gtk_tree_model_get (tree_model
, iter
, DTREE_ENTRY_COLUMN
, &node
, -1);
303 g_value_reset (&gvalue
);
304 g_value_set_static_string (&gvalue
,
305 colors
[(node
&& node
->modified
? 1 : 0)]);
307 g_object_set_property (G_OBJECT (cell
), "foreground", &gvalue
);
313 delete_child(GtkTreeModel
*model
, GtkTreePath
* path
,
314 GtkTreeIter
* iter
, gpointer user_data
)
316 DmaVariableData
*data
;
317 DmaDebuggerQueue
*debugger
= (DmaDebuggerQueue
*)user_data
;
319 g_return_val_if_fail (model
,TRUE
);
320 g_return_val_if_fail (iter
,TRUE
);
322 gtk_tree_model_get(model
, iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
324 /* Dummy node (data == NULL) are used when child are not known */
327 dma_variable_data_free(data
);
328 my_gtk_tree_model_foreach_child (model
, iter
, delete_child
, debugger
);
335 delete_parent(GtkTreeModel
*model
, GtkTreePath
* path
,
336 GtkTreeIter
* iter
, gpointer user_data
)
338 DmaVariableData
*data
;
339 DmaDebuggerQueue
*debugger
= (DmaDebuggerQueue
*)user_data
;
341 g_return_val_if_fail (model
,TRUE
);
342 g_return_val_if_fail (iter
,TRUE
);
344 gtk_tree_model_get(model
, iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
346 /* Dummy node (data == NULL) are used as a place holder in watch box */
353 /* Object has been created in debugger and is not a child
354 * (destroyed with their parent) */
355 dma_queue_delete_variable (debugger
, data
->name
);
359 dma_variable_data_free(data
);
361 my_gtk_tree_model_foreach_child (model
, iter
, delete_child
, debugger
);
368 debug_tree_remove_children (GtkTreeModel
*model
, DmaDebuggerQueue
*debugger
, GtkTreeIter
* parent
, GtkTreeIter
* first
)
375 /* Start with first child */
381 /* Remove all children */
382 child
= gtk_tree_model_iter_children(model
, &iter
, parent
);
387 delete_child (model
, NULL
, &iter
, debugger
);
389 child
= gtk_tree_store_remove (GTK_TREE_STORE (model
), &iter
);
394 debug_tree_model_add_dummy_children (GtkTreeModel
*model
, GtkTreeIter
*parent
)
398 gtk_tree_store_append(GTK_TREE_STORE(model
), &iter
, parent
);
399 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
,
403 ROOT_COLUMN
, parent
== NULL
? TRUE
: FALSE
,
404 DTREE_ENTRY_COLUMN
, NULL
, -1);
408 debug_tree_add_children (GtkTreeModel
*model
, DmaDebuggerQueue
*debugger
, GtkTreeIter
* parent
, guint from
, const GList
*children
)
414 valid
= gtk_tree_model_iter_nth_child (model
, &iter
, parent
, from
);
416 /* Add new children */
417 for (child
= g_list_first ((GList
*)children
); child
!= NULL
; child
= g_list_next (child
))
419 IAnjutaDebuggerVariableObject
*var
= (IAnjutaDebuggerVariableObject
*)child
->data
;
420 DmaVariableData
*data
;
424 /* Add new tree node */
425 gtk_tree_store_append(GTK_TREE_STORE(model
), &iter
, parent
);
427 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
,
428 TYPE_COLUMN
, var
->type
== NULL
? UNKNOWN_TYPE
: var
->type
,
429 VALUE_COLUMN
, var
->value
== NULL
? UNKNOWN_VALUE
: var
->value
,
430 VARIABLE_COLUMN
, var
->expression
,
432 DTREE_ENTRY_COLUMN
, NULL
,-1);
437 /* Update tree node */
438 if (var
->type
!= NULL
)
439 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
, TYPE_COLUMN
, var
->type
, -1);
440 if (var
->value
!= NULL
)
441 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
, VALUE_COLUMN
, var
->value
, -1);
442 if (var
->expression
!= NULL
)
443 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
, VARIABLE_COLUMN
, var
->expression
, -1);
444 gtk_tree_model_get(model
, &iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
446 if (var
->name
== NULL
)
448 /* Dummy node representing additional children */
451 dma_variable_data_free (data
);
452 gtk_tree_store_set(GTK_TREE_STORE (model
), &iter
, DTREE_ENTRY_COLUMN
, NULL
, -1);
458 if ((var
->name
!= NULL
) && (data
== NULL
))
460 /* Create new data */
461 data
= dma_variable_data_new(var
->name
, TRUE
);
462 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
, DTREE_ENTRY_COLUMN
, data
, -1);
465 /* Clear all children if they exist */
466 debug_tree_remove_children (model
, debugger
, &iter
, NULL
);
467 if ((var
->children
!= 0) || var
->has_more
|| (var
->name
== NULL
))
469 /* Add dummy children */
470 debug_tree_model_add_dummy_children (model
, &iter
);
473 valid
= gtk_tree_model_iter_next (model
, &iter
);
476 /* Clear remaining old children */
477 if (valid
) debug_tree_remove_children (model
, debugger
, parent
, &iter
);
480 /*---------------------------------------------------------------------------*/
483 gdb_var_evaluate_expression (const gchar
*value
,
484 gpointer user_data
, GError
* err
)
486 DmaVariablePacket
*pack
= (DmaVariablePacket
*) user_data
;
489 g_return_if_fail (pack
!= NULL
);
492 || (pack
->data
== NULL
)
493 || !dma_variable_packet_get_iter (pack
, &iter
))
495 /* Command failed or item has been deleted */
496 dma_variable_packet_free (pack
);
501 pack
->data
->changed
= FALSE
;
502 gtk_tree_store_set(GTK_TREE_STORE (pack
->model
), &iter
, VALUE_COLUMN
, value
, -1);
503 dma_variable_packet_free (pack
);
507 gdb_var_list_children (const GList
*children
, gpointer user_data
, GError
*err
)
509 DmaVariablePacket
*pack
= (DmaVariablePacket
*) user_data
;
512 g_return_if_fail (pack
!= NULL
);
515 || (pack
->data
== NULL
)
516 || !dma_variable_packet_get_iter (pack
, &iter
))
518 /* Command failed or item has been deleted */
519 dma_variable_packet_free (pack
);
524 debug_tree_add_children (pack
->model
, pack
->debugger
, &iter
, pack
->from
, children
);
526 dma_variable_packet_free (pack
);
530 gdb_var_create (IAnjutaDebuggerVariableObject
*variable
, gpointer user_data
, GError
*err
)
532 DmaVariablePacket
*pack
= (DmaVariablePacket
*) user_data
;
535 g_return_if_fail (pack
!= NULL
);
540 dma_variable_packet_free (pack
);
544 if ((pack
->data
== NULL
)
545 || !dma_variable_packet_get_iter (pack
, &iter
))
547 /* Item has been deleted, but not removed from debugger as it was not
548 * created at this time, so remove it now */
549 if ((pack
->debugger
) && (variable
->name
))
551 dma_queue_delete_variable (pack
->debugger
, variable
->name
);
553 dma_variable_packet_free (pack
);
558 DmaVariableData
*data
= pack
->data
;
560 if ((variable
->name
!= NULL
) && (data
->name
== NULL
))
562 data
->name
= strdup (variable
->name
);
564 data
->changed
= TRUE
;
565 data
->deleted
= FALSE
;
566 data
->exited
= FALSE
;
568 gtk_tree_store_set(GTK_TREE_STORE(pack
->model
), &iter
,
569 TYPE_COLUMN
, variable
->type
,
570 VALUE_COLUMN
, variable
->value
, -1);
573 if ((variable
->children
== 0) && !variable
->has_more
)
575 debug_tree_remove_children (pack
->model
, pack
->debugger
, &iter
, NULL
);
579 debug_tree_model_add_dummy_children (pack
->model
, &iter
);
583 /* Request value and/or children if they are missing
584 * reusing same packet if possible */
585 if (variable
->value
== NULL
)
587 dma_queue_evaluate_variable (
590 (IAnjutaDebuggerCallback
)gdb_var_evaluate_expression
,
595 dma_variable_packet_free (pack
);
599 /* ------------------------------------------------------------------ */
602 on_treeview_row_expanded (GtkTreeView
*treeview
,
607 DebugTree
*tree
= (DebugTree
*)user_data
;
609 if (tree
->debugger
!= NULL
)
611 GtkTreeModel
*const model
= gtk_tree_view_get_model (treeview
);
612 DmaVariableData
*data
;
614 gtk_tree_model_get (model
, iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
616 if ((data
!= NULL
) && (data
->name
!= NULL
))
618 /* Expand variable node */
621 if (gtk_tree_model_iter_children (model
, &child
, iter
))
623 DmaVariableData
*child_data
;
625 gtk_tree_model_get (model
, &child
, DTREE_ENTRY_COLUMN
, &child_data
, -1);
626 if ((child_data
== NULL
) || (child_data
->name
== NULL
))
628 /* Dummy children, get the real children */
629 DmaVariablePacket
*pack
;
631 pack
= dma_variable_packet_new(model
, iter
, tree
->debugger
, data
, 0);
632 dma_queue_list_children (
636 (IAnjutaDebuggerCallback
)gdb_var_list_children
,
643 /* Dummy node representing additional children */
646 if (gtk_tree_model_iter_parent (model
, &parent
, iter
))
648 gtk_tree_model_get (model
, &parent
, DTREE_ENTRY_COLUMN
, &data
, -1);
649 if ((data
!= NULL
) && (data
->name
!= NULL
))
651 DmaVariablePacket
*pack
;
655 pos
= my_gtk_tree_model_child_position (model
, iter
);
656 from
= pos
< 0 ? 0 : pos
;
658 pack
= dma_variable_packet_new(model
, &parent
, tree
->debugger
, data
, from
);
659 dma_queue_list_children (
663 (IAnjutaDebuggerCallback
)gdb_var_list_children
,
674 on_debug_tree_variable_changed (GtkCellRendererText
*cell
,
679 DebugTree
*tree
= (DebugTree
*)user_data
;
681 GtkTreeModel
* model
;
683 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
684 if (gtk_tree_model_get_iter_from_string (model
, &iter
, path_string
))
686 debug_tree_remove (tree
, &iter
);
688 if ((text
!= NULL
) && (*text
!= '\0'))
690 IAnjutaDebuggerVariableObject var
= {NULL
, NULL
, NULL
, NULL
, FALSE
, FALSE
, FALSE
, -1};
692 var
.expression
= text
;
693 debug_tree_add_watch (tree
, &var
, TRUE
);
697 debug_tree_add_dummy (tree
, NULL
);
703 on_debug_tree_value_changed (GtkCellRendererText
*cell
,
708 DebugTree
*tree
= (DebugTree
*)user_data
;
710 GtkTreeModel
* model
;
712 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
714 if (gtk_tree_model_get_iter_from_string (model
, &iter
, path_string
))
716 DmaVariableData
*item
;
717 DmaVariablePacket
*tran
;
719 gtk_tree_model_get (model
, &iter
, DTREE_ENTRY_COLUMN
, &item
, -1);
720 if ((item
!= NULL
) && (item
->name
!= NULL
) && (tree
->debugger
!= NULL
))
722 /* Variable is valid */
723 dma_queue_assign_variable (tree
->debugger
, item
->name
, text
);
724 tran
= dma_variable_packet_new(model
, &iter
, tree
->debugger
, item
, 0);
725 dma_queue_evaluate_variable (
728 (IAnjutaDebuggerCallback
) gdb_var_evaluate_expression
,
735 debug_tree_create (DebugTree
*tree
, GtkTreeView
*view
)
737 GtkCellRenderer
*renderer
;
738 GtkTreeViewColumn
*column
;
739 GtkTreeModel
* model
= GTK_TREE_MODEL (gtk_tree_store_new
749 view
= GTK_TREE_VIEW (gtk_tree_view_new ());
752 gtk_tree_view_set_model (view
, GTK_TREE_MODEL (model
));
754 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (view
);
755 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
756 g_object_unref (G_OBJECT (model
));
759 column
= gtk_tree_view_column_new ();
760 renderer
= gtk_cell_renderer_text_new ();
761 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
762 gtk_tree_view_column_add_attribute (column
, renderer
, "text", VARIABLE_COLUMN
);
763 gtk_tree_view_column_add_attribute (column
, renderer
, "editable", ROOT_COLUMN
);
764 g_signal_connect(renderer
, "edited", (GCallback
) on_debug_tree_variable_changed
, tree
);
765 gtk_tree_view_column_set_sizing (column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
766 gtk_tree_view_column_set_resizable (column
, TRUE
);
767 gtk_tree_view_column_set_title (column
, _(tree_title
[0]));
768 gtk_tree_view_append_column (view
, column
);
769 gtk_tree_view_set_expander_column (view
, column
);
771 column
= gtk_tree_view_column_new ();
772 renderer
= gtk_cell_renderer_text_new ();
773 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
774 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
775 debug_tree_cell_data_func
, NULL
, NULL
);
776 gtk_tree_view_column_add_attribute (column
, renderer
, "text", VALUE_COLUMN
);
777 g_object_set(renderer
, "editable", TRUE
, NULL
);
778 g_signal_connect(renderer
, "edited", (GCallback
) on_debug_tree_value_changed
, tree
);
779 gtk_tree_view_column_set_sizing (column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
780 gtk_tree_view_column_set_resizable (column
, TRUE
);
781 gtk_tree_view_column_set_title (column
, _(tree_title
[1]));
782 gtk_tree_view_append_column (view
, column
);
785 column
= gtk_tree_view_column_new ();
786 renderer
= gtk_cell_renderer_text_new ();
787 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
788 gtk_tree_view_column_add_attribute (column
, renderer
, "text", TYPE_COLUMN
);
789 gtk_tree_view_column_set_sizing (column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
790 gtk_tree_view_column_set_resizable (column
, TRUE
);
791 gtk_tree_view_column_set_title (column
, _(tree_title
[2]));
792 gtk_tree_view_append_column (view
, column
);
794 return GTK_WIDGET (view
);
798 *---------------------------------------------------------------------------*/
800 /* clear the display of the debug tree and reset the title */
802 debug_tree_remove_all (DebugTree
*tree
)
806 g_return_if_fail (tree
);
807 g_return_if_fail (tree
->view
);
809 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
810 debug_tree_remove_model (tree
, model
);
814 debug_tree_find_name (const GtkTreeModel
*model
, GtkTreeIter
*iter
, const gchar
*name
)
817 GtkTreeIter parent_iter
;
818 GtkTreeIter
* parent
= NULL
;
824 /* Check if we look for a child variable */
825 ptr
= strchr(name
+ len
+ 1, '.');
832 for (search
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), iter
, parent
);
834 search
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), iter
))
836 DmaVariableData
*iData
;
837 gtk_tree_model_get (GTK_TREE_MODEL (model
), iter
, DTREE_ENTRY_COLUMN
, &iData
, -1);
839 if ((iData
!= NULL
) && (iData
->name
!= NULL
) && (name
[len
] == '.') && (strncmp (name
, iData
->name
, len
) == 0))
848 parent
= &parent_iter
;
858 /* Variable without any child */
861 for (search
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), iter
, parent
);
863 search
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), iter
))
865 DmaVariableData
*iData
;
866 gtk_tree_model_get (GTK_TREE_MODEL (model
), iter
, DTREE_ENTRY_COLUMN
, &iData
, -1);
868 if ((iData
!= NULL
) && (iData
->name
!= NULL
) && (strcmp (name
, iData
->name
) == 0))
880 debug_tree_replace_list (DebugTree
*tree
, const GList
*expressions
)
882 GtkTreeModel
* model
= gtk_tree_view_get_model (GTK_TREE_VIEW(tree
->view
));
885 GList
*list
= g_list_copy ((GList
*)expressions
);
887 /* Keep in the tree only the variable in the list */
888 valid
= gtk_tree_model_get_iter_first (model
, &iter
);
893 DmaVariableData
*node
;
895 gtk_tree_model_get (model
, &iter
,
896 VARIABLE_COLUMN
, &exp
,
897 DTREE_ENTRY_COLUMN
, &node
, -1);
899 if ((node
->deleted
== FALSE
) && (node
->exited
== FALSE
) && (exp
!= NULL
))
901 find
= g_list_find_custom (list
, exp
, (GCompareFunc
)strcmp
);
906 /* Keep variable in tree, remove in add list */
907 list
= g_list_delete_link (list
, find
);
908 valid
= gtk_tree_model_iter_next (model
, &iter
);
912 /* Remove variable from the tree */
913 delete_parent(model
, NULL
, &iter
, tree
->debugger
);
914 valid
= gtk_tree_store_remove (GTK_TREE_STORE (model
), &iter
);
918 /* Create new variable */
921 IAnjutaDebuggerVariableObject var
= {NULL
, NULL
, NULL
, NULL
, FALSE
, FALSE
, FALSE
, -1};
923 var
.expression
= (gchar
*)(list
->data
);
924 debug_tree_add_watch (tree
, &var
, TRUE
);
926 list
= g_list_delete_link (list
, list
);
931 debug_tree_add_dummy (DebugTree
*tree
, GtkTreeIter
*parent
)
933 GtkTreeModel
* model
= gtk_tree_view_get_model (GTK_TREE_VIEW(tree
->view
));
935 debug_tree_model_add_dummy_children (model
, parent
);
938 /* Get a IAnjutaVariable as argument in order to use the same function without
939 * variable object, currently only the expression field is set */
942 debug_tree_add_watch (DebugTree
*tree
, const IAnjutaDebuggerVariableObject
* var
, gboolean auto_update
)
944 GtkTreeModel
*model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
946 DmaVariableData
*data
;
949 data
= dma_variable_data_new(var
->name
, auto_update
);
951 /* Add node in tree */
952 gtk_tree_store_append(GTK_TREE_STORE(model
), &iter
, NULL
);
953 gtk_tree_store_set(GTK_TREE_STORE(model
), &iter
,
954 TYPE_COLUMN
, var
->type
== NULL
? UNKNOWN_TYPE
: var
->type
,
955 VALUE_COLUMN
, var
->value
== NULL
? UNKNOWN_VALUE
: var
->value
,
956 VARIABLE_COLUMN
, var
->expression
,
958 DTREE_ENTRY_COLUMN
, data
, -1);
960 if (tree
->debugger
!= NULL
)
962 if ((var
->value
== NULL
) || (var
->children
== -1))
964 if (var
->name
== NULL
)
966 /* Need to create variable before to get value */
967 DmaVariablePacket
*pack
;
969 pack
= dma_variable_packet_new(model
, &iter
, tree
->debugger
, data
, 0);
970 dma_queue_create_variable (
973 (IAnjutaDebuggerCallback
)gdb_var_create
,
978 DEBUG_PRINT("%s", "You shouldn't read this, debug_tree_add_watch");
979 if (var
->value
== NULL
)
982 DmaVariablePacket
*pack
=
984 pack
= dma_variable_packet_new(model
, &iter
, tree
->debugger
, data
, 0);
985 dma_queue_evaluate_variable (
988 (IAnjutaDebuggerCallback
)gdb_var_evaluate_expression
,
997 on_add_watch (gpointer data
, gpointer user_data
)
999 DebugTree
* this = (DebugTree
*)user_data
;
1000 gboolean auto_update
= ((const gchar
*)data
)[0] & AUTO_UPDATE_WATCH
? TRUE
: FALSE
;
1001 IAnjutaDebuggerVariableObject var
= {NULL
, NULL
, NULL
, NULL
, FALSE
, FALSE
, FALSE
, -1};
1003 var
.expression
= &((gchar
*)data
)[1];
1004 debug_tree_add_watch (this, &var
, auto_update
);
1008 debug_tree_add_full_watch_list (DebugTree
*this, GList
*expressions
)
1010 g_list_foreach (expressions
, on_add_watch
, this);
1014 on_add_manual_watch (gpointer data
, gpointer user_data
)
1016 DebugTree
* this = (DebugTree
*)user_data
;
1017 IAnjutaDebuggerVariableObject var
= {NULL
, NULL
, NULL
, NULL
, FALSE
, FALSE
, FALSE
, -1};
1019 var
.expression
= &((gchar
*)data
)[0];
1020 debug_tree_add_watch (this, &var
, FALSE
);
1024 on_add_auto_watch (gpointer data
, gpointer user_data
)
1026 DebugTree
* this = (DebugTree
*)user_data
;
1027 IAnjutaDebuggerVariableObject var
= {NULL
, NULL
, NULL
, NULL
, FALSE
, FALSE
, -1};
1029 var
.expression
= &((gchar
*)data
)[0];
1030 debug_tree_add_watch (this, &var
, TRUE
);
1034 debug_tree_add_watch_list (DebugTree
*this, GList
*expressions
, gboolean auto_update
)
1036 g_list_foreach (expressions
, auto_update
? on_add_auto_watch
: on_add_manual_watch
, this);
1040 on_debug_tree_changed (gpointer data
, gpointer user_data
)
1042 IAnjutaDebuggerVariableObject
*var
= (IAnjutaDebuggerVariableObject
*)data
;
1044 if (var
->name
!= NULL
)
1046 /* Search corresponding variable in one tree */
1049 for (list
= g_list_first (gTreeList
); list
!= NULL
; list
= g_list_next (list
))
1051 DebugTree
*tree
= (DebugTree
*)list
->data
;
1054 GtkTreeModel
*model
;
1056 model
= debug_tree_get_model (tree
);
1058 if (debug_tree_find_name (model
, &iter
, var
->name
))
1060 DmaVariableData
*data
;
1061 gtk_tree_model_get (model
, &iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
1065 data
->changed
= var
->changed
;
1066 data
->exited
= var
->exited
;
1067 data
->deleted
= var
->deleted
;
1077 debug_tree_update_real (GtkTreeModel
*model
, DmaDebuggerQueue
*debugger
, GtkTreeIter
* iter
, gboolean force
)
1079 DmaVariableData
*data
= NULL
;
1082 gboolean refresh
= TRUE
;
1084 gtk_tree_model_get (model
, iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
1085 if (data
== NULL
) return FALSE
;
1088 if ((data
->deleted
) && (data
->name
!= NULL
) && (force
|| data
->auto_update
))
1090 /* Variable deleted (by example if type change), try to recreate it */
1091 dma_queue_delete_variable (debugger
, data
->name
);
1092 g_free (data
->name
);
1096 if (data
->name
== NULL
)
1098 /* Check is the variable creation is not pending */
1099 if (data
->packet
== NULL
)
1101 /* Variable need to be created first */
1103 DmaVariablePacket
*pack
;
1105 gtk_tree_model_get (model
, iter
, VARIABLE_COLUMN
, &exp
, -1);
1106 pack
= dma_variable_packet_new(model
, iter
, debugger
, data
, 0);
1107 dma_queue_create_variable (
1110 (IAnjutaDebuggerCallback
)gdb_var_create
,
1117 else if (force
|| (data
->auto_update
&& data
->changed
))
1119 DmaVariablePacket
*pack
= dma_variable_packet_new(model
, iter
, debugger
, data
, 0);
1120 refresh
= data
->modified
!= (data
->changed
!= FALSE
);
1121 data
->modified
= (data
->changed
!= FALSE
);
1122 dma_queue_evaluate_variable (
1125 (IAnjutaDebuggerCallback
)gdb_var_evaluate_expression
,
1127 data
->changed
= FALSE
;
1131 refresh
= data
->modified
;
1132 data
->modified
= FALSE
;
1135 /* update children */
1136 for (search
= gtk_tree_model_iter_children(model
, &child
, iter
);
1138 search
= gtk_tree_model_iter_next (model
, &child
))
1140 if (debug_tree_update_real (model
, debugger
, &child
, force
))
1142 refresh
= data
->modified
== TRUE
;
1143 data
->modified
= TRUE
;
1150 path
= gtk_tree_model_get_path (model
, iter
);
1151 gtk_tree_model_row_changed (model
, path
, iter
);
1152 gtk_tree_path_free (path
);
1155 return data
->modified
;
1159 /* Get information from debugger and update variable with automatic update */
1161 on_debug_tree_update_all (const GList
*change
, gpointer user_data
, GError
* err
)
1163 DmaDebuggerQueue
*debugger
= (DmaDebuggerQueue
*)user_data
;
1166 if (err
!= NULL
) return;
1168 // Update all variables information from debugger data
1169 g_list_foreach ((GList
*)change
, on_debug_tree_changed
, NULL
);
1171 // Update all tree models
1172 for (list
= g_list_first (gTreeList
); list
!= NULL
; list
= g_list_next (list
))
1174 DebugTree
* tree
= (DebugTree
*)list
->data
;
1176 GtkTreeModel
* model
;
1180 model
= debug_tree_get_model (tree
);
1183 for (valid
= gtk_tree_model_get_iter_first (model
, &iter
);
1185 valid
= gtk_tree_model_iter_next (model
, &iter
))
1187 debug_tree_update_real (model
, debugger
, &iter
, FALSE
);
1193 debug_tree_update_all (DmaDebuggerQueue
*debugger
)
1195 dma_queue_update_variable (debugger
,
1196 (IAnjutaDebuggerCallback
)on_debug_tree_update_all
,
1200 /* Update all variables in the specified tree */
1202 debug_tree_update_tree (DebugTree
*this)
1204 GtkTreeModel
*model
;
1208 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (this->view
));
1211 for (valid
= gtk_tree_model_get_iter_first (model
, &iter
);
1213 valid
= gtk_tree_model_iter_next (model
, &iter
))
1215 debug_tree_update_real (model
, this->debugger
, &iter
, TRUE
);
1220 debug_tree_get_full_watch_list (DebugTree
*this)
1223 GtkTreeModel
*model
;
1226 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (this->view
));
1228 if (gtk_tree_model_get_iter_first (model
, &iter
) == TRUE
)
1232 DmaVariableData
*data
;
1234 gchar
*exp_with_flag
;
1236 gtk_tree_model_get(model
, &iter
, DTREE_ENTRY_COLUMN
, &data
,
1237 VARIABLE_COLUMN
, &exp
, -1);
1241 exp_with_flag
= g_strconcat (" ", exp
, NULL
);
1242 exp_with_flag
[0] = data
->auto_update
? AUTO_UPDATE_WATCH
: ' ';
1243 list
= g_list_prepend (list
, exp_with_flag
);
1246 } while (gtk_tree_model_iter_next (model
, &iter
) == TRUE
);
1249 list
= g_list_reverse (list
);
1256 debug_tree_get_tree_widget (DebugTree
*this)
1262 debug_tree_get_current (DebugTree
*tree
, GtkTreeIter
* iter
)
1264 return get_current_iter (GTK_TREE_VIEW (tree
->view
), iter
);
1267 /* Return TRUE if iter is still valid (point to next item) */
1269 debug_tree_remove (DebugTree
*tree
, GtkTreeIter
* iter
)
1271 GtkTreeModel
*model
;
1273 g_return_val_if_fail (tree
, FALSE
);
1274 g_return_val_if_fail (tree
->view
, FALSE
);
1275 g_return_val_if_fail (iter
, FALSE
);
1277 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
1279 delete_parent (model
, NULL
, iter
, tree
->debugger
);
1280 return gtk_tree_store_remove (GTK_TREE_STORE (model
), iter
);
1284 debug_tree_update (DebugTree
* tree
, GtkTreeIter
* iter
, gboolean force
)
1286 if (tree
->debugger
!= NULL
)
1288 GtkTreeModel
*model
;
1290 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
1291 return debug_tree_update_real (model
, tree
->debugger
, iter
, force
);
1300 debug_tree_set_auto_update (DebugTree
* this, GtkTreeIter
* iter
, gboolean state
)
1302 GtkTreeModel
*model
;
1303 DmaVariableData
*data
;
1305 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (this->view
));
1306 gtk_tree_model_get(model
, iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
1309 data
->auto_update
= state
;
1314 debug_tree_get_auto_update (DebugTree
* this, GtkTreeIter
* iter
)
1316 GtkTreeModel
*model
;
1317 DmaVariableData
*data
;
1319 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (this->view
));
1320 gtk_tree_model_get(model
, iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
1324 return data
->auto_update
;
1333 debug_tree_connect (DebugTree
*this, DmaDebuggerQueue
* debugger
)
1335 this->debugger
= debugger
;
1339 on_disconnect_variable (GtkTreeModel
*model
,
1344 DmaVariableData
*data
;
1346 gtk_tree_model_get (model
, iter
, DTREE_ENTRY_COLUMN
, &data
, -1);
1350 g_free (data
->name
);
1358 debug_tree_disconnect (DebugTree
*this)
1360 GtkTreeModel
*model
;
1362 this->debugger
= NULL
;
1363 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (this->view
));
1365 /* Remove all variable name */
1366 gtk_tree_model_foreach (model
, on_disconnect_variable
, NULL
);
1370 debug_tree_get_model (DebugTree
*tree
)
1372 return gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
1376 debug_tree_set_model (DebugTree
*tree
, GtkTreeModel
*model
)
1378 gtk_tree_view_set_model (GTK_TREE_VIEW (tree
->view
), model
);
1382 debug_tree_new_model (DebugTree
*tree
)
1384 GtkTreeModel
* model
= GTK_TREE_MODEL (gtk_tree_store_new
1392 gtk_tree_view_set_model (GTK_TREE_VIEW (tree
->view
), model
);
1396 debug_tree_remove_model (DebugTree
*tree
, GtkTreeModel
*model
)
1398 my_gtk_tree_model_foreach_child (model
, NULL
, delete_parent
, tree
->debugger
);
1399 gtk_tree_store_clear (GTK_TREE_STORE (model
));
1403 debug_tree_get_selected (DebugTree
*tree
)
1408 if (get_current_iter (GTK_TREE_VIEW (tree
->view
), &iter
))
1410 GtkTreeModel
*model
;
1412 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
1415 gtk_tree_model_get(model
, &iter
, VARIABLE_COLUMN
, &exp
, -1);
1423 debug_tree_get_first (DebugTree
*tree
)
1427 GtkTreeModel
*model
;
1429 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
1432 if (gtk_tree_model_get_iter_first (model
, &iter
))
1434 gtk_tree_model_get(model
, &iter
, VARIABLE_COLUMN
, &exp
, -1);
1442 debug_tree_find_variable_value (DebugTree
*tree
, const gchar
*name
)
1444 GtkTreeModel
*model
;
1447 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (tree
->view
));
1449 if (gtk_tree_model_get_iter_first (model
, &iter
))
1455 gtk_tree_model_get(model
, &iter
, VARIABLE_COLUMN
, &exp
,
1456 VALUE_COLUMN
, &value
, -1);
1458 if (strcmp (exp
, name
) == 0)
1462 } while (gtk_tree_model_iter_next (model
, &iter
));
1468 /* Debugging functions
1469 *---------------------------------------------------------------------------*/
1472 debug_tree_dump_iter (GtkTreeModel
*model
, GtkTreeIter
*iter
, guint indent
)
1477 DmaVariableData
*node
;
1481 gtk_tree_model_get (model
, iter
,
1482 VARIABLE_COLUMN
, &expression
,
1483 VALUE_COLUMN
, &value
,
1485 DTREE_ENTRY_COLUMN
, &node
,
1489 g_message ("%*s %s | %s | %s | %s | %d%d%d%d%d", indent
, "",
1490 expression
, value
, type
, node
->name
,
1491 node
->modified
, node
->changed
, node
->exited
, node
->deleted
, node
->auto_update
);
1495 g_message ("%*s %s | %s | %s | %s | %c%c%c%c%c", indent
, "",
1496 expression
, value
, type
, "???",
1497 '?','?','?','?','?');
1499 g_free (expression
);
1503 for (valid
= gtk_tree_model_iter_children (model
, &child
, iter
);
1505 valid
= gtk_tree_model_iter_next (model
, &child
))
1507 debug_tree_dump_iter (model
, &child
, indent
+ 4);
1512 debug_tree_dump (void)
1516 for (list
= g_list_first (gTreeList
); list
!= NULL
; list
= g_list_next (list
))
1518 DebugTree
* tree
= (DebugTree
*)list
->data
;
1520 GtkTreeModel
* model
;
1524 model
= debug_tree_get_model (tree
);
1525 g_message ("Tree model %p MCEDU", model
);
1526 for (valid
= gtk_tree_model_get_iter_first (model
, &iter
);
1528 valid
= gtk_tree_model_iter_next (model
, &iter
))
1530 debug_tree_dump_iter (model
, &iter
, 4);
1535 /* Constructor & Destructor
1536 *---------------------------------------------------------------------------*/
1538 /* return a pointer to a newly allocated DebugTree object */
1540 debug_tree_new_with_view (AnjutaPlugin
*plugin
, GtkTreeView
*view
)
1542 DebugTree
*tree
= g_new0 (DebugTree
, 1);
1544 tree
->plugin
= plugin
;
1545 tree
->view
= debug_tree_create(tree
, view
);
1546 tree
->auto_expand
= FALSE
;
1548 /* Add this tree in list */
1549 gTreeList
= g_list_prepend (gTreeList
, tree
);
1551 /* Connect signal */
1552 g_signal_connect(GTK_TREE_VIEW (tree
->view
), "row_expanded", G_CALLBACK (on_treeview_row_expanded
), tree
);
1559 /* return a pointer to a newly allocated DebugTree object */
1561 debug_tree_new (AnjutaPlugin
* plugin
)
1563 return debug_tree_new_with_view (plugin
, NULL
);
1566 /* DebugTree destructor */
1568 debug_tree_free (DebugTree
* tree
)
1570 g_return_if_fail (tree
);
1572 debug_tree_remove_all (tree
);
1574 /* Remove from list */
1575 gTreeList
= g_list_remove (gTreeList
, tree
);
1577 g_signal_handlers_disconnect_by_func (GTK_TREE_VIEW (tree
->view
),
1578 G_CALLBACK (on_treeview_row_expanded
), tree
);
1580 gtk_widget_destroy (tree
->view
);