Fix a Gtk warning when checking path input in the log viewer.
[anjuta-git-plugin.git] / plugins / debug-manager / watch.c
blob6b64d46eb39527440a21367e5c2917f28b53a426
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * watch.c Copyright (C) 2000 Kh. Naba Kumar Singh
4 *
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)
8 * any later version.
9 *
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
13 * more details.
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.,
17 * 59 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
23 #include "watch.h"
25 #include "debug_tree.h"
26 #include "utilities.h"
28 /*#define DEBUG*/
29 #include <libanjuta/anjuta-debug.h>
30 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
31 #include <libanjuta/interfaces/ianjuta-editor.h>
32 #include <libanjuta/interfaces/ianjuta-document-manager.h>
34 /* Type
35 *---------------------------------------------------------------------------*/
37 struct _ExprWatch
39 AnjutaPlugin *plugin;
41 GtkWidget *scrolledwindow;
42 DebugTree *debug_tree;
43 DmaDebuggerQueue *debugger;
45 /* Menu action */
46 GtkActionGroup *action_group;
47 GtkActionGroup *toggle_group;
50 struct _InspectDialog
52 DebugTree *tree;
53 GtkWidget *treeview;
54 GtkWidget *dialog;
57 typedef struct _InspectDialog InspectDialog;
59 /* Widget and signal name found in glade file
60 *---------------------------------------------------------------------------*/
62 #define ADD_WATCH_DIALOG "add_watch_dialog"
63 #define CHANGE_WATCH_DIALOG "change_watch_dialog"
64 #define INSPECT_EVALUATE_DIALOG "watch_dialog"
65 #define NAME_ENTRY "name_entry"
66 #define VALUE_ENTRY "value_entry"
67 #define VALUE_TREE "value_treeview"
68 #define AUTO_UPDATE_CHECK "auto_update_check"
70 /* Private functions
71 *---------------------------------------------------------------------------*/
73 #if 0
74 static void
75 on_entry_updated (const gchar *value, gpointer user_data, GError *err)
77 GtkWidget *entry = GTK_WIDGET (user_data);
79 gtk_entry_set_text (GTK_ENTRY (entry), value);
80 gtk_widget_unref (entry);
82 #endif
84 static void
85 debug_tree_inspect_evaluate_dialog (ExprWatch * ew, const gchar* expression)
87 GladeXML *gxml;
88 gint reply;
89 gchar *new_expr;
90 // const gchar *value;
91 InspectDialog dlg;
92 IAnjutaDebuggerVariableObject var = {NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, -1};
94 gxml = glade_xml_new (GLADE_FILE, INSPECT_EVALUATE_DIALOG, NULL);
95 dlg.dialog = glade_xml_get_widget (gxml, INSPECT_EVALUATE_DIALOG);
96 gtk_window_set_transient_for (GTK_WINDOW (dlg.dialog),
97 NULL);
98 dlg.treeview = glade_xml_get_widget (gxml, VALUE_TREE);
99 g_object_unref (gxml);
101 /* Create debug tree */
102 dlg.tree = debug_tree_new_with_view (ANJUTA_PLUGIN (ew->plugin), GTK_TREE_VIEW (dlg.treeview));
103 if (ew->debugger)
104 debug_tree_connect (dlg.tree, ew->debugger);
105 if (expression != NULL)
107 var.expression = (gchar *)expression;
108 debug_tree_add_watch (dlg.tree, &var, FALSE);
110 else
112 debug_tree_add_dummy (dlg.tree, NULL);
115 for(;;)
117 reply = gtk_dialog_run (GTK_DIALOG (dlg.dialog));
118 switch (reply)
120 case GTK_RESPONSE_OK:
121 /* Add in watch window */
122 new_expr = debug_tree_get_first (dlg.tree);
124 if (new_expr != NULL)
126 var.expression = new_expr;
127 debug_tree_add_watch (ew->debug_tree, &var, FALSE);
128 g_free (new_expr);
130 break;
131 default:
132 break;
134 break;
136 debug_tree_free (dlg.tree);
137 gtk_widget_destroy (dlg.dialog);
140 static void
141 debug_tree_add_watch_dialog (ExprWatch *ew, const gchar* expression)
143 GladeXML *gxml;
144 GtkWidget *dialog;
145 GtkWidget *name_entry;
146 GtkWidget *auto_update_check;
147 gint reply;
148 IAnjutaDebuggerVariableObject var = {NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, -1};
150 gxml = glade_xml_new (GLADE_FILE, ADD_WATCH_DIALOG, NULL);
151 dialog = glade_xml_get_widget (gxml, ADD_WATCH_DIALOG);
152 gtk_window_set_transient_for (GTK_WINDOW (dialog),
153 NULL);
154 auto_update_check = glade_xml_get_widget (gxml, AUTO_UPDATE_CHECK);
155 name_entry = glade_xml_get_widget (gxml, NAME_ENTRY);
156 g_object_unref (gxml);
158 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_update_check), TRUE);
159 gtk_entry_set_text (GTK_ENTRY (name_entry), expression == NULL ? "" : expression);
161 reply = gtk_dialog_run (GTK_DIALOG (dialog));
162 if (reply == GTK_RESPONSE_OK)
164 var.expression = (gchar *)gtk_entry_get_text (GTK_ENTRY (name_entry));
165 debug_tree_add_watch (ew->debug_tree, &var,
166 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (auto_update_check)));
168 gtk_widget_destroy (dialog);
171 static void
172 debug_tree_change_watch_dialog (ExprWatch *ew, GtkTreeIter* iter)
174 #if 0
175 GladeXML *gxml;
176 GtkWidget *dialog;
177 GtkWidget *name_entry;
178 GtkWidget *value_entry;
179 gint reply;
180 TrimmableItem *item = NULL;
181 GtkTreeModel* model = NULL;
183 model = gtk_tree_view_get_model(d_tree->view);
184 gtk_tree_model_get (model, iter, ITEM_COLUMN, &item, -1);
186 gxml = glade_xml_new (GLADE_FILE, CHANGE_WATCH_DIALOG, NULL);
187 dialog = glade_xml_get_widget (gxml, CHANGE_WATCH_DIALOG);
188 gtk_window_set_transient_for (GTK_WINDOW (dialog),
189 NULL);
190 name_entry = glade_xml_get_widget (gxml, NAME_ENTRY);
191 value_entry = glade_xml_get_widget (gxml, VALUE_ENTRY);
192 g_object_unref (gxml);
194 gtk_widget_grab_focus (value_entry);
195 gtk_entry_set_text (GTK_ENTRY (name_entry), &item->name[1]);
196 gtk_entry_set_text (GTK_ENTRY (value_entry), item->value);
198 reply = gtk_dialog_run (GTK_DIALOG (dialog));
199 if (reply == GTK_RESPONSE_APPLY)
201 debug_tree_evaluate (d_tree, iter, gtk_entry_get_text (GTK_ENTRY (value_entry)));
203 gtk_widget_destroy (dialog);
204 #endif
207 static void
208 on_program_stopped (ExprWatch *ew)
210 debug_tree_update_all (ew->debug_tree);
213 static void
214 on_program_exited (ExprWatch *ew)
216 debug_tree_disconnect (ew->debug_tree);
218 /* Disconnect to other debugger signal */
219 g_signal_handlers_disconnect_by_func (ew->plugin, G_CALLBACK (on_program_exited), ew);
220 g_signal_handlers_disconnect_by_func (ew->plugin, G_CALLBACK (on_program_stopped), ew);
223 static void
224 on_program_started (ExprWatch *ew)
226 if (!dma_debugger_queue_is_supported (ew->debugger, HAS_VARIABLE)) return;
228 debug_tree_connect (ew->debug_tree, ew->debugger);
230 /* Connect to other debugger signal */
231 g_signal_connect_swapped (ew->plugin, "program-exited", G_CALLBACK (on_program_exited), ew);
232 g_signal_connect_swapped (ew->plugin, "program-stopped", G_CALLBACK (on_program_stopped), ew);
235 /* Menu call backs
236 *---------------------------------------------------------------------------*/
238 static void
239 on_debug_tree_inspect (GtkAction *action, gpointer user_data)
241 ExprWatch * ew = (ExprWatch *)user_data;
242 IAnjutaEditor *te = NULL;
243 gchar *expression = NULL;
245 /* Get current editor and line */
246 te = dma_get_current_editor (ANJUTA_PLUGIN (ew->plugin));
247 if (te == NULL) return;
249 expression = ianjuta_editor_selection_get (IANJUTA_EDITOR_SELECTION (te), NULL);
250 if (expression == NULL)
252 expression = ianjuta_editor_get_current_word (IANJUTA_EDITOR (te), NULL);
255 debug_tree_inspect_evaluate_dialog (ew, expression);
256 g_free (expression);
259 static void
260 on_debug_tree_add_watch (GtkAction *action, gpointer user_data)
262 ExprWatch * ew = (ExprWatch *)user_data;
264 debug_tree_add_watch_dialog (ew, NULL);
267 static void
268 on_debug_tree_remove_watch (GtkAction *action, gpointer user_data)
270 ExprWatch * ew = (ExprWatch *)user_data;
271 GtkTreeIter iter;
273 if (debug_tree_get_current (ew->debug_tree, &iter))
275 debug_tree_remove (ew->debug_tree, &iter);
279 static void
280 on_debug_tree_update_watch (GtkAction *action, gpointer user_data)
282 ExprWatch * ew = (ExprWatch *)user_data;
283 GtkTreeIter iter;
285 if (debug_tree_get_current (ew->debug_tree, &iter))
287 debug_tree_update (ew->debug_tree, &iter, TRUE);
291 static void
292 on_debug_tree_auto_update_watch (GtkAction *action, gpointer user_data)
294 ExprWatch * ew = (ExprWatch *)user_data;
295 GtkTreeIter iter;
297 if (debug_tree_get_current (ew->debug_tree, &iter))
299 gboolean state;
301 state = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
302 debug_tree_set_auto_update (ew->debug_tree, &iter, state);
306 static void
307 on_debug_tree_edit_watch (GtkAction *action, gpointer user_data)
309 ExprWatch * ew = (ExprWatch *)user_data;
310 GtkTreeIter iter;
312 if (debug_tree_get_current (ew->debug_tree, &iter))
314 debug_tree_change_watch_dialog (ew, &iter);
318 static void
319 on_debug_tree_update_all_watch (GtkAction *action, gpointer user_data)
321 ExprWatch * ew = (ExprWatch *)user_data;
323 debug_tree_update_all (ew->debug_tree);
326 static void
327 on_debug_tree_remove_all_watch (GtkAction *action, gpointer user_data)
329 ExprWatch * ew = (ExprWatch *)user_data;
331 debug_tree_remove_all (ew->debug_tree);
334 static gboolean
335 on_debug_tree_button_press (GtkWidget *widget, GdkEventButton *bevent, gpointer user_data)
337 ExprWatch * ew = (ExprWatch *)user_data;
339 if (bevent->button == 3)
341 GtkAction *action;
342 AnjutaUI *ui;
343 GtkTreeIter iter;
344 GtkWidget *middle_click_menu;
346 ui = anjuta_shell_get_ui (ew->plugin->shell, NULL);
347 action = anjuta_ui_get_action (ui, "ActionGroupWatchToggle", "ActionDmaAutoUpdateWatch");
348 if (debug_tree_get_current (ew->debug_tree, &iter))
350 gtk_action_set_sensitive (GTK_ACTION (action), TRUE);
351 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), debug_tree_get_auto_update (ew->debug_tree, &iter));
353 else
355 gtk_action_set_sensitive (GTK_ACTION (action), FALSE);
358 action = anjuta_ui_get_action (ui, "ActionGroupWatch", "ActionDmaEditWatch");
359 gtk_action_set_sensitive (GTK_ACTION (action), FALSE); // FIXME: Not implemented
361 middle_click_menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui), "/PopupWatch");
362 g_return_val_if_fail (middle_click_menu != NULL, FALSE);
363 gtk_menu_popup (GTK_MENU (middle_click_menu), NULL, NULL, NULL, NULL,
364 bevent->button, bevent->time);
367 return FALSE;
370 /* Actions table
371 *---------------------------------------------------------------------------*/
373 static GtkActionEntry actions_watch[] = {
375 "ActionDmaInspect", /* Action name */
376 GTK_STOCK_DIALOG_INFO, /* Stock icon, if any */
377 N_("Ins_pect/Evaluate..."), /* Display label */
378 NULL, /* short-cut */
379 N_("Inspect or evaluate an expression or variable"), /* Tooltip */
380 G_CALLBACK (on_debug_tree_inspect) /* action callback */
383 "ActionDmaAddWatch",
384 NULL,
385 N_("Add Watch..."),
386 NULL,
387 NULL,
388 G_CALLBACK (on_debug_tree_add_watch)
391 "ActionDmaRemoveWatch",
392 NULL,
393 N_("Remove Watch"),
394 NULL,
395 NULL,
396 G_CALLBACK (on_debug_tree_remove_watch)
399 "ActionDmaUpdateWatch",
400 NULL,
401 N_("Update Watch"),
402 NULL,
403 NULL,
404 G_CALLBACK (on_debug_tree_update_watch)
407 "ActionDmaEditWatch",
408 NULL,
409 N_("Change Value"),
410 NULL,
411 NULL,
412 G_CALLBACK (on_debug_tree_edit_watch)
415 "ActionDmaUpdateAllWatch",
416 NULL,
417 N_("Update all"),
418 NULL,
419 NULL,
420 G_CALLBACK (on_debug_tree_update_all_watch)
423 "ActionDmaRemoveAllWatch",
424 NULL,
425 N_("Remove all"),
426 NULL,
427 NULL,
428 G_CALLBACK (on_debug_tree_remove_all_watch)
432 static GtkToggleActionEntry toggle_watch[] = {
434 "ActionDmaAutoUpdateWatch", /* Action name */
435 NULL, /* Stock icon, if any */
436 N_("Automatic update"), /* Display label */
437 NULL, /* short-cut */
438 NULL, /* Tooltip */
439 G_CALLBACK (on_debug_tree_auto_update_watch), /* action callback */
440 FALSE /* Initial state */
444 static void
445 create_expr_watch_gui (ExprWatch * ew)
447 AnjutaUI *ui;
449 ew->debug_tree = debug_tree_new (ew->plugin);
450 ew->scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
451 gtk_widget_show (ew->scrolledwindow);
452 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ew->scrolledwindow),
453 GTK_POLICY_AUTOMATIC,
454 GTK_POLICY_AUTOMATIC);
455 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (ew->scrolledwindow),
456 GTK_SHADOW_IN);
457 gtk_container_add (GTK_CONTAINER (ew->scrolledwindow), debug_tree_get_tree_widget (ew->debug_tree));
459 ui = anjuta_shell_get_ui (ew->plugin->shell, NULL);
460 ew->action_group =
461 anjuta_ui_add_action_group_entries (ui, "ActionGroupWatch",
462 _("Watch operations"),
463 actions_watch,
464 G_N_ELEMENTS (actions_watch),
465 GETTEXT_PACKAGE, TRUE, ew);
466 ew->toggle_group =
467 anjuta_ui_add_toggle_action_group_entries (ui, "ActionGroupWatchToggle",
468 _("Watch operations"),
469 toggle_watch,
470 G_N_ELEMENTS (toggle_watch),
471 GETTEXT_PACKAGE, TRUE, ew);
472 g_signal_connect (debug_tree_get_tree_widget (ew->debug_tree), "button-press-event", G_CALLBACK (on_debug_tree_button_press), ew);
474 gtk_widget_show_all (ew->scrolledwindow);
477 /* Public function
478 *---------------------------------------------------------------------------*/
480 gchar*
481 expr_watch_find_variable_value (ExprWatch *ew, const gchar *name)
483 return debug_tree_find_variable_value (ew->debug_tree, name);
486 /* Callback for saving session
487 *---------------------------------------------------------------------------*/
489 static void
490 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, ExprWatch *ew)
492 GList *list;
494 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
495 return;
497 list = debug_tree_get_full_watch_list (ew->debug_tree);
498 if (list != NULL)
499 anjuta_session_set_string_list (session, "Debugger", "Watch", list);
500 g_list_foreach (list, (GFunc)g_free, NULL);
501 g_list_free (list);
504 static void
505 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, ExprWatch *ew)
507 GList *list;
509 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
510 return;
512 /* debug_tree_remove_all (ew->debug_tree); */
513 list = anjuta_session_get_string_list (session, "Debugger", "Watch");
514 if (list != NULL)
515 debug_tree_add_full_watch_list (ew->debug_tree, list);
518 /* Constructor & Destructor
519 *---------------------------------------------------------------------------*/
521 ExprWatch *
522 expr_watch_new (AnjutaPlugin *plugin)
524 ExprWatch *ew;
526 ew = g_new0 (ExprWatch, 1);
527 ew->plugin = plugin;
528 create_expr_watch_gui (ew);
529 ew->debugger = dma_debug_manager_get_queue (ANJUTA_PLUGIN_DEBUG_MANAGER (plugin));
531 /* Connect to Load and Save event */
532 g_signal_connect (ew->plugin->shell, "save-session",
533 G_CALLBACK (on_session_save), ew);
534 g_signal_connect (ew->plugin->shell, "load-session",
535 G_CALLBACK (on_session_load), ew);
537 /* Add watch window */
538 anjuta_shell_add_widget (ew->plugin->shell,
539 ew->scrolledwindow,
540 "AnjutaDebuggerWatch", _("Watches"),
541 "gdb-watch-icon", ANJUTA_SHELL_PLACEMENT_BOTTOM,
542 NULL);
544 /* Connect to debugger */
545 g_signal_connect_swapped (ew->plugin, "program-started", G_CALLBACK (on_program_started), ew);
547 return ew;
550 void
551 expr_watch_destroy (ExprWatch * ew)
553 AnjutaUI *ui;
555 g_return_if_fail (ew != NULL);
557 /* Disconnect from Load and Save event */
558 g_signal_handlers_disconnect_matched (ew->plugin->shell, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, ew);
559 g_signal_handlers_disconnect_matched (ew->plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, ew);
561 ui = anjuta_shell_get_ui (ew->plugin->shell, NULL);
562 anjuta_ui_remove_action_group (ui, ew->action_group);
563 anjuta_ui_remove_action_group (ui, ew->toggle_group);
565 debug_tree_free (ew->debug_tree);
566 gtk_widget_destroy (ew->scrolledwindow);
567 g_free (ew);