Updated Spanish translation
[anjuta-git-plugin.git] / plugins / debug-manager / stack_trace.c
blobe09c87385277543096d6804a66e869a8be038bb1
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 stack_trace.c
4 Copyright (C) 2000 Kh. Naba Kumar Singh
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #include "stack_trace.h"
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <gnome.h>
32 /*#define DEBUG*/
33 #include <libanjuta/resources.h>
34 #include <libanjuta/anjuta-debug.h>
35 #include <libanjuta/interfaces/ianjuta-editor.h>
36 #include <libanjuta/interfaces/ianjuta-document-manager.h>
38 #include "utilities.h"
39 #include "info.h"
41 #define ANJUTA_PIXMAP_POINTER PACKAGE_PIXMAPS_DIR"/pointer.png"
43 typedef struct _DmaThreadStackTrace
45 GtkTreeModel *model;
46 guint thread;
47 guint last_update;
48 } DmaThreadStackTrace;
50 struct _StackTrace
52 DebugManagerPlugin *plugin;
53 IAnjutaDebugger *debugger;
55 GtkActionGroup *action_group;
57 DmaThreadStackTrace* current;
58 GList *list;
60 gint current_frame;
61 guint current_update;
63 GtkTreeView *treeview;
64 GtkMenu *menu;
65 GtkWidget *scrolledwindow;
68 enum {
69 STACK_TRACE_ACTIVE_COLUMN,
70 STACK_TRACE_FRAME_COLUMN,
71 STACK_TRACE_FILE_COLUMN,
72 STACK_TRACE_LINE_COLUMN,
73 STACK_TRACE_FUNC_COLUMN,
74 STACK_TRACE_ADDR_COLUMN,
75 STACK_TRACE_ARGS_COLUMN,
76 STACK_TRACE_URI_COLUMN,
77 STACK_TRACE_COLOR_COLUMN,
78 STACK_TRACE_N_COLUMNS
81 /* Helpers functions
82 *---------------------------------------------------------------------------*/
84 static gboolean
85 get_current_iter (GtkTreeView *view, GtkTreeIter* iter)
87 GtkTreeSelection *selection;
89 selection = gtk_tree_view_get_selection (view);
90 return gtk_tree_selection_get_selected (selection, NULL, iter);
94 * returns the current stack frame or -1 on error
96 static gint
97 get_current_index (StackTrace* st)
99 GtkTreeIter iter;
101 if (get_current_iter (st->treeview, &iter))
103 GtkTreeModel *model;
104 gint frame_no;
106 model = gtk_tree_view_get_model (st->treeview);
107 gtk_tree_model_get (model, &iter, STACK_TRACE_FRAME_COLUMN, &frame_no, -1);
109 return frame_no;
111 else
113 return -1;
117 static gboolean
118 my_gtk_tree_model_get_iter_last(GtkTreeModel *model, GtkTreeIter *last)
120 gboolean exist;
121 GtkTreeIter iter;
123 exist = gtk_tree_model_get_iter_first(model, &iter);
124 if (!exist) return FALSE;
128 *last = iter;
129 exist = gtk_tree_model_iter_next(model, &iter);
131 while (exist);
133 return TRUE;
136 static gboolean
137 my_gtk_tree_model_iter_prev(GtkTreeModel *model, GtkTreeIter *iter)
139 GtkTreePath* path;
140 gboolean exist;
142 path = gtk_tree_model_get_path (model, iter);
143 exist = gtk_tree_path_prev (path);
144 if (exist)
146 exist = gtk_tree_model_get_iter (model, iter, path);
148 gtk_tree_path_free (path);
150 return exist;
153 static gint
154 my_gtk_tree_iter_compare(GtkTreeModel *model, GtkTreeIter *itera, GtkTreeIter *iterb)
156 GtkTreePath* patha;
157 GtkTreePath* pathb;
158 gint comp;
160 patha = gtk_tree_model_get_path (model, itera);
161 pathb = gtk_tree_model_get_path (model, iterb);
163 comp = gtk_tree_path_compare (patha, pathb);
165 gtk_tree_path_free (patha);
166 gtk_tree_path_free (pathb);
168 return comp;
171 /* Private functions
172 *---------------------------------------------------------------------------*/
174 static void
175 on_clear_stack_trace (gpointer data, gpointer user_data)
177 DmaThreadStackTrace *trace = (DmaThreadStackTrace *) data;
179 g_object_unref (G_OBJECT (trace->model));
180 g_free (trace);
183 static void
184 dma_thread_clear_all_stack_trace (StackTrace *self)
186 /* Clear all GtkListStore */
187 g_list_foreach (self->list, (GFunc)on_clear_stack_trace, NULL);
188 g_list_free (self->list);
190 self->current = NULL;
191 self->list = NULL;
194 static void
195 on_stack_trace_updated (const GList *stack, gpointer user_data)
197 StackTrace *self = (StackTrace *)user_data;
198 const GList *node;
199 GtkListStore *model;
200 GtkTreeIter iter;
201 gboolean exist;
202 GdkPixbuf *pic;
204 model = GTK_LIST_STORE (self->current->model);
206 pic = gdk_pixbuf_new_from_file (ANJUTA_PIXMAP_POINTER, NULL);
208 exist = my_gtk_tree_model_get_iter_last (GTK_TREE_MODEL (model), &iter);
210 for (node = (const GList *)g_list_last((GList *)stack); node != NULL; node = node->prev)
212 IAnjutaDebuggerFrame *frame;
213 gchar *adr;
214 gchar *uri;
215 gchar *file;
217 frame = (IAnjutaDebuggerFrame *)node->data;
219 if (exist)
221 /* Check if it's the same stack frame */
222 gchar *adr;
223 gchar *args;
224 guint address;
225 guint line;
226 gboolean same;
228 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
229 STACK_TRACE_ADDR_COLUMN, &adr,
230 STACK_TRACE_LINE_COLUMN, &line,
231 STACK_TRACE_ARGS_COLUMN, &args,
232 -1);
233 address = adr != NULL ? strtoul (adr, NULL, 0) : 0;
234 same = (address == frame->address) && (line == frame->line);
235 if ((args == NULL) || (frame->args == NULL))
237 same = same && (args == frame->args);
239 else
241 same = same && (strcmp (args, frame->args) == 0);
243 g_free (adr);
244 g_free (args);
246 if (same)
248 /* Same frame, just change the color */
249 gtk_list_store_set (model, &iter,
250 STACK_TRACE_ACTIVE_COLUMN, frame->level == self->current_frame ? pic : NULL,
251 STACK_TRACE_FRAME_COLUMN, frame->level,
252 STACK_TRACE_COLOR_COLUMN, "black", -1);
254 /* Check previous frame */
255 exist = my_gtk_tree_model_iter_prev (GTK_TREE_MODEL (model), &iter);
256 if (!exist || (node->prev != NULL))
258 /* Last frame or Upper frame still exist */
259 continue;
261 /* Upper frame do not exist, remove all them */
264 /* New frame, remove all previous frame */
265 GtkTreeIter first;
267 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &first);
268 while (my_gtk_tree_iter_compare (GTK_TREE_MODEL (model), &first, &iter) < 0)
270 gtk_list_store_remove (model, &first);
272 gtk_list_store_remove (model, &first);
274 if (same)
276 break;
278 else
280 exist = FALSE;
284 gtk_list_store_prepend (model, &iter);
286 adr = g_strdup_printf ("0x%x", frame->address);
287 if (frame->file)
289 uri = g_strconcat ("file://", frame->file, NULL);
290 file = strrchr(uri, '/') + 1;
292 else
294 uri = NULL;
295 file = frame->library;
298 gtk_list_store_set(model, &iter,
299 STACK_TRACE_ACTIVE_COLUMN, frame->level == self->current_frame ? pic : NULL,
300 STACK_TRACE_FRAME_COLUMN, frame->level,
301 STACK_TRACE_FILE_COLUMN, file,
302 STACK_TRACE_LINE_COLUMN, frame->line,
303 STACK_TRACE_FUNC_COLUMN, frame->function,
304 STACK_TRACE_ADDR_COLUMN, adr,
305 STACK_TRACE_ARGS_COLUMN, frame->args,
306 STACK_TRACE_URI_COLUMN, uri,
307 STACK_TRACE_COLOR_COLUMN, "red",
308 -1);
309 g_free (uri);
310 g_free (adr);
312 gdk_pixbuf_unref (pic);
316 static DmaThreadStackTrace*
317 dma_thread_create_new_stack_trace (StackTrace *self, guint thread)
319 DmaThreadStackTrace *trace;
320 GtkListStore *store;
322 /* Create new list store */
323 store = gtk_list_store_new (STACK_TRACE_N_COLUMNS,
324 GDK_TYPE_PIXBUF,
325 G_TYPE_UINT,
326 G_TYPE_STRING,
327 G_TYPE_UINT,
328 G_TYPE_STRING,
329 G_TYPE_STRING,
330 G_TYPE_STRING,
331 G_TYPE_STRING,
332 G_TYPE_STRING);
334 trace = g_new (DmaThreadStackTrace, 1);
335 trace->thread = thread;
336 trace->model = GTK_TREE_MODEL (store);
337 trace->last_update = self->current_update;
339 self->current = trace;
341 /* Ask debugger to get all frame data */
342 ianjuta_debugger_list_frame (
343 self->debugger,
344 (IAnjutaDebuggerCallback)on_stack_trace_updated,
345 self,
346 NULL);
348 self->list = g_list_append (self->list, trace);
350 return trace;
353 static DmaThreadStackTrace*
354 dma_thread_update_stack_trace (StackTrace *self, DmaThreadStackTrace *trace)
356 GtkListStore *store;
358 trace->last_update = self->current_update;
360 /* Ask debugger to get all frame data */
361 ianjuta_debugger_list_frame (
362 self->debugger,
363 (IAnjutaDebuggerCallback)on_stack_trace_updated,
364 self,
365 NULL);
367 return trace;
370 static gboolean
371 on_find_stack_trace (gconstpointer a, gconstpointer b)
373 const DmaThreadStackTrace *trace = (const DmaThreadStackTrace *)a;
374 guint thread = (guint)b;
376 return trace->thread != thread;
379 static void
380 dma_thread_set_stack_trace (StackTrace *self, guint thread)
382 GList *list;
383 DmaThreadStackTrace *trace;
385 if ((self->current == NULL) || (self->current->thread != thread) || (self->current->last_update != self->current_update))
387 self->current_frame = 0;
389 list = g_list_find_custom (self->list, (gconstpointer) thread, on_find_stack_trace);
391 if (list == NULL)
393 /* Create new stack trace */
394 trace = dma_thread_create_new_stack_trace(self, thread);
396 else
398 trace = (DmaThreadStackTrace *)list->data;
399 self->current = trace;
401 if (trace->last_update != self->current_update)
403 /* Update stack trace */
404 dma_thread_update_stack_trace (self, trace);
407 gtk_tree_view_set_model (self->treeview, trace->model);
411 /* Callback functions
412 *---------------------------------------------------------------------------*/
414 static void
415 on_frame_changed (StackTrace *self, guint frame, guint thread)
417 GtkTreeIter iter;
418 GtkTreeModel *model;
420 /* Change thread */
421 dma_thread_set_stack_trace (self, thread);
423 /* Change frame */
424 self->current_frame = frame;
426 model = self->current->model;
428 /* Clear old pointer */
429 if(gtk_tree_model_get_iter_first (model, &iter))
433 /* clear pixmap on the previous active frame */
434 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
435 STACK_TRACE_ACTIVE_COLUMN, NULL, -1);
436 } while (gtk_tree_model_iter_next (model, &iter));
439 /* Set pointer to current frame */
440 if (gtk_tree_model_iter_nth_child (model, &iter, NULL, self->current_frame))
442 GdkPixbuf *pointer_pix = gdk_pixbuf_new_from_file (ANJUTA_PIXMAP_POINTER, NULL);
444 /* set pointer on this frame */
445 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
446 STACK_TRACE_ACTIVE_COLUMN, pointer_pix,
447 -1);
448 gdk_pixbuf_unref (pointer_pix);
452 static void
453 on_stack_frame_set_activate (GtkAction *action, gpointer user_data)
455 StackTrace *st;
456 guint selected_frame;
458 st = (StackTrace*) user_data;
460 selected_frame = get_current_index (st);
462 /* No frame selected */
463 if (selected_frame == -1)
464 return;
466 /* current frame is already active */
467 if (selected_frame == st->current_frame)
468 return;
470 /* issue a command to switch active frame to new location */
471 ianjuta_debugger_set_frame (st->debugger, selected_frame, NULL);
474 static void
475 on_stack_view_source_activate (GtkAction *action, gpointer user_data)
477 GtkTreeModel *model;
478 GtkTreeSelection *selection;
479 GtkTreeIter iter;
480 GtkTreeView *view;
481 gchar *uri;
482 guint line;
483 gchar *adr;
484 guint address;
486 StackTrace* st = (StackTrace*) user_data;
488 view = st->treeview;
489 selection = gtk_tree_view_get_selection (view);
490 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
491 return;
493 /* get the frame info */
494 gtk_tree_model_get (model, &iter,
495 STACK_TRACE_URI_COLUMN, &uri,
496 STACK_TRACE_LINE_COLUMN, &line,
497 STACK_TRACE_ADDR_COLUMN, &adr,
498 -1);
500 address = adr != NULL ? strtoul (adr, NULL, 0) : 0;
501 dma_debug_manager_goto_code (st->plugin, uri, line, address);
502 g_free (uri);
503 g_free (adr);
506 static void
507 on_stack_trace_row_activated (GtkTreeView *treeview,
508 GtkTreePath *arg1,
509 GtkTreeViewColumn *arg2,
510 StackTrace *st)
512 on_stack_frame_set_activate (NULL, st);
515 static gboolean
516 on_stack_trace_button_press (GtkWidget *widget, GdkEventButton *bevent, gpointer user_data)
518 StackTrace *st = (StackTrace*) user_data;
520 if ((bevent->type == GDK_BUTTON_PRESS) && (bevent->button == 3))
522 /* Right mouse click */
523 g_return_val_if_fail (st->menu != NULL, FALSE);
524 gtk_menu_popup (GTK_MENU (st->menu), NULL, NULL, NULL, NULL,
525 bevent->button, bevent->time);
527 else if ((bevent->type == GDK_2BUTTON_PRESS) && (bevent->button == 1))
529 /* Double left mouse click */
530 on_stack_view_source_activate (NULL, user_data);
533 return FALSE;
536 /* Actions table
537 *---------------------------------------------------------------------------*/
539 static GtkActionEntry actions_stack_trace[] = {
541 "ActionDmaSetCurrentFrame", /* Action name */
542 NULL, /* Stock icon, if any */
543 N_("Set current frame"), /* Display label */
544 NULL, /* short-cut */
545 NULL, /* Tooltip */
546 G_CALLBACK (on_stack_frame_set_activate) /* action callback */
549 "ActionDmaJumpToFrame",
550 NULL,
551 N_("View Source"),
552 NULL,
553 NULL,
554 G_CALLBACK (on_stack_view_source_activate)
558 static void
559 create_stack_trace_gui(StackTrace *st)
561 GtkTreeModel* model;
562 GtkTreeSelection *selection;
563 GtkTreeViewColumn *column;
564 GtkCellRenderer *renderer;
565 AnjutaUI *ui;
567 g_return_if_fail (st->scrolledwindow == NULL);
569 /* Create tree view */
570 model = GTK_TREE_MODEL(gtk_list_store_new (STACK_TRACE_N_COLUMNS,
571 GDK_TYPE_PIXBUF,
572 G_TYPE_UINT,
573 G_TYPE_STRING,
574 G_TYPE_UINT,
575 G_TYPE_STRING,
576 G_TYPE_STRING,
577 G_TYPE_STRING,
578 G_TYPE_STRING,
579 G_TYPE_STRING));
580 st->treeview = GTK_TREE_VIEW (gtk_tree_view_new_with_model (model));
581 g_object_unref (G_OBJECT (model));
583 selection = gtk_tree_view_get_selection (st->treeview);
584 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
586 /* Columns */
587 column = gtk_tree_view_column_new ();
588 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
589 gtk_tree_view_column_set_title (column, _("Active"));
590 renderer = gtk_cell_renderer_pixbuf_new ();
591 gtk_tree_view_column_pack_start (column, renderer, TRUE);
592 gtk_tree_view_column_add_attribute (column, renderer, "pixbuf",
593 STACK_TRACE_ACTIVE_COLUMN);
594 gtk_tree_view_append_column (st->treeview, column);
595 gtk_tree_view_set_expander_column (st->treeview,
596 column);
598 column = gtk_tree_view_column_new ();
599 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
600 gtk_tree_view_column_set_title (column, _("Frame"));
601 renderer = gtk_cell_renderer_text_new ();
602 gtk_tree_view_column_pack_start (column, renderer, TRUE);
603 gtk_tree_view_column_add_attribute (column, renderer, "text",
604 STACK_TRACE_FRAME_COLUMN);
605 gtk_tree_view_column_add_attribute (column, renderer, "foreground",
606 STACK_TRACE_COLOR_COLUMN);
607 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
608 gtk_tree_view_append_column (st->treeview, column);
609 gtk_tree_view_set_expander_column (st->treeview,
610 column);
612 column = gtk_tree_view_column_new ();
613 renderer = gtk_cell_renderer_text_new ();
614 gtk_tree_view_column_pack_start (column, renderer, TRUE);
615 gtk_tree_view_column_add_attribute (column, renderer, "text",
616 STACK_TRACE_FILE_COLUMN);
617 gtk_tree_view_column_add_attribute (column, renderer, "foreground",
618 STACK_TRACE_COLOR_COLUMN);
619 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
620 gtk_tree_view_column_set_title (column, _("File"));
621 gtk_tree_view_append_column (st->treeview, column);
623 column = gtk_tree_view_column_new ();
624 renderer = gtk_cell_renderer_text_new ();
625 gtk_tree_view_column_pack_start (column, renderer, TRUE);
626 gtk_tree_view_column_add_attribute (column, renderer, "text",
627 STACK_TRACE_LINE_COLUMN);
628 gtk_tree_view_column_add_attribute (column, renderer, "foreground",
629 STACK_TRACE_COLOR_COLUMN);
630 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
631 gtk_tree_view_column_set_title (column, _("Line"));
632 gtk_tree_view_append_column (st->treeview, column);
634 column = gtk_tree_view_column_new ();
635 renderer = gtk_cell_renderer_text_new ();
636 gtk_tree_view_column_pack_start (column, renderer, TRUE);
637 gtk_tree_view_column_add_attribute (column, renderer, "text",
638 STACK_TRACE_FUNC_COLUMN);
639 gtk_tree_view_column_add_attribute (column, renderer, "foreground",
640 STACK_TRACE_COLOR_COLUMN);
641 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
642 gtk_tree_view_column_set_title (column, _("Function"));
643 gtk_tree_view_append_column (st->treeview, column);
645 column = gtk_tree_view_column_new ();
646 renderer = gtk_cell_renderer_text_new ();
647 gtk_tree_view_column_pack_start (column, renderer, TRUE);
648 gtk_tree_view_column_add_attribute (column, renderer, "text",
649 STACK_TRACE_ADDR_COLUMN);
650 gtk_tree_view_column_add_attribute (column, renderer, "foreground",
651 STACK_TRACE_COLOR_COLUMN);
652 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
653 gtk_tree_view_column_set_title (column, _("Address"));
654 gtk_tree_view_append_column (st->treeview, column);
656 column = gtk_tree_view_column_new ();
657 renderer = gtk_cell_renderer_text_new ();
658 gtk_tree_view_column_pack_start (column, renderer, TRUE);
659 gtk_tree_view_column_add_attribute (column, renderer, "text",
660 STACK_TRACE_ARGS_COLUMN);
661 gtk_tree_view_column_add_attribute (column, renderer, "foreground",
662 STACK_TRACE_COLOR_COLUMN);
663 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
664 gtk_tree_view_column_set_title (column, _("Arguments"));
665 gtk_tree_view_append_column (st->treeview, column);
667 /* Create popup menu */
668 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN(st->plugin)->shell, NULL);
669 st->menu = GTK_MENU (gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui), "/PopupStack"));
671 /* Connect signal */
672 g_signal_connect (st->treeview, "button-press-event", G_CALLBACK (on_stack_trace_button_press), st);
673 g_signal_connect (st->treeview, "row-activated", G_CALLBACK (on_stack_trace_row_activated), st);
675 /* Add stack window */
676 st->scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
677 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (st->scrolledwindow),
678 GTK_POLICY_AUTOMATIC,
679 GTK_POLICY_AUTOMATIC);
680 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (st->scrolledwindow),
681 GTK_SHADOW_IN);
682 gtk_container_add (GTK_CONTAINER (st->scrolledwindow),
683 GTK_WIDGET (st->treeview));
684 gtk_widget_show_all (st->scrolledwindow);
686 anjuta_shell_add_widget (ANJUTA_PLUGIN(st->plugin)->shell,
687 st->scrolledwindow,
688 "AnjutaDebuggerStack", _("Stack"),
689 "gdb-stack-icon", ANJUTA_SHELL_PLACEMENT_BOTTOM,
690 NULL);
694 static void
695 destroy_stack_trace_gui (StackTrace *st)
697 if (st->scrolledwindow != NULL)
699 gtk_widget_destroy (st->scrolledwindow);
700 st->scrolledwindow = NULL;
704 static void
705 on_program_stopped (StackTrace *self, guint thread)
707 self->current_update++;
708 dma_thread_set_stack_trace (self, thread);
711 static void
712 on_debugger_started (StackTrace *self)
714 self->current_update = 0;
715 create_stack_trace_gui (self);
718 static void
719 on_debugger_stopped (StackTrace *self)
721 dma_thread_clear_all_stack_trace (self);
722 destroy_stack_trace_gui (self);
725 /* Public functions
726 *---------------------------------------------------------------------------*/
728 /* Constructor & Destructor
729 *---------------------------------------------------------------------------*/
731 StackTrace *
732 stack_trace_new (IAnjutaDebugger *debugger, DebugManagerPlugin *plugin)
734 StackTrace *st;
735 AnjutaUI *ui;
737 st = g_new0 (StackTrace, 1);
738 if (st == NULL) return NULL;
740 st->plugin = plugin;
741 st->debugger = debugger;
742 if (debugger != NULL) g_object_ref (debugger);
744 /* Register actions */
745 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN(st->plugin)->shell, NULL);
746 st->action_group =
747 anjuta_ui_add_action_group_entries (ui, "ActionGroupStack",
748 _("Stack frame operations"),
749 actions_stack_trace,
750 G_N_ELEMENTS (actions_stack_trace),
751 GETTEXT_PACKAGE, TRUE, st);
753 g_signal_connect_swapped (st->debugger, "debugger-started", G_CALLBACK (on_debugger_started), st);
754 g_signal_connect_swapped (st->debugger, "debugger-stopped", G_CALLBACK (on_debugger_stopped), st);
755 g_signal_connect_swapped (st->debugger, "program-stopped", G_CALLBACK (on_program_stopped), st);
756 g_signal_connect_swapped (st->debugger, "frame-changed", G_CALLBACK (on_frame_changed), st);
758 return st;
761 void
762 stack_trace_free (StackTrace * st)
764 AnjutaUI *ui;
766 g_return_if_fail (st != NULL);
768 /* Disconnect from debugger */
769 if (st->debugger != NULL)
771 g_signal_handlers_disconnect_by_func (st->debugger, G_CALLBACK (on_debugger_started), st);
772 g_signal_handlers_disconnect_by_func (st->debugger, G_CALLBACK (on_debugger_stopped), st);
773 g_signal_handlers_disconnect_by_func (st->debugger, G_CALLBACK (on_program_stopped), st);
774 g_signal_handlers_disconnect_by_func (st->debugger, G_CALLBACK (on_frame_changed), st);
775 g_object_unref (st->debugger);
778 /* Remove menu actions */
779 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (st->plugin)->shell, NULL);
780 anjuta_ui_remove_action_group (ui, st->action_group);
782 /* Destroy menu */
783 destroy_stack_trace_gui (st);
785 g_free (st);