Fix #530740 – Use GtkBuilder instead of libglade
[anjuta-extras.git] / plugins / profiler / plugin.c
blob56b0ec128b7c68e58cc285b412dff13617605e63
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * plugin.c
4 * Copyright (C) James Liggett 2006 <jrliggett@cox.net>
5 *
6 * plugin.c is free software.
7 *
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2, or (at your option) any later version.
12 * plugin.c is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 * See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with plugin.c. See the file "COPYING". If not,
19 * write to: The Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
25 #include "plugin.h"
28 #define UI_FILE PACKAGE_DATA_DIR"/ui/profiler.xml"
29 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/profiler.ui"
30 #define ICON_FILE PACKAGE_PIXMAPS_DIR"/anjuta-profiler-plugin-48.png"
32 static gpointer parent_class;
34 static void
35 add_options_strings (GPtrArray *options, const gchar *prefix, const gchar *args)
37 gchar **split_args; /* List of arguements split by lines */
38 gchar **current_string;
39 gchar *full_arg; /* Argument with prefix */
41 if (strlen (args) > 0)
43 split_args = g_strsplit (args, "\n", -1);
45 for (current_string = split_args;
46 *current_string;
47 current_string++)
50 if (strlen (*current_string) > 0)
52 full_arg = g_strconcat (prefix, *current_string, NULL);
53 g_ptr_array_add (options, full_arg);
57 g_strfreev (split_args);
61 static GPtrArray *
62 setup_options (Profiler *profiler)
64 GPtrArray *options;
65 gchar *symbols;
67 options = g_ptr_array_new ();
69 /* First handle the easy ones: -a, -c, and -z */
70 if (gprof_options_get_int (profiler->options, "no_show_static"))
72 g_ptr_array_add (options, g_strdup ("-a"));
75 if (gprof_options_get_int (profiler->options, "show_possible_called"))
77 g_ptr_array_add (options, g_strdup ("-c"));
80 if (gprof_options_get_int (profiler->options, "show_uncalled"))
82 g_ptr_array_add (options, g_strdup ("-z"));
85 /* If the user wants to modify the call graph, put in -p so we have a flat
86 * profile. */
87 if (!gprof_options_get_int (profiler->options, "show_all_symbols"))
89 g_ptr_array_add (options, g_strdup ("-p"));
91 symbols = gprof_options_get_string (profiler->options, "symbols");
93 if (gprof_options_get_int (profiler->options, "include_symbols"))
95 add_options_strings (options, "-q", symbols);
98 if (gprof_options_get_int (profiler->options, "exclude_symbols"))
100 add_options_strings (options, "-Q", symbols);
103 g_free (symbols);
106 /* Time propagation options */
107 if (!gprof_options_get_int (profiler->options, "propagate_all_symbols"))
110 symbols = gprof_options_get_string (profiler->options,
111 "propagation_symbols");
113 if (gprof_options_get_int (profiler->options,
114 "propagate_include_symbols"))
116 add_options_strings (options, "-n", symbols);
119 if (gprof_options_get_int (profiler->options,
120 "propagate_exclude_symbols"))
122 add_options_strings (options, "-N", symbols);
125 g_free (symbols);
128 /* NULL terminate the array for compatibility with g_strfreev */
130 g_ptr_array_add (options, NULL);
132 /* Other options not directly passed to gprof */
134 /* If there is an existing profile data monitor and automatic refresh
135 * is disabled, cancel the monitor */
137 if (profiler->profile_data_monitor)
139 if (!gprof_options_get_int (profiler->options, "automatic_refresh"))
141 g_file_monitor_cancel (profiler->profile_data_monitor);
142 g_object_unref (profiler->profile_data_monitor);
143 profiler->profile_data_monitor = NULL;
147 return options;
150 static gboolean
151 profiler_get_data (Profiler *profiler)
153 GPtrArray *options;
154 gchar **option_strings;
155 gchar *profiling_data_path;
156 gchar *profiling_data_path_from_options;
157 gboolean ret = FALSE;
159 if (profiler->profile_target_path)
162 options = setup_options (profiler);
164 profiling_data_path_from_options = gprof_options_get_string (profiler->options,
165 "profile_data_file");
167 if (strlen (profiling_data_path_from_options) > 0)
168 profiling_data_path = profiling_data_path_from_options;
169 else
170 profiling_data_path = NULL;
172 if (!gprof_profile_data_init_profile (profiler->profile_data,
173 profiler->profile_target_path,
174 profiling_data_path,
175 options))
177 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (profiler)->shell),
178 _("Could not get profiling data."
179 "\n\n"
180 "Please check the path to "
181 "this target's profiling data file."));
184 option_strings = (gchar **) g_ptr_array_free (options, FALSE);
185 g_free (profiling_data_path_from_options);
186 g_strfreev (option_strings);
188 ret = TRUE;
191 return ret;
194 static void
195 on_profile_data_changed (GFileMonitor *monitor,
196 GFile *file,
197 GFile *other_file,
198 GFileMonitorEvent event_type,
199 gpointer user_data)
201 DEBUG_PRINT ("%s", "Data changed called");
202 Profiler *profiler;
204 profiler = PROFILER (user_data);
206 switch (event_type)
208 case G_FILE_MONITOR_EVENT_CHANGED:
209 if (profiler_get_data (profiler))
210 gprof_view_manager_refresh_views (profiler->view_manager);
211 break;
212 case G_FILE_MONITOR_EVENT_DELETED:
213 g_file_monitor_cancel (monitor);
214 g_object_unref (profiler->profile_data_monitor);
215 profiler->profile_data_monitor = NULL;
216 break;
217 default:
218 break;
222 static void
223 profiler_set_target (Profiler *profiler, const gchar *profile_target_uri)
225 gchar *profile_target_path;
226 gchar *profile_target_dir;
227 gchar *profile_data_path;
228 gchar *profile_data_path_from_options;
229 gchar *profile_data_uri;
230 GFile *file;
232 if (profiler->profile_target_path)
234 g_free (profiler->profile_target_path);
235 profiler->profile_target_path = NULL;
238 if (profile_target_uri)
240 profile_target_path = anjuta_util_get_local_path_from_uri (profile_target_uri);
242 profile_data_path_from_options = gprof_options_get_string (profiler->options,
243 "profile_data_file");
245 if (strlen (profile_data_path_from_options) > 0)
247 profile_data_path = g_strdup (profile_data_path_from_options);
248 profile_target_dir = NULL;
250 else
252 profile_target_dir = g_path_get_dirname (profile_target_path);
253 profile_data_path = g_build_filename (profile_target_dir, "gmon.out",
254 NULL);
257 g_free (profile_data_path_from_options);
259 file = g_file_new_for_path (profile_data_path);
260 profile_data_uri = g_file_get_uri (file);
261 g_object_unref (file);
263 if (g_file_test (profile_data_path, G_FILE_TEST_EXISTS))
265 profiler->profile_target_path = profile_target_path;
268 /* Set up a file change monitor for automatic refresh if enabled */
269 if (gprof_options_get_int (profiler->options,
270 "automatic_refresh"))
272 /* Cancel any existing monitor */
273 if (profiler->profile_data_monitor)
274 g_file_monitor_cancel (profiler->profile_data_monitor);
275 file = g_file_new_for_uri (profile_data_uri);
276 profiler->profile_data_monitor =
277 g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
278 g_signal_connect (G_OBJECT (profiler->profile_data_monitor),
279 "changed", G_CALLBACK (on_profile_data_changed),
280 profiler);
283 /* Show user the profiler views if they aren't visible so they
284 * know what happened */
285 anjuta_shell_present_widget (ANJUTA_PLUGIN (profiler)->shell,
286 gprof_view_manager_get_notebook (profiler->view_manager),
287 NULL);
289 else
291 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (profiler)->shell),
292 _("This target does not have any "
293 "profiling data.\n\n"
294 "Please ensure that the target is "
295 "complied with profiling support "
296 "and that it is run at least "
297 "once."));
300 g_free (profile_target_dir);
301 g_free (profile_data_path);
302 g_free (profile_data_uri);
306 static GProfOptions *
307 register_options ()
309 GProfOptions *options;
311 options = gprof_options_new ();
313 gprof_options_register_key (options, "automatic_refresh", "0",
314 "automatic_refresh_check",
315 OPTION_TYPE_TOGGLE);
317 gprof_options_register_key (options, "no_show_static", "0",
318 "no_show_static_check",
319 OPTION_TYPE_TOGGLE);
321 gprof_options_register_key (options, "show_possible_called", "0",
322 "show_possible_called_check",
323 OPTION_TYPE_TOGGLE);
325 gprof_options_register_key (options, "show_uncalled", "0",
326 "show_uncalled_check",
327 OPTION_TYPE_TOGGLE);
329 gprof_options_register_key (options, "show_all_symbols", "1",
330 "show_all_symbols_radio",
331 OPTION_TYPE_TOGGLE);
333 gprof_options_register_key (options, "include_symbols", "0",
334 "include_symbols_radio",
335 OPTION_TYPE_TOGGLE);
337 gprof_options_register_key (options, "exclude_symbols", "0",
338 "exclude_symbols_radio",
339 OPTION_TYPE_TOGGLE);
341 gprof_options_register_key (options, "symbols", "", "symbols_text_view",
342 OPTION_TYPE_TEXT_ENTRY);
344 gprof_options_register_key (options, "propagate_all_symbols", "1",
345 "propagate_all_symbols_radio",
346 OPTION_TYPE_TOGGLE);
348 gprof_options_register_key (options, "propagate_include_symbols", "0",
349 "propagate_include_symbols_radio",
350 OPTION_TYPE_TOGGLE);
352 gprof_options_register_key (options, "propagate_exclude_symbols", "0",
353 "propagate_exclude_symbols_radio",
354 OPTION_TYPE_TOGGLE);
356 gprof_options_register_key (options, "propagation_symbols", "",
357 "propagation_text_view",
358 OPTION_TYPE_TEXT_ENTRY);
360 gprof_options_register_key (options, "profile_data_file", "",
361 "profile_data_file_entry",
362 OPTION_TYPE_ENTRY);
364 return options;
367 static void
368 on_profile_data_browse_button_clicked (GtkButton *button, GtkBuilder *bxml)
370 GtkWidget *select_file_dialog;
371 GtkWidget *profile_data_file_entry;
372 GtkWidget *profiling_options_dialog;
373 gchar *selected_file;
375 profile_data_file_entry = GTK_WIDGET (gtk_builder_get_object (bxml, "profile_data_file_entry"));
376 profiling_options_dialog = GTK_WIDGET (gtk_builder_get_object (bxml,
377 "profiling_options_dialog"));
378 select_file_dialog = gtk_file_chooser_dialog_new ("Select Data File",
379 GTK_WINDOW (profiling_options_dialog),
380 GTK_FILE_CHOOSER_ACTION_OPEN,
381 GTK_STOCK_CANCEL,
382 GTK_RESPONSE_CANCEL,
383 GTK_STOCK_OPEN,
384 GTK_RESPONSE_ACCEPT,
385 NULL);
387 if (gtk_dialog_run (GTK_DIALOG (select_file_dialog)) == GTK_RESPONSE_ACCEPT)
389 selected_file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (select_file_dialog));
390 gtk_entry_set_text (GTK_ENTRY (profile_data_file_entry), selected_file);
391 g_free (selected_file);
394 gtk_widget_destroy (select_file_dialog);
397 static void
398 on_profiling_options_button_clicked (GtkButton *button, gpointer *user_data)
400 Profiler *profiler;
401 GtkBuilder *bxml= gtk_builder_new ();
402 GtkWidget *profiling_options_dialog;
403 GtkWidget *profile_data_browse_button;
404 GError* error = NULL;
406 profiler = PROFILER (user_data);
407 if (!gtk_builder_add_from_file (bxml, GLADE_FILE, &error))
409 g_warning ("Couldn't load builder file: %s", error->message);
410 g_error_free (error);
412 profiling_options_dialog = GTK_WIDGET (gtk_builder_get_object (bxml, "profiling_options_dialog"));
413 profile_data_browse_button = GTK_WIDGET (gtk_builder_get_object (bxml,
414 "profile_data_browse_button"));
416 g_signal_connect (profile_data_browse_button, "clicked",
417 G_CALLBACK (on_profile_data_browse_button_clicked),
418 bxml);
420 g_signal_connect (profiling_options_dialog, "response", G_CALLBACK (gtk_widget_hide),
421 profiling_options_dialog);
423 gprof_options_create_window (profiler->options, bxml);
425 gtk_window_set_transient_for (GTK_WINDOW (profiling_options_dialog),
426 GTK_WINDOW (ANJUTA_PLUGIN(profiler)->shell));
428 gtk_dialog_run (GTK_DIALOG (profiling_options_dialog));
430 g_object_unref (bxml);
433 static void
434 on_select_other_target_button_clicked (GtkButton *button,
435 GtkTreeView *targets_list_view)
437 GtkTreeModel *model;
438 GtkWidget *target_chooser_dialog;
439 GtkTreeIter iter;
440 gchar *selected_target_path;
441 gchar *selected_target_uri;
442 GtkTreeSelection *selection;
443 GtkTreePath *new_target_path;
444 GFile *file;
446 model = gtk_tree_view_get_model (targets_list_view);
447 target_chooser_dialog = gtk_file_chooser_dialog_new ("Select Target",
448 NULL,
449 GTK_FILE_CHOOSER_ACTION_OPEN,
450 GTK_STOCK_CANCEL,
451 GTK_RESPONSE_CANCEL,
452 GTK_STOCK_OPEN,
453 GTK_RESPONSE_ACCEPT,
454 NULL);
456 if (gtk_dialog_run (GTK_DIALOG (target_chooser_dialog)) == GTK_RESPONSE_ACCEPT)
458 selected_target_path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (target_chooser_dialog));
459 file = g_file_new_for_path (selected_target_path);
460 selected_target_uri = g_file_get_uri (file);
461 g_object_unref (file);
463 selection = gtk_tree_view_get_selection (targets_list_view);
465 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
466 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0,
467 selected_target_path, 1,
468 selected_target_uri, -1);
470 gtk_tree_selection_select_iter (selection, &iter);
471 new_target_path = gtk_tree_model_get_path (model, &iter);
472 gtk_tree_view_scroll_to_cell (targets_list_view, new_target_path, NULL,
473 TRUE, 0.5, 0.0);
475 g_free (selected_target_path);
476 g_free (selected_target_uri);
477 gtk_tree_path_free (new_target_path);
480 gtk_widget_destroy (target_chooser_dialog);
483 static gboolean
484 on_target_selected (GtkTreeSelection *selection, GtkTreeModel *model,
485 GtkTreePath *path, gboolean path_currently_selected,
486 Profiler *profiler)
488 GtkTreeIter list_iter;
489 gchar *target_uri;
491 gtk_tree_model_get_iter (model, &list_iter, path);
492 gtk_tree_model_get (model, &list_iter, 1, &target_uri, -1);
494 if (target_uri)
496 gprof_options_set_target (profiler->options, target_uri);
497 g_free (target_uri);
500 return TRUE;
503 static void
504 on_profiler_select_target (GtkAction *action, Profiler *profiler)
506 GtkBuilder *bxml= gtk_builder_new ();
507 GtkWidget *select_target_dialog;
508 GtkWidget *profiling_options_button;
509 GtkWidget *select_other_target_button;
510 GtkWidget *targets_list_view;
511 GtkTreeViewColumn *column;
512 GtkCellRenderer *renderer;
513 GtkListStore *targets_list_store;
514 gint response;
515 GList *current_target;
516 GtkTreeIter iter;
517 GList *exec_targets;
518 IAnjutaProjectManager *project_manager;
519 GtkTreeSelection *selection;
520 GtkTreeModel *model;
521 gchar *target = NULL;
522 gchar *relative_path;
523 guint project_root_uri_length;
524 GError* error = NULL;
526 if (!gtk_builder_add_from_file (bxml, GLADE_FILE, &error))
528 g_warning ("Couldn't load builder file: %s", error->message);
529 g_error_free (error);
532 select_target_dialog = GTK_WIDGET (gtk_builder_get_object (bxml,
533 "select_target_dialog"));
534 targets_list_view = GTK_WIDGET (gtk_builder_get_object (bxml,
535 "targets_list_view"));
536 profiling_options_button = GTK_WIDGET (gtk_builder_get_object (bxml,
537 "profiling_options_button"));
538 select_other_target_button = GTK_WIDGET (gtk_builder_get_object (bxml,
539 "select_other_target_button"));
541 g_signal_connect (profiling_options_button, "clicked",
542 G_CALLBACK (on_profiling_options_button_clicked),
543 profiler);
545 g_signal_connect (select_other_target_button, "clicked",
546 G_CALLBACK (on_select_other_target_button_clicked),
547 targets_list_view);
549 gtk_window_set_transient_for (GTK_WINDOW (select_target_dialog),
550 GTK_WINDOW (ANJUTA_PLUGIN(profiler)->shell));
552 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (targets_list_view));
553 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
554 gtk_tree_selection_set_select_function (selection,
555 (GtkTreeSelectionFunc) on_target_selected,
556 profiler, NULL);
557 targets_list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
559 column = gtk_tree_view_column_new ();
560 gtk_tree_view_column_set_sizing (column,
561 GTK_TREE_VIEW_COLUMN_AUTOSIZE);
563 renderer = gtk_cell_renderer_text_new ();
564 gtk_tree_view_column_pack_start (column, renderer, FALSE);
565 gtk_tree_view_column_add_attribute (column, renderer, "text",
567 gtk_tree_view_append_column (GTK_TREE_VIEW (targets_list_view), column);
568 gtk_tree_view_set_expander_column (GTK_TREE_VIEW (targets_list_view), column);
570 if (profiler->project_root_uri)
572 project_manager = anjuta_shell_get_interface (ANJUTA_PLUGIN (profiler)->shell,
573 IAnjutaProjectManager, NULL);
575 exec_targets = ianjuta_project_manager_get_targets (project_manager,
576 IANJUTA_PROJECT_MANAGER_TARGET_EXECUTABLE,
577 NULL);
579 project_root_uri_length = strlen (profiler->project_root_uri) + 1;
581 if (exec_targets)
583 /* Populate listview */
584 current_target = exec_targets;
586 while (current_target)
588 relative_path = (gchar *) current_target->data + project_root_uri_length;
590 gtk_list_store_append (targets_list_store, &iter);
591 gtk_list_store_set (targets_list_store, &iter, 0, relative_path, 1,
592 current_target->data, -1);
594 g_free (current_target->data);
595 current_target = g_list_next (current_target);
597 g_list_free (exec_targets);
599 gtk_tree_view_set_model (GTK_TREE_VIEW (targets_list_view),
600 GTK_TREE_MODEL (targets_list_store));
601 g_object_unref (targets_list_store);
604 else
606 gtk_tree_view_set_model (GTK_TREE_VIEW (targets_list_view),
607 GTK_TREE_MODEL (targets_list_store));
608 g_object_unref (targets_list_store);
611 /* Run dialog */
612 response = gtk_dialog_run (GTK_DIALOG (select_target_dialog));
614 if (response == GTK_RESPONSE_OK)
616 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (targets_list_view));
617 if (gtk_tree_selection_get_selected (selection, &model, &iter))
619 gtk_tree_model_get (model, &iter, 1, &target, -1);
620 profiler_set_target (profiler, target);
622 if (profiler_get_data (profiler))
623 gprof_view_manager_refresh_views (profiler->view_manager);
625 else
626 profiler_set_target (profiler, NULL);
629 gtk_widget_hide (select_target_dialog);
630 g_object_unref (bxml);
633 static void
634 on_profiler_refresh (GtkAction *action, Profiler *profiler)
636 if (profiler_get_data (profiler))
637 gprof_view_manager_refresh_views (profiler->view_manager);
640 static void
641 on_profiler_delete_data (GtkAction *action, Profiler *profiler)
643 gchar *profile_target_dir;
644 gchar *profile_data_path_from_options;
645 gchar *profile_data_path;
647 if (profiler->profile_target_path)
649 profile_data_path_from_options = gprof_options_get_string (profiler->options,
650 "profile_data_file");
651 /* Delete given path if we have one, or just use the default */
652 if (strlen (profile_data_path_from_options) > 0)
653 g_unlink (profile_data_path_from_options);
654 else
657 profile_target_dir = g_path_get_dirname (profiler->profile_target_path);
658 profile_data_path = g_build_filename (profile_target_dir,
659 "gmon.out", NULL);
661 g_unlink (profile_data_path);
663 g_free (profile_target_dir);
664 g_free (profile_data_path);
667 g_free (profile_data_path_from_options);
671 static void
672 project_root_added (AnjutaPlugin *plugin, const gchar *name,
673 const GValue *value, gpointer user_data)
675 Profiler *profiler;
676 const gchar *root_uri;
678 profiler = PROFILER (plugin);
679 root_uri = g_value_get_string (value);
681 if (root_uri)
683 g_free (profiler->project_root_uri);
684 profiler->project_root_uri = g_strdup (root_uri);
690 static void
691 project_root_removed (AnjutaPlugin *plugin, const gchar *name,
692 gpointer user_data)
694 Profiler *profiler;
696 profiler = PROFILER (plugin);
698 g_free (profiler->project_root_uri);
699 profiler->project_root_uri = NULL;
702 static void
703 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
704 AnjutaSession *session,
705 Profiler *plugin)
707 const gchar *session_dir;
708 gchar *settings_file_path;
710 if (phase == ANJUTA_SESSION_PHASE_NORMAL)
712 session_dir = anjuta_session_get_session_directory (session);
713 settings_file_path = g_build_filename (session_dir,
714 "profiler-settings.xml",
715 NULL);
717 gprof_options_load (plugin->options, settings_file_path);
719 g_free (settings_file_path);
723 static void
724 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
725 AnjutaSession *session,
726 Profiler *plugin)
728 const gchar *session_dir;
729 gchar *settings_file_path;
731 if (phase == ANJUTA_SESSION_PHASE_NORMAL)
733 session_dir = anjuta_session_get_session_directory (session);
734 settings_file_path = g_build_filename (session_dir,
735 "profiler-settings.xml",
736 NULL);
738 gprof_options_save (plugin->options, settings_file_path);
740 g_free (settings_file_path);
745 static GtkActionEntry actions_file[] = {
747 "ActionMenuDebug", /* Action name */
748 NULL, /* Stock icon, if any */
749 N_("Debug"), /* Display label */
750 NULL, /* short-cut */
751 NULL, /* Tooltip */
752 NULL /* Action callback */
755 "ActionMenuProfiler", /* Action name */
756 "profiler-icon", /* Stock icon, if any */
757 N_("Profiler"), /* Display label */
758 NULL, /* short-cut */
759 NULL, /* Tooltip */
760 NULL /* Action callback */
763 "ActionProfilerSelectTarget", /* Action name */
764 GTK_STOCK_EXECUTE, /* Stock icon, if any */
765 N_("Select Target..."), /* Display label */
766 NULL, /* short-cut */
767 NULL, /* Tooltip */
768 G_CALLBACK (on_profiler_select_target) /* Action callback */
771 "ActionProfilerRefresh", /* Action name */
772 GTK_STOCK_REFRESH, /* Stock icon, if any */
773 N_("Refresh"), /* Display label */
774 NULL, /* short-cut */
775 NULL, /* Tooltip */
776 G_CALLBACK (on_profiler_refresh) /* Action callback */
779 "ActionProfilerDeleteData", /* Action name */
780 GTK_STOCK_DELETE, /* Stock icon, if any */
781 N_("Delete Data"), /* Display label */
782 NULL, /* short-cut */
783 NULL, /* Tooltip */
784 G_CALLBACK (on_profiler_delete_data) /* Action callback */
788 static void
789 register_stock_icons (AnjutaPlugin *plugin)
791 AnjutaUI *ui;
792 GtkIconFactory *icon_factory;
793 GtkIconSet *icon_set;
794 static gboolean registered = FALSE;
796 if (registered)
797 return;
798 registered = TRUE;
800 /* Register stock icons */
801 ui = anjuta_shell_get_ui (plugin->shell, NULL);
802 icon_factory = anjuta_ui_get_icon_factory (ui);
803 REGISTER_ICON ("anjuta-profiler-plugin-48.png", "profiler-icon");
806 static gboolean
807 profiler_activate (AnjutaPlugin *plugin)
810 AnjutaUI *ui;
811 Profiler *profiler;
812 IAnjutaSymbolManager *symbol_manager;
813 IAnjutaDocumentManager *document_manager;
815 DEBUG_PRINT ("%s", "Profiler: Activating Profiler plugin ...");
816 profiler = PROFILER (plugin);
818 /* Add all UI actions and merge UI */
819 ui = anjuta_shell_get_ui (plugin->shell, NULL);
820 register_stock_icons (plugin);
822 profiler->action_group =
823 anjuta_ui_add_action_group_entries (ui, "ActionGroupProfiler",
824 _("Application Performance Profiler"),
825 actions_file,
826 G_N_ELEMENTS (actions_file),
827 GETTEXT_PACKAGE, TRUE,
828 plugin);
829 profiler->uiid = anjuta_ui_merge (ui, UI_FILE);
831 profiler->view_manager = gprof_view_manager_new ();
832 profiler->profile_data = gprof_profile_data_new ();
834 symbol_manager = anjuta_shell_get_interface (plugin->shell,
835 IAnjutaSymbolManager,
836 NULL);
838 document_manager = anjuta_shell_get_interface (plugin->shell,
839 IAnjutaDocumentManager,
840 NULL);
842 gprof_view_manager_add_view (profiler->view_manager,
843 GPROF_VIEW (gprof_flat_profile_view_new (profiler->profile_data,
844 symbol_manager,
845 document_manager)),
846 _("Flat Profile"));
847 gprof_view_manager_add_view (profiler->view_manager,
848 GPROF_VIEW (gprof_call_graph_view_new (profiler->profile_data,
849 symbol_manager,
850 document_manager)),
851 _("Call Graph"));
852 gprof_view_manager_add_view (profiler->view_manager,
853 GPROF_VIEW (gprof_function_call_tree_view_new (profiler->profile_data,
854 symbol_manager,
855 document_manager)),
856 _("Function Call Tree"));
858 #ifdef HAVE_GRAPHVIZ
859 gprof_view_manager_add_view (profiler->view_manager,
860 GPROF_VIEW (gprof_function_call_chart_view_new (profiler->profile_data,
861 symbol_manager,
862 document_manager)),
863 _("Function Call Chart"));
864 #endif
866 anjuta_shell_add_widget (plugin->shell,
867 gprof_view_manager_get_notebook (profiler->view_manager),
868 "Profiler",
869 _("Profiler"),
870 "profiler-icon",
871 ANJUTA_SHELL_PLACEMENT_CENTER,
872 NULL);
874 profiler->project_watch_id = anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
875 project_root_added,
876 project_root_removed, NULL);
878 profiler->options = register_options ();
880 /* Set up session save/load */
881 g_signal_connect (G_OBJECT (plugin->shell), "save_session",
882 G_CALLBACK (on_session_save), plugin);
884 g_signal_connect (G_OBJECT (plugin->shell), "load_session",
885 G_CALLBACK (on_session_load), plugin);
887 return TRUE;
890 static gboolean
891 profiler_deactivate (AnjutaPlugin *plugin)
894 AnjutaUI *ui;
895 Profiler *profiler;
897 DEBUG_PRINT ("%s", "Profiler: Dectivating Profiler plugin ...");
899 /* Disconnect session save/load */
900 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
901 G_CALLBACK (on_session_save), plugin);
903 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
904 G_CALLBACK (on_session_load), plugin);
906 ui = anjuta_shell_get_ui (plugin->shell, NULL);
907 profiler = PROFILER (plugin);
909 anjuta_plugin_remove_watch (plugin, profiler->project_watch_id, TRUE);
911 anjuta_ui_unmerge (ui, PROFILER (plugin)->uiid);
912 anjuta_ui_remove_action_group (ui, PROFILER (plugin)->action_group);
914 anjuta_shell_remove_widget (plugin->shell,
915 gprof_view_manager_get_notebook (profiler->view_manager),
916 NULL);
918 profiler_set_target (profiler, NULL);
919 gprof_view_manager_free (profiler->view_manager);
920 gprof_profile_data_free (profiler->profile_data);
922 gprof_options_destroy (profiler->options);
924 g_free (profiler->project_root_uri);
926 if (profiler->profile_data_monitor)
927 g_file_monitor_cancel (profiler->profile_data_monitor);
929 return TRUE;
932 static void
933 profiler_finalize (GObject *obj)
935 /* Finalization codes here */
936 G_OBJECT_CLASS (parent_class)->finalize (obj);
939 static void
940 profiler_dispose (GObject *obj)
942 /* Disposition codes */
943 G_OBJECT_CLASS (parent_class)->dispose (obj);
946 static void
947 profiler_instance_init (GObject *obj)
949 Profiler *profiler = PROFILER (obj);
951 profiler->uiid = 0;
952 profiler->project_root_uri = NULL;
953 profiler->profile_target_path = NULL;
958 static void
959 profiler_class_init (GObjectClass *klass)
961 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
963 parent_class = g_type_class_peek_parent (klass);
965 plugin_class->activate = profiler_activate;
966 plugin_class->deactivate = profiler_deactivate;
967 klass->finalize = profiler_finalize;
968 klass->dispose = profiler_dispose;
971 /* File open interface */
972 static void
973 ifile_open (IAnjutaFile *manager, GFile* file,
974 GError **err)
976 Profiler *profiler;
978 profiler = PROFILER (manager);
980 gchar* uri = g_file_get_uri (file);
982 profiler_set_target (profiler, uri);
984 /* Respect user settings for this target if they exist. Otherwise, don't
985 * create an entry for this target to avoid having the settings file
986 * balloon with the settings for a bunch of targets, espcially if this
987 * is a one-time operation. If previous settings don't exist, just use
988 * the defaults. */
989 if (gprof_options_has_target (profiler->options, uri))
990 gprof_options_set_target (profiler->options, uri);
991 else
992 gprof_options_set_target (profiler->options, NULL);
994 if (profiler_get_data (profiler))
995 gprof_view_manager_refresh_views (profiler->view_manager);
997 g_free (uri);
1000 static GFile*
1001 ifile_get_file (IAnjutaFile *manager, GError **err)
1003 DEBUG_PRINT ("%s", "Unsupported operation");
1004 return NULL;
1007 static void
1008 ifile_iface_init (IAnjutaFileIface *iface)
1010 iface->open = ifile_open;
1011 iface->get_file = ifile_get_file;
1014 ANJUTA_PLUGIN_BEGIN (Profiler, profiler);
1015 ANJUTA_PLUGIN_ADD_INTERFACE (ifile, IANJUTA_TYPE_FILE);
1016 ANJUTA_PLUGIN_END;
1018 ANJUTA_SIMPLE_PLUGIN (Profiler, profiler);