1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 * watch.c Copyright (C) 2000 Kh. Naba Kumar Singh
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place, Suite 330, Boston, MA 02111-1307 USA */
24 #include "debug_tree.h"
28 #include <libanjuta/anjuta-debug.h>
29 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
30 #include <libanjuta/interfaces/ianjuta-editor.h>
31 #include <libanjuta/interfaces/ianjuta-document-manager.h>
34 *---------------------------------------------------------------------------*/
40 GtkWidget
*scrolledwindow
;
41 DebugTree
*debug_tree
;
42 IAnjutaDebugger
*debugger
;
45 GtkActionGroup
*action_group
;
46 GtkActionGroup
*toggle_group
;
56 typedef struct _InspectDialog InspectDialog
;
58 /* Widget and signal name found in glade file
59 *---------------------------------------------------------------------------*/
61 #define ADD_WATCH_DIALOG "add_watch_dialog"
62 #define CHANGE_WATCH_DIALOG "change_watch_dialog"
63 #define INSPECT_EVALUATE_DIALOG "watch_dialog"
64 #define NAME_ENTRY "name_entry"
65 #define VALUE_ENTRY "value_entry"
66 #define VALUE_TREE "value_treeview"
67 #define AUTO_UPDATE_CHECK "auto_update_check"
70 *---------------------------------------------------------------------------*/
74 on_entry_updated (const gchar
*value
, gpointer user_data
, GError
*err
)
76 GtkWidget
*entry
= GTK_WIDGET (user_data
);
78 gtk_entry_set_text (GTK_ENTRY (entry
), value
);
79 gtk_widget_unref (entry
);
84 debug_tree_inspect_evaluate_dialog (ExprWatch
* ew
, const gchar
* expression
)
89 // const gchar *value;
91 IAnjutaDebuggerVariable var
= {NULL
, NULL
, NULL
, NULL
, FALSE
, -1};
93 gxml
= glade_xml_new (GLADE_FILE
, INSPECT_EVALUATE_DIALOG
, NULL
);
94 dlg
.dialog
= glade_xml_get_widget (gxml
, INSPECT_EVALUATE_DIALOG
);
95 gtk_window_set_transient_for (GTK_WINDOW (dlg
.dialog
),
97 dlg
.treeview
= glade_xml_get_widget (gxml
, VALUE_TREE
);
98 g_object_unref (gxml
);
100 /* Create debug tree */
101 dlg
.tree
= debug_tree_new_with_view (ANJUTA_PLUGIN (ew
->plugin
), GTK_TREE_VIEW (dlg
.treeview
));
103 debug_tree_connect (dlg
.tree
, ew
->debugger
);
104 if (expression
!= NULL
)
106 var
.expression
= (gchar
*)expression
;
107 debug_tree_add_watch (dlg
.tree
, &var
, FALSE
);
111 debug_tree_add_dummy (dlg
.tree
, NULL
);
116 reply
= gtk_dialog_run (GTK_DIALOG (dlg
.dialog
));
119 case GTK_RESPONSE_OK
:
120 /* Add in watch window */
121 new_expr
= debug_tree_get_first (dlg
.tree
);
123 if (new_expr
!= NULL
)
125 var
.expression
= new_expr
;
126 debug_tree_add_watch (ew
->debug_tree
, &var
, FALSE
);
135 debug_tree_free (dlg
.tree
);
136 gtk_widget_destroy (dlg
.dialog
);
140 debug_tree_add_watch_dialog (ExprWatch
*ew
, const gchar
* expression
)
144 GtkWidget
*name_entry
;
145 GtkWidget
*auto_update_check
;
147 IAnjutaDebuggerVariable var
= {NULL
, NULL
, NULL
, NULL
, FALSE
, -1};
149 gxml
= glade_xml_new (GLADE_FILE
, ADD_WATCH_DIALOG
, NULL
);
150 dialog
= glade_xml_get_widget (gxml
, ADD_WATCH_DIALOG
);
151 gtk_window_set_transient_for (GTK_WINDOW (dialog
),
153 auto_update_check
= glade_xml_get_widget (gxml
, AUTO_UPDATE_CHECK
);
154 name_entry
= glade_xml_get_widget (gxml
, NAME_ENTRY
);
155 g_object_unref (gxml
);
157 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_update_check
), TRUE
);
158 gtk_entry_set_text (GTK_ENTRY (name_entry
), expression
== NULL
? "" : expression
);
160 reply
= gtk_dialog_run (GTK_DIALOG (dialog
));
161 if (reply
== GTK_RESPONSE_OK
)
163 var
.expression
= (gchar
*)gtk_entry_get_text (GTK_ENTRY (name_entry
));
164 debug_tree_add_watch (ew
->debug_tree
, &var
,
165 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (auto_update_check
)));
167 gtk_widget_destroy (dialog
);
171 debug_tree_change_watch_dialog (ExprWatch
*ew
, GtkTreeIter
* iter
)
176 GtkWidget
*name_entry
;
177 GtkWidget
*value_entry
;
179 TrimmableItem
*item
= NULL
;
180 GtkTreeModel
* model
= NULL
;
182 model
= gtk_tree_view_get_model(d_tree
->view
);
183 gtk_tree_model_get (model
, iter
, ITEM_COLUMN
, &item
, -1);
185 gxml
= glade_xml_new (GLADE_FILE
, CHANGE_WATCH_DIALOG
, NULL
);
186 dialog
= glade_xml_get_widget (gxml
, CHANGE_WATCH_DIALOG
);
187 gtk_window_set_transient_for (GTK_WINDOW (dialog
),
189 name_entry
= glade_xml_get_widget (gxml
, NAME_ENTRY
);
190 value_entry
= glade_xml_get_widget (gxml
, VALUE_ENTRY
);
191 g_object_unref (gxml
);
193 gtk_widget_grab_focus (value_entry
);
194 gtk_entry_set_text (GTK_ENTRY (name_entry
), &item
->name
[1]);
195 gtk_entry_set_text (GTK_ENTRY (value_entry
), item
->value
);
197 reply
= gtk_dialog_run (GTK_DIALOG (dialog
));
198 if (reply
== GTK_RESPONSE_APPLY
)
200 debug_tree_evaluate (d_tree
, iter
, gtk_entry_get_text (GTK_ENTRY (value_entry
)));
202 gtk_widget_destroy (dialog
);
207 *---------------------------------------------------------------------------*/
210 on_debug_tree_inspect (GtkAction
*action
, gpointer user_data
)
212 ExprWatch
* ew
= (ExprWatch
*)user_data
;
214 IAnjutaDocumentManager
*docman
= NULL
;
215 IAnjutaEditor
*te
= NULL
;
216 gchar
*expression
= NULL
;
218 /* Get current editor and line */
219 obj
= anjuta_shell_get_object (ANJUTA_PLUGIN (ew
->plugin
)->shell
,
220 "IAnjutaDocumentManager", NULL
/* TODO */);
221 docman
= IANJUTA_DOCUMENT_MANAGER (obj
);
224 te
= ianjuta_document_manager_get_current_editor (docman
, NULL
);
225 expression
= ianjuta_editor_selection_get (IANJUTA_EDITOR_SELECTION (te
), NULL
);
226 if (expression
== NULL
)
228 expression
= ianjuta_editor_get_current_word (IANJUTA_EDITOR (te
), NULL
);
232 debug_tree_inspect_evaluate_dialog (ew
, expression
);
237 on_debug_tree_add_watch (GtkAction
*action
, gpointer user_data
)
239 ExprWatch
* ew
= (ExprWatch
*)user_data
;
241 debug_tree_add_watch_dialog (ew
, NULL
);
245 on_debug_tree_remove_watch (GtkAction
*action
, gpointer user_data
)
247 ExprWatch
* ew
= (ExprWatch
*)user_data
;
250 if (debug_tree_get_current (ew
->debug_tree
, &iter
))
252 debug_tree_remove (ew
->debug_tree
, &iter
);
257 on_debug_tree_update_watch (GtkAction
*action
, gpointer user_data
)
259 ExprWatch
* ew
= (ExprWatch
*)user_data
;
262 if (debug_tree_get_current (ew
->debug_tree
, &iter
))
264 debug_tree_update (ew
->debug_tree
, &iter
, TRUE
);
269 on_debug_tree_auto_update_watch (GtkAction
*action
, gpointer user_data
)
271 ExprWatch
* ew
= (ExprWatch
*)user_data
;
274 if (debug_tree_get_current (ew
->debug_tree
, &iter
))
278 state
= gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action
));
279 debug_tree_set_auto_update (ew
->debug_tree
, &iter
, state
);
284 on_debug_tree_edit_watch (GtkAction
*action
, gpointer user_data
)
286 ExprWatch
* ew
= (ExprWatch
*)user_data
;
289 if (debug_tree_get_current (ew
->debug_tree
, &iter
))
291 debug_tree_change_watch_dialog (ew
, &iter
);
296 on_debug_tree_update_all_watch (GtkAction
*action
, gpointer user_data
)
298 ExprWatch
* ew
= (ExprWatch
*)user_data
;
300 debug_tree_update_all (ew
->debug_tree
);
304 on_debug_tree_remove_all_watch (GtkAction
*action
, gpointer user_data
)
306 ExprWatch
* ew
= (ExprWatch
*)user_data
;
308 debug_tree_remove_all (ew
->debug_tree
);
312 on_debug_tree_button_press (GtkWidget
*widget
, GdkEventButton
*bevent
, gpointer user_data
)
314 ExprWatch
* ew
= (ExprWatch
*)user_data
;
316 if (bevent
->button
== 3)
321 GtkWidget
*middle_click_menu
;
323 ui
= anjuta_shell_get_ui (ew
->plugin
->shell
, NULL
);
324 action
= anjuta_ui_get_action (ui
, "ActionGroupWatchToggle", "ActionDmaAutoUpdateWatch");
325 if (debug_tree_get_current (ew
->debug_tree
, &iter
))
327 gtk_action_set_sensitive (GTK_ACTION (action
), TRUE
);
328 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
), debug_tree_get_auto_update (ew
->debug_tree
, &iter
));
332 gtk_action_set_sensitive (GTK_ACTION (action
), FALSE
);
335 action
= anjuta_ui_get_action (ui
, "ActionGroupWatch", "ActionDmaEditWatch");
336 gtk_action_set_sensitive (GTK_ACTION (action
), FALSE
); // FIXME: Not implemented
338 middle_click_menu
= gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui
), "/PopupWatch");
339 g_return_val_if_fail (middle_click_menu
!= NULL
, FALSE
);
340 gtk_menu_popup (GTK_MENU (middle_click_menu
), NULL
, NULL
, NULL
, NULL
,
341 bevent
->button
, bevent
->time
);
348 *---------------------------------------------------------------------------*/
350 static GtkActionEntry actions_watch
[] = {
352 "ActionDmaInspect", /* Action name */
353 GTK_STOCK_DIALOG_INFO
, /* Stock icon, if any */
354 N_("Ins_pect/Evaluate..."), /* Display label */
355 NULL
, /* short-cut */
356 N_("Inspect or evaluate an expression or variable"), /* Tooltip */
357 G_CALLBACK (on_debug_tree_inspect
) /* action callback */
365 G_CALLBACK (on_debug_tree_add_watch
)
368 "ActionDmaRemoveWatch",
373 G_CALLBACK (on_debug_tree_remove_watch
)
376 "ActionDmaUpdateWatch",
381 G_CALLBACK (on_debug_tree_update_watch
)
384 "ActionDmaEditWatch",
389 G_CALLBACK (on_debug_tree_edit_watch
)
392 "ActionDmaUpdateAllWatch",
397 G_CALLBACK (on_debug_tree_update_all_watch
)
400 "ActionDmaRemoveAllWatch",
405 G_CALLBACK (on_debug_tree_remove_all_watch
)
409 static GtkToggleActionEntry toggle_watch
[] = {
411 "ActionDmaAutoUpdateWatch", /* Action name */
412 NULL
, /* Stock icon, if any */
413 N_("Automatic update"), /* Display label */
414 NULL
, /* short-cut */
416 G_CALLBACK (on_debug_tree_auto_update_watch
), /* action callback */
417 FALSE
/* Initial state */
422 create_expr_watch_gui (ExprWatch
* ew
)
426 ew
->debug_tree
= debug_tree_new (ew
->plugin
);
427 ew
->scrolledwindow
= gtk_scrolled_window_new (NULL
, NULL
);
428 gtk_widget_show (ew
->scrolledwindow
);
429 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ew
->scrolledwindow
),
430 GTK_POLICY_AUTOMATIC
,
431 GTK_POLICY_AUTOMATIC
);
432 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (ew
->scrolledwindow
),
434 gtk_container_add (GTK_CONTAINER (ew
->scrolledwindow
), debug_tree_get_tree_widget (ew
->debug_tree
));
436 ui
= anjuta_shell_get_ui (ew
->plugin
->shell
, NULL
);
438 anjuta_ui_add_action_group_entries (ui
, "ActionGroupWatch",
439 _("Watch operations"),
441 G_N_ELEMENTS (actions_watch
),
442 GETTEXT_PACKAGE
, TRUE
, ew
);
444 anjuta_ui_add_toggle_action_group_entries (ui
, "ActionGroupWatchToggle",
445 _("Watch operations"),
447 G_N_ELEMENTS (toggle_watch
),
448 GETTEXT_PACKAGE
, TRUE
, ew
);
449 g_signal_connect (debug_tree_get_tree_widget (ew
->debug_tree
), "button-press-event", G_CALLBACK (on_debug_tree_button_press
), ew
);
451 gtk_widget_show_all (ew
->scrolledwindow
);
455 *---------------------------------------------------------------------------*/
458 expr_watch_cmd_queqe (ExprWatch
*ew
)
460 debug_tree_update_all (ew
->debug_tree
);
464 expr_watch_connect (ExprWatch
*ew
, IAnjutaDebugger
*debugger
)
466 ew
->debugger
= debugger
;
467 debug_tree_connect (ew
->debug_tree
, debugger
);
470 /* Callback for saving session
471 *---------------------------------------------------------------------------*/
474 on_session_save (AnjutaShell
*shell
, AnjutaSessionPhase phase
, AnjutaSession
*session
, ExprWatch
*ew
)
478 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
481 list
= debug_tree_get_full_watch_list (ew
->debug_tree
);
483 anjuta_session_set_string_list (session
, "Debugger", "Watch", list
);
484 g_list_foreach (list
, (GFunc
)g_free
, NULL
);
489 on_session_load (AnjutaShell
*shell
, AnjutaSessionPhase phase
, AnjutaSession
*session
, ExprWatch
*ew
)
493 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
496 /* debug_tree_remove_all (ew->debug_tree); */
497 list
= anjuta_session_get_string_list (session
, "Debugger", "Watch");
499 debug_tree_add_full_watch_list (ew
->debug_tree
, list
);
502 /* Constructor & Destructor
503 *---------------------------------------------------------------------------*/
506 expr_watch_new (AnjutaPlugin
*plugin
, IAnjutaDebugger
*debugger
)
510 ew
= g_new0 (ExprWatch
, 1);
512 create_expr_watch_gui (ew
);
513 g_object_ref (debugger
);
514 ew
->debugger
= debugger
;
516 /* Connect to Load and Save event */
517 g_signal_connect (plugin
->shell
, "save-session",
518 G_CALLBACK (on_session_save
), ew
);
519 g_signal_connect (plugin
->shell
, "load-session",
520 G_CALLBACK (on_session_load
), ew
);
522 /* Add watch window */
523 anjuta_shell_add_widget (plugin
->shell
,
525 "AnjutaDebuggerWatch", _("Watches"),
526 "gdb-watch-icon", ANJUTA_SHELL_PLACEMENT_BOTTOM
,
534 expr_watch_destroy (ExprWatch
* ew
)
538 g_return_if_fail (ew
!= NULL
);
540 /* Disconnect from Load and Save event */
541 g_signal_handlers_disconnect_by_func (ew
->plugin
->shell
, G_CALLBACK (on_session_save
), ew
);
542 g_signal_handlers_disconnect_by_func (ew
->plugin
->shell
, G_CALLBACK (on_session_load
), ew
);
544 ui
= anjuta_shell_get_ui (ew
->plugin
->shell
, NULL
);
545 anjuta_ui_remove_action_group (ui
, ew
->action_group
);
546 anjuta_ui_remove_action_group (ui
, ew
->toggle_group
);
548 debug_tree_free (ew
->debug_tree
);
549 gtk_widget_destroy (ew
->scrolledwindow
);