1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) James Liggett 2007 <jrliggett@cox.net>
6 * gprof-options.c is free software.
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.
24 #include "gprof-options.h"
26 /* Internal structure to hold information on individual preference keys */
31 GProfOptions
*options
; /* Need this to set/get data from callbacks */
32 OptionWidgetType widget_type
;
35 struct _GProfOptionsPriv
37 GHashTable
*default_options
;
39 GHashTable
*current_target
;
40 GHashTable
*key_data_table
;
47 g_free (key
->widget_name
);
52 gprof_options_init (GProfOptions
*self
)
54 self
->priv
= g_new0 (GProfOptionsPriv
, 1);
56 self
->priv
->default_options
= g_hash_table_new_full (g_str_hash
,
60 self
->priv
->key_data_table
= g_hash_table_new_full (g_str_hash
,
63 (GDestroyNotify
) free_key
);
65 self
->priv
->targets
= g_hash_table_new_full (g_str_hash
,
68 (GDestroyNotify
) g_hash_table_destroy
);
72 gprof_options_finalize (GObject
*obj
)
76 self
= (GProfOptions
*) obj
;
78 g_hash_table_destroy (self
->priv
->default_options
);
79 g_hash_table_destroy (self
->priv
->key_data_table
);
80 g_hash_table_destroy (self
->priv
->targets
);
86 gprof_options_class_init (GProfOptionsClass
*klass
)
88 GObjectClass
*object_class
;
90 object_class
= (GObjectClass
*) klass
;
91 object_class
->finalize
= gprof_options_finalize
;
94 /* Copy defaults into a new target specifc settings table */
96 copy_default_key (gchar
*key
, gchar
*value
, GHashTable
*new_settings
)
98 g_hash_table_insert (new_settings
, g_strdup (key
), g_strdup (value
));
102 gprof_options_parse_tree (GProfOptions
*self
, xmlNodePtr node
)
104 xmlNodePtr current_node
;
105 xmlChar
*target_name
;
113 if (strcmp ((gchar
*) current_node
->name
, "target") == 0)
115 target_name
= xmlGetProp (current_node
, BAD_CAST
"name");
116 gprof_options_set_target (self
, (gchar
*) target_name
);
118 xmlFree (target_name
);
120 else if (strcmp ((gchar
*) current_node
->name
, "key") == 0)
122 key_name
= xmlGetProp (current_node
, BAD_CAST
"name");
123 key_value
= xmlNodeGetContent (current_node
);
125 /* Filter out deprecated keys (those that aren't registered) */
126 if (g_hash_table_lookup_extended (self
->priv
->key_data_table
,
130 gprof_options_set_string (self
, (gchar
*) key_name
,
131 (gchar
*) key_value
);
138 gprof_options_parse_tree (self
, current_node
->children
);
139 current_node
= current_node
->next
;
145 build_key_elements (gchar
*key
, gchar
*value
, xmlNodePtr parent
)
149 new_key
= xmlNewChild (parent
, NULL
, BAD_CAST
"key", BAD_CAST value
);
150 xmlNewProp (new_key
, BAD_CAST
"name", BAD_CAST key
);
154 build_target_elements (gchar
*key
, GHashTable
*target_settings
,
157 xmlNodePtr new_target
;
159 new_target
= xmlNewChild (parent
, NULL
, BAD_CAST
"target", NULL
);
160 xmlNewProp (new_target
, BAD_CAST
"name", BAD_CAST key
);
162 g_hash_table_foreach (target_settings
, (GHFunc
) build_key_elements
, new_target
);
165 /* GUI functions: callbacks and various setup functions */
167 on_option_toggled (GtkToggleButton
*button
, Key
*key
)
169 if (gtk_toggle_button_get_active (button
))
170 gprof_options_set_int (key
->options
, key
->name
, 1);
172 gprof_options_set_int (key
->options
, key
->name
, 0);
176 on_option_focus_out (GtkWidget
*text_view
, GdkEventFocus
*event
,
179 GtkTextBuffer
*text_buffer
;
180 GtkTextIter start_iter
;
181 GtkTextIter end_iter
;
184 text_buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view
));
185 gtk_text_buffer_get_start_iter (text_buffer
, &start_iter
);
186 gtk_text_buffer_get_end_iter (text_buffer
, &end_iter
);
187 string
= gtk_text_buffer_get_text (text_buffer
, &start_iter
, &end_iter
, FALSE
);
189 gprof_options_set_string (key
->options
, key
->name
, string
);
197 on_option_changed (GtkEditable
*editable
, Key
*key
)
201 string
= gtk_editable_get_chars (editable
, 0, -1);
202 gprof_options_set_string (key
->options
, key
->name
, string
);
208 setup_widgets (gchar
*key_name
, Key
*key
, GtkBuilder
*bxml
)
211 GtkTextBuffer
*buffer
;
214 widget
= GTK_WIDGET (gtk_builder_get_object (bxml
, key
->widget_name
));
218 switch (key
->widget_type
)
220 case OPTION_TYPE_TOGGLE
:
221 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
),
222 gprof_options_get_int (key
->options
,
224 g_signal_connect (widget
, "toggled", G_CALLBACK (on_option_toggled
),
227 case OPTION_TYPE_TEXT_ENTRY
:
228 buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget
));
229 string
= gprof_options_get_string (key
->options
, key_name
);
230 gtk_text_buffer_set_text (buffer
, string
, -1);
232 g_signal_connect (widget
, "focus-out-event", G_CALLBACK (on_option_focus_out
),
237 case OPTION_TYPE_ENTRY
:
238 string
= gprof_options_get_string (key
->options
, key
->name
);
239 gtk_entry_set_text (GTK_ENTRY (widget
), string
);
241 g_signal_connect (widget
, "changed", G_CALLBACK (on_option_changed
),
253 gprof_options_get_type (void)
255 static GType obj_type
= 0;
259 static const GTypeInfo obj_info
=
261 sizeof (GProfOptionsClass
),
262 (GBaseInitFunc
) NULL
,
263 (GBaseFinalizeFunc
) NULL
,
264 (GClassInitFunc
) gprof_options_class_init
,
265 (GClassFinalizeFunc
) NULL
,
266 NULL
, /* class_data */
267 sizeof (GProfOptions
),
269 (GInstanceInitFunc
) gprof_options_init
,
270 NULL
/* value_table */
272 obj_type
= g_type_register_static (G_TYPE_OBJECT
,
273 "GProfOptions", &obj_info
, 0);
281 return g_object_new (GPROF_OPTIONS_TYPE
, NULL
);
285 gprof_options_destroy (GProfOptions
*self
)
287 g_object_unref (self
);
291 gprof_options_set_target (GProfOptions
*self
, gchar
*target
)
293 GHashTable
*new_table
;
297 /* First, the target must have an entry in the target table. If we don't
298 * have one, set one up and copy the defaults into it. */
300 if (!g_hash_table_lookup_extended (self
->priv
->targets
, target
,
303 new_table
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
,
305 g_hash_table_foreach (self
->priv
->default_options
,
306 (GHFunc
) copy_default_key
, new_table
);
307 g_hash_table_insert (self
->priv
->targets
, g_strdup (target
),
311 self
->priv
->current_target
= g_hash_table_lookup (self
->priv
->targets
,
315 self
->priv
->current_target
= NULL
;
319 gprof_options_has_target (GProfOptions
*self
, gchar
*target
)
321 return g_hash_table_lookup_extended (self
->priv
->targets
, target
,
325 /* Free returned string */
327 gprof_options_get_string (GProfOptions
*self
, const gchar
*key
)
329 if (self
->priv
->current_target
)
331 return g_strdup (g_hash_table_lookup (self
->priv
->current_target
,
336 return g_strdup (g_hash_table_lookup (self
->priv
->default_options
,
344 gprof_options_get_int (GProfOptions
*self
, const gchar
*key
)
349 value_string
= gprof_options_get_string (self
, key
);
353 value
= atoi (value_string
);
354 g_free (value_string
);
363 gprof_options_set_string (GProfOptions
*self
, gchar
*key
, gchar
*value
)
365 if (self
->priv
->current_target
)
367 g_hash_table_insert (self
->priv
->current_target
,
368 g_strdup (key
), g_strdup (value
));
372 g_warning ("GProfOptions: Trying to set option value with "
378 gprof_options_set_int (GProfOptions
*self
, gchar
*key
, gint value
)
382 value_string
= g_strdup_printf ("%i", value
);
383 gprof_options_set_string (self
, key
, value_string
);
385 g_free (value_string
);
389 gprof_options_register_key (GProfOptions
*self
, gchar
*key_name
,
390 const gchar
*default_value
,
391 const gchar
*widget_name
,
392 OptionWidgetType widget_type
)
396 new_key
= g_new0 (Key
, 1);
398 new_key
->name
= g_strdup (key_name
);
399 new_key
->widget_name
= g_strdup (widget_name
);
400 new_key
->options
= self
;
401 new_key
->widget_type
= widget_type
;
403 g_hash_table_insert (self
->priv
->key_data_table
, g_strdup (key_name
),
405 g_hash_table_insert (self
->priv
->default_options
, g_strdup (key_name
),
406 g_strdup (default_value
));
410 gprof_options_create_window (GProfOptions
*self
, GtkBuilder
*bxml
)
412 g_hash_table_foreach (self
->priv
->key_data_table
, (GHFunc
) setup_widgets
,
417 gprof_options_load (GProfOptions
*self
, const gchar
*path
)
419 if (g_file_test (path
, G_FILE_TEST_EXISTS
))
421 xmlDocPtr settings_doc
;
424 settings_doc
= xmlReadFile (path
, NULL
, 0);
425 root
= xmlDocGetRootElement (settings_doc
);
427 gprof_options_parse_tree (self
, root
);
429 xmlFreeDoc (settings_doc
);
435 gprof_options_save (GProfOptions
*self
, const gchar
*path
)
437 xmlDocPtr settings_doc
;
438 xmlNodePtr root_node
;
440 settings_doc
= xmlNewDoc (BAD_CAST
"1.0");
441 root_node
= xmlNewNode (NULL
, BAD_CAST
"profiler-settings");
442 xmlDocSetRootElement (settings_doc
, root_node
);
444 g_hash_table_foreach (self
->priv
->targets
, (GHFunc
) build_target_elements
,
447 xmlSaveFormatFile (path
, settings_doc
, TRUE
);
449 xmlFreeDoc (settings_doc
);