1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Authors: Jeffrey Stedfast <fejj@ximian.com>
4 * Copyright (C) Massimo Cora' 2005 <maxcvs@gmail.com>
6 * Copyright 2003 Ximian, Inc. (www.ximian.com)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 #include <sys/types.h>
37 #include <gconf/gconf-client.h>
38 #include <libgnome/gnome-i18n.h>
39 #include <libgnomevfs/gnome-vfs.h>
40 #include <libanjuta/anjuta-debug.h>
42 #include "vggeneralprefs.h"
45 #define DEMANGLE_KEY "/apps/anjuta/valgrind/general/demangle"
46 #define NUM_CALLERS_KEY "/apps/anjuta/valgrind/general/num-callers"
47 #define ERROR_LIMIT_KEY "/apps/anjuta/valgrind/general/error-limit"
48 #define SLOPPY_MALLOC_KEY "/apps/anjuta/valgrind/general/sloppy-malloc"
49 #define TRACE_CHILDREN_KEY "/apps/anjuta/valgrind/general/trace-children"
50 #define TRACK_FDS_KEY "/apps/anjuta/valgrind/general/track-fds"
51 #define TIME_STAMP_KEY "/apps/anjuta/valgrind/general/time-stamp"
52 #define RUN_LIBC_FREERES_KEY "/apps/anjuta/valgrind/general/run-libc-freeres"
53 #define SUPPRESSIONS_KEY "/apps/anjuta/valgrind/general/suppressions"
55 #define SUPPRESSIONS_DEFAULT_FILE ".anjuta/valgrind.supp"
57 static void vg_general_prefs_class_init (VgGeneralPrefsClass
*klass
);
58 static void vg_general_prefs_init (VgGeneralPrefs
*prefs
);
59 static void vg_general_prefs_destroy (GtkObject
*obj
);
60 static void vg_general_prefs_finalize (GObject
*obj
);
62 static void general_prefs_apply (VgToolPrefs
*prefs
);
63 static void general_prefs_get_argv (VgToolPrefs
*prefs
, const char *tool
, GPtrArray
*argv
);
66 static VgToolPrefsClass
*parent_class
= NULL
;
70 vg_general_prefs_get_type (void)
72 static GType type
= 0;
75 static const GTypeInfo info
= {
76 sizeof (VgGeneralPrefsClass
),
77 NULL
, /* base_class_init */
78 NULL
, /* base_class_finalize */
79 (GClassInitFunc
) vg_general_prefs_class_init
,
80 NULL
, /* class_finalize */
81 NULL
, /* class_data */
82 sizeof (VgGeneralPrefs
),
84 (GInstanceInitFunc
) vg_general_prefs_init
,
87 type
= g_type_register_static (VG_TYPE_TOOL_PREFS
, "VgGeneralPrefs", &info
, 0);
94 vg_general_prefs_class_init (VgGeneralPrefsClass
*klass
)
96 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
97 GtkObjectClass
*gtk_object_class
= GTK_OBJECT_CLASS (klass
);
98 VgToolPrefsClass
*tool_class
= VG_TOOL_PREFS_CLASS (klass
);
100 parent_class
= g_type_class_ref (VG_TYPE_TOOL_PREFS
);
102 object_class
->finalize
= vg_general_prefs_finalize
;
103 gtk_object_class
->destroy
= vg_general_prefs_destroy
;
105 /* virtual methods */
106 tool_class
->apply
= general_prefs_apply
;
107 tool_class
->get_argv
= general_prefs_get_argv
;
112 toggle_button_toggled (GtkToggleButton
*toggle
, const char *key
)
117 gconf
= gconf_client_get_default ();
119 bool = gtk_toggle_button_get_active (toggle
);
120 gconf_client_set_bool (gconf
, key
, bool, NULL
);
122 g_object_unref (gconf
);
126 spin_focus_out (GtkSpinButton
*spin
, GdkEventFocus
*event
, const char *key
)
131 gconf
= gconf_client_get_default ();
133 num
= gtk_spin_button_get_value_as_int (spin
);
134 gconf_client_set_int (gconf
, key
, num
, NULL
);
136 g_object_unref (gconf
);
142 file_entry_changed (GtkFileChooser
*chooser
, const char *key
)
147 gconf
= gconf_client_get_default ();
149 str
= gtk_file_chooser_get_filename (chooser
);
151 DEBUG_PRINT ("str is %s key is %s", str
, key
);
153 gconf_client_set_string (gconf
, key
, str
? str
: "", NULL
);
156 g_object_unref (gconf
);
160 vg_general_prefs_init (VgGeneralPrefs
*prefs
)
162 GtkWidget
*vbox
, *hbox
, *label
;
170 gconf
= gconf_client_get_default ();
172 VG_TOOL_PREFS (prefs
)->label
= _("General");
174 vbox
= GTK_WIDGET (prefs
);
175 gtk_box_set_spacing (GTK_BOX (vbox
), 6);
177 bool = gconf_client_get_bool (gconf
, DEMANGLE_KEY
, NULL
);
178 widget
= gtk_check_button_new_with_label (_("Demangle c++ symbol names"));
179 g_signal_connect (widget
, "toggled", G_CALLBACK (toggle_button_toggled
), DEMANGLE_KEY
);
180 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
), bool);
181 prefs
->demangle
= GTK_TOGGLE_BUTTON (widget
);
182 gtk_widget_show (widget
);
183 gtk_box_pack_start (GTK_BOX (vbox
), widget
, FALSE
, FALSE
, 0);
185 hbox
= gtk_hbox_new (FALSE
, 6);
186 label
= gtk_label_new (_("Show"));
187 gtk_widget_show (label
);
188 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
189 num
= gconf_client_get_int (gconf
, NUM_CALLERS_KEY
, NULL
);
190 widget
= gtk_spin_button_new_with_range (0, (gdouble
) 1024, 1);
191 gtk_widget_show (widget
);
192 prefs
->num_callers
= GTK_SPIN_BUTTON (widget
);
193 gtk_spin_button_set_digits (prefs
->num_callers
, 0);
194 gtk_spin_button_set_numeric (prefs
->num_callers
, TRUE
);
195 gtk_spin_button_set_value (prefs
->num_callers
, (gdouble
) num
);
196 g_signal_connect (widget
, "focus-out-event", G_CALLBACK (spin_focus_out
), NUM_CALLERS_KEY
);
197 gtk_box_pack_start (GTK_BOX (hbox
), widget
, FALSE
, FALSE
, 0);
198 label
= gtk_label_new (_("callers in stack trace"));
199 gtk_widget_show (label
);
200 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
201 gtk_widget_show (hbox
);
202 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
204 bool = gconf_client_get_bool (gconf
, ERROR_LIMIT_KEY
, NULL
);
205 widget
= gtk_check_button_new_with_label (_("Stop showing errors if there are too many"));
206 g_signal_connect (widget
, "toggled", G_CALLBACK (toggle_button_toggled
), ERROR_LIMIT_KEY
);
207 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
), bool);
208 prefs
->error_limit
= GTK_TOGGLE_BUTTON (widget
);
209 gtk_widget_show (widget
);
210 gtk_box_pack_start (GTK_BOX (vbox
), widget
, FALSE
, FALSE
, 0);
212 bool = gconf_client_get_bool (gconf
, SLOPPY_MALLOC_KEY
, NULL
);
213 widget
= gtk_check_button_new_with_label (_("Round malloc sizes to next word"));
214 g_signal_connect (widget
, "toggled", G_CALLBACK (toggle_button_toggled
), SLOPPY_MALLOC_KEY
);
215 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
), bool);
216 prefs
->sloppy_malloc
= GTK_TOGGLE_BUTTON (widget
);
217 gtk_widget_show (widget
);
218 gtk_box_pack_start (GTK_BOX (vbox
), widget
, FALSE
, FALSE
, 0);
220 bool = gconf_client_get_bool (gconf
, TRACE_CHILDREN_KEY
, NULL
);
221 widget
= gtk_check_button_new_with_label (_("Trace any child processes forked off by the program being debugged"));
222 g_signal_connect (widget
, "toggled", G_CALLBACK (toggle_button_toggled
), TRACE_CHILDREN_KEY
);
223 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
), bool);
224 prefs
->trace_children
= GTK_TOGGLE_BUTTON (widget
);
225 gtk_widget_show (widget
);
226 gtk_box_pack_start (GTK_BOX (vbox
), widget
, FALSE
, FALSE
, 0);
228 bool = gconf_client_get_bool (gconf
, TRACK_FDS_KEY
, NULL
);
229 widget
= gtk_check_button_new_with_label (_("Track open file descriptors"));
230 g_signal_connect (widget
, "toggled", G_CALLBACK (toggle_button_toggled
), TRACK_FDS_KEY
);
231 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
), bool);
232 prefs
->track_fds
= GTK_TOGGLE_BUTTON (widget
);
233 gtk_widget_show (widget
);
234 gtk_box_pack_start (GTK_BOX (vbox
), widget
, FALSE
, FALSE
, 0);
236 bool = gconf_client_get_bool (gconf
, TIME_STAMP_KEY
, NULL
);
237 widget
= gtk_check_button_new_with_label (_("Add time stamps to log messages"));
238 g_signal_connect (widget
, "toggled", G_CALLBACK (toggle_button_toggled
), TIME_STAMP_KEY
);
239 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
), bool);
240 prefs
->time_stamp
= GTK_TOGGLE_BUTTON (widget
);
241 gtk_widget_show (widget
);
242 gtk_box_pack_start (GTK_BOX (vbox
), widget
, FALSE
, FALSE
, 0);
244 bool = gconf_client_get_bool (gconf
, RUN_LIBC_FREERES_KEY
, NULL
);
245 widget
= gtk_check_button_new_with_label (_("Call __libc_freeres() at exit before checking for memory leaks"));
246 g_signal_connect (widget
, "toggled", G_CALLBACK (toggle_button_toggled
), RUN_LIBC_FREERES_KEY
);
247 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
), bool);
248 prefs
->run_libc_freeres
= GTK_TOGGLE_BUTTON (widget
);
249 gtk_widget_show (widget
);
250 gtk_box_pack_start (GTK_BOX (vbox
), widget
, FALSE
, FALSE
, 0);
252 hbox
= gtk_hbox_new (FALSE
, 6);
253 label
= gtk_label_new (_("Suppressions File:"));
254 gtk_widget_show (label
);
255 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
257 if (!(str_file
= gconf_client_get_string (gconf
, SUPPRESSIONS_KEY
, &err
)) || err
!= NULL
) {
260 str_file
= g_build_filename (g_get_home_dir (), SUPPRESSIONS_DEFAULT_FILE
, NULL
);
261 if ((fd
= open (str_file
, O_WRONLY
| O_CREAT
, 0666)) == -1) {
268 g_clear_error (&err
);
273 gtk_file_chooser_button_new (_("Choose Valgrind Suppressions File..."),
274 GTK_FILE_CHOOSER_ACTION_OPEN
);
276 if ( gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (widget
), str_file
) == FALSE
)
277 DEBUG_PRINT ("error: could not select file uri with gtk_file_chooser_select_filename ()");
279 /* grab every change in file selection */
280 g_signal_connect (widget
, "selection-changed", G_CALLBACK (file_entry_changed
), SUPPRESSIONS_KEY
);
282 gtk_widget_show (widget
);
283 gtk_box_pack_start (GTK_BOX (hbox
), widget
, TRUE
, TRUE
, 0);
285 gtk_widget_show (hbox
);
286 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
288 g_object_unref (gconf
);
292 vg_general_prefs_finalize (GObject
*obj
)
294 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
298 vg_general_prefs_destroy (GtkObject
*obj
)
300 GTK_OBJECT_CLASS (parent_class
)->destroy (obj
);
305 general_prefs_apply (VgToolPrefs
*prefs
)
324 { DEMANGLE_KEY
, "--demangle", NULL
, ARG_TYPE_BOOL
, 1 },
325 { NUM_CALLERS_KEY
, "--num-callers", NULL
, ARG_TYPE_INT
, 4 },
326 { ERROR_LIMIT_KEY
, "--error-limit", NULL
, ARG_TYPE_BOOL
, 1 },
327 { SLOPPY_MALLOC_KEY
, "--sloppy-malloc", NULL
, ARG_TYPE_BOOL
, 0 },
328 { TRACE_CHILDREN_KEY
, "--trace-children", NULL
, ARG_TYPE_BOOL
, 0 },
329 { TRACK_FDS_KEY
, "--track-fds", NULL
, ARG_TYPE_BOOL
, 0 },
330 { TIME_STAMP_KEY
, "--time-stamp", NULL
, ARG_TYPE_BOOL
, 0 },
331 { RUN_LIBC_FREERES_KEY
, "--run-libc-freeres", NULL
, ARG_TYPE_BOOL
, 0 },
332 { SUPPRESSIONS_KEY
, "--suppressions", NULL
, ARG_TYPE_STRING
, 0 },
336 general_prefs_get_argv (VgToolPrefs
*prefs
, const char *tool
, GPtrArray
*argv
)
342 gconf
= gconf_client_get_default ();
344 g_ptr_array_add (argv
, "--alignment=8");
346 for (i
= 0; i
< G_N_ELEMENTS (general_args
); i
++) {
347 const char *arg
= general_args
[i
].arg
;
348 const char *key
= general_args
[i
].key
;
351 g_free (general_args
[i
].buf
);
352 if (general_args
[i
].type
== ARG_TYPE_INT
) {
353 num
= gconf_client_get_int (gconf
, key
, NULL
);
354 if (num
== general_args
[i
].dval
)
357 general_args
[i
].buf
= g_strdup_printf ("%s=%d", arg
, num
);
358 } else if (general_args
[i
].type
== ARG_TYPE_BOOL
) {
359 bool = gconf_client_get_bool (gconf
, key
, NULL
) ? 1 : 0;
360 if (bool == general_args
[i
].dval
)
363 general_args
[i
].buf
= g_strdup_printf ("%s=%s", arg
, bool ? "yes" : "no");
365 if (!(str
= gconf_client_get_string (gconf
, key
, NULL
)) || *str
== '\0') {
366 general_args
[i
].buf
= NULL
;
371 if (g_str_equal (general_args
[i
].key
, SUPPRESSIONS_KEY
) &&
372 (stat (str
, &st
) == -1 || !S_ISREG (st
.st_mode
))) {
373 general_args
[i
].buf
= NULL
;
378 general_args
[i
].buf
= g_strdup_printf ("%s=%s", arg
, str
);
382 g_ptr_array_add (argv
, general_args
[i
].buf
);
385 g_object_unref (gconf
);