65
65
#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility"
66
66
#define GTK_THEME_KEY "/desktop/gnome/interface/gtk_theme"
67
67
#define ICON_THEME_KEY "/desktop/gnome/interface/icon_theme"
68
#define GTK_MODULES_KEY "/apps/gnome_settings_daemon/gtk-modules"
68
69
#define DESKTOP_IS_HOME_DIR "/apps/nautilus/preferences/desktop_is_home_dir"
69
70
#define MIN_REPORT_DETAILS_CHARS 10
72
73
static int bug_count = 0;
73
74
static GHashTable *apps = NULL;
77
show_version_cb (const char *option_name,
82
g_print ("%s %s\n", _("GNOME bug-buddy"), VERSION);
75
89
static const GOptionEntry options[] = {
76
90
{ "package", '\0', 0, G_OPTION_ARG_STRING, &gopt_data.package, N_("Package containing the program"), N_("PACKAGE") },
77
91
{ "appname", '\0', 0, G_OPTION_ARG_FILENAME, &gopt_data.app_file, N_("File name of crashed program"), N_("FILE") },
78
92
{ "pid", '\0', 0, G_OPTION_ARG_INT, &gopt_data.pid, N_("PID of crashed program"), N_("PID") },
79
93
{ "include", '\0', 0, G_OPTION_ARG_FILENAME, &gopt_data.include_file, N_("Text file to include in the report"), N_("FILE") },
94
{ "unlink-tempfile", '\0', 0, G_OPTION_ARG_NONE, &gopt_data.own_file, N_("Delete the included file after reporting"),NULL},
80
95
{ "minidump", '\0', 0, G_OPTION_ARG_FILENAME, &gopt_data.minidump_file, N_("MiniDump file with info about the crash"), N_("FILE") },
96
{ "version", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, show_version_cb, NULL, NULL },
85
101
static void fill_custom_info (BugzillaApplication *app, GtkBuilder *ui);
86
102
static void close_callback (GtkWidget *widget, gpointer user_data);
87
103
static void bug_buddy_quit (GtkBuilder *ui);
104
static void fill_include_file (char *filename, gboolean own_file, GtkBuilder *ui);
277
294
version = g_new0 (GnomeVersionInfo, 1);
279
xml_file = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_DATADIR,
280
"gnome-about/gnome-version.xml",
296
xml_file = g_build_filename (DATADIR, "gnome-about/gnome-version.xml", NULL);
284
298
doc = xmlParseFile (xml_file);
285
299
g_free (xml_file);
395
409
link_callback (GtkLinkButton *button, gpointer user_data)
397
411
const gchar *link = gtk_link_button_get_uri (button);
398
#if GTK_CHECK_VERSION (2,13,0)
399
412
GdkAppLaunchContext *context;
401
414
context = gdk_app_launch_context_new ();
407
420
if (!g_app_info_launch_default_for_uri (link,
408
421
G_APP_LAUNCH_CONTEXT (context),
411
if (!g_app_info_launch_default_for_uri (link, NULL, NULL))
416
426
text = g_markup_printf_escaped (_("Bug Buddy was unable to view the link \"%s\"\n"), link);
779
787
gtk_text_buffer_get_end_iter (buffer, &end);
780
788
details_text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
782
type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(ui), "type"));
790
type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (ui), "type"));
783
791
final_text = g_strdup_printf ("%s%s\n\n\n%s",
784
792
type == BUG_TYPE_CRASH ? "What were you doing when the application crashed?\n" : "",
785
793
details_text != NULL ? details_text : "",
1472
1485
help_callback (GtkWidget *widget, gpointer user_data)
1474
GnomeProgram *program = (GnomeProgram *)user_data;
1475
1487
GError *error = NULL;
1477
gnome_help_display_desktop (program,
1490
res = gtk_show_uri (gtk_widget_get_screen (widget),
1491
"ghelp:user-guide#feedback-bugs",
1492
gtk_get_current_event_time (), &error);
1484
1495
GtkWidget *error_dialog =
1485
1496
gtk_message_dialog_new (NULL,
1486
1497
GTK_DIALOG_MODAL,
1554
1565
g_return_if_fail (app != NULL);
1555
1566
g_return_if_fail (ui != NULL);
1568
/* fill the include info now that gdb has run */
1569
if (gopt_data.include_file != NULL) {
1570
fill_include_file (gopt_data.include_file, gopt_data.own_file, ui);
1557
1573
if (app->extra_info_script == NULL) {
1620
fill_include_file (char *filename, GtkBuilder *ui)
1636
fill_include_file (char *filename, gboolean own_file, GtkBuilder *ui)
1622
1638
GtkTextView *text_view;
1623
1639
GtkTextIter end;
1624
1640
GtkTextBuffer *buffer;
1626
1643
GError *error = NULL;
1628
if (g_file_get_contents (filename, &text, NULL, &error) != TRUE) {
1645
res = g_file_get_contents (filename, &text, NULL, &error);
1647
/* if own_file is set, delete the file regardless of the result:
1648
* if _get_contents () fails chances are the file has already been
1653
if (g_unlink (filename) == -1)
1654
g_warning ("Unable to delete %s", filename);
1629
1658
buddy_error (NULL, error->message);
1630
1659
g_error_free (error);
1634
1663
text_view = GTK_TEXT_VIEW (gtk_builder_get_object (ui, "gdb-text"));
1635
1664
buffer = gtk_text_view_get_buffer (text_view);
1636
1665
gtk_text_buffer_get_end_iter (buffer, &end);
1656
1700
g_return_if_fail (ui != NULL);
1658
1702
system_info = g_string_new ("");
1660
1705
if (uname (&uts_buf) == 0) {
1661
1706
g_string_append_printf (system_info, "System: %s %s %s %s\n", uts_buf.sysname, uts_buf.release, uts_buf.version, uts_buf.machine);
1693
1738
str = gconf_client_get_string (gconf_client, ICON_THEME_KEY, NULL);
1694
1739
g_string_append_printf (system_info, "Icon Theme: %s\n", str);
1742
/* add the GTK+ loaded modules. to do that, we look both in GConf and
1743
* inside the GTK_MODULES env var.
1746
entries = gconf_client_all_entries (gconf_client, GTK_MODULES_KEY, NULL);
1753
modules = g_string_new ("GTK+ Modules: ");
1755
for (l = entries; l != NULL; l = l->next) {
1757
val = gconf_entry_get_value (entry);
1759
/* if the value is a boolean, check if it's activated, otherwise if it's
1760
* a string, it will refer to a boolean; check that.
1761
* i know this is quite ugly.
1763
if ((val->type == GCONF_VALUE_BOOL && gconf_value_get_bool (val)) ||
1764
(val->type == GCONF_VALUE_STRING && gconf_client_get_bool (gconf_client,
1765
gconf_value_get_string (val),
1769
name = gconf_get_key_name_from_path (gconf_entry_get_key (entry));
1771
if (!g_strstr_len (modules->str, modules->len, name)) {
1772
g_string_append_printf (modules, "%s, ", name);
1778
gconf_entry_unref (entry);
1781
g_slist_free (entries);
1784
str = (char * ) g_getenv ("GTK_MODULES");
1790
modules = g_string_new ("GTK+ Modules: ");
1793
/* modules are divided by G_SEARCHPATH_SEPARATOR */
1794
splitted = pango_split_file_list (str);
1796
for (i = 0; splitted[i]; i++) {
1797
if (!g_strstr_len (modules->str, modules->len, splitted[i])) {
1798
g_string_append_printf (modules, "%s, ", splitted[i]);
1802
g_strfreev (splitted);
1806
/* discard the last ", " */
1807
g_string_append_len (system_info, modules->str, (modules->len - 2));
1808
g_string_append (system_info, "\n");
1809
g_string_free (modules, TRUE);
1696
1812
g_object_unref (gconf_client);
1698
1814
g_string_append (system_info, "\n");
1783
1899
guint progress;
1784
1900
GtkWidget *main_window;
1785
1901
GOptionContext *context;
1786
GnomeProgram *program;
1787
1902
guint source_id;
1788
1903
GError *err = NULL;
1789
1904
GtkBuilder *ui = NULL;
1791
1906
memset (&gopt_data, 0, sizeof (gopt_data));
1793
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
1794
bind_textdomain_codeset (PACKAGE, "UTF-8");
1795
textdomain (PACKAGE);
1908
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
1909
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1910
textdomain (GETTEXT_PACKAGE);
1797
1912
context = g_option_context_new (N_("\n\nBug Buddy is a utility that helps report debugging\n"
1798
1913
"information to the GNOME Bugzilla when a program crashes."));
1800
1915
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
1802
1916
g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
1804
program = gnome_program_init (PACKAGE, VERSION,
1807
GNOME_PARAM_GOPTION_CONTEXT, context,
1808
GNOME_PARAM_APP_DATADIR, BUDDY_DATADIR,
1809
GNOME_CLIENT_PARAM_SM_CONNECT, FALSE,
1917
g_option_context_add_group (context, gtk_get_option_group (TRUE));
1919
if (!g_option_context_parse (context, &argc, &argv, &err)) {
1920
g_critical ("Failed to parse arguments: %s\n", err->message);
1922
g_option_context_free (context);
1926
g_option_context_free (context);
1928
if (!bonobo_activation_is_initialized ())
1929
bonobo_activation_init (argc, argv);
1812
1931
g_set_application_name (_("Bug Buddy"));
1813
1932
gtk_window_set_default_icon_name ("bug-buddy");
1934
s = g_build_filename (BUDDY_DATADIR, "bug-buddy.gtkbuilder", NULL);
1816
s = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_DATADIR,
1817
"bug-buddy.gtkbuilder", TRUE, NULL);
1819
ui = gtk_builder_new ();
1820
gtk_builder_add_from_file (ui, s, &err);
1821
gtk_builder_set_translation_domain (ui, GETTEXT_PACKAGE);
1936
ui = gtk_builder_new ();
1937
gtk_builder_add_from_file (ui, s, &err);
1938
gtk_builder_set_translation_domain (ui, GETTEXT_PACKAGE);
1855
1969
gopt_data.include_file == NULL &&
1856
1970
gopt_data.minidump_file == NULL) {
1857
1971
buddy_error (NULL, _("Either --pid , --include or --minidump arguments are required.\n"));
1858
g_object_unref (program);
1975
if (gopt_data.own_file == TRUE && gopt_data.include_file == NULL) {
1976
buddy_error (NULL, _("The --unlink-tempfile option needs a --include argument.\n"));
1862
1980
/* get some information about the gnome version */
1863
1981
gnome_version = get_gnome_version_info ();
1874
1991
/* connect the signal handler for the help button */
1875
1992
g_signal_connect (gtk_builder_get_object (ui, "help-button"), "clicked",
1876
G_CALLBACK (help_callback), program);
1993
G_CALLBACK (help_callback), NULL);
1878
1995
gtk_widget_show (main_window);
1999
2115
gtk_entry_set_text (GTK_ENTRY (email_entry), default_email);
2000
2116
g_free (default_email);
2002
g_object_set_data (G_OBJECT (ui), "type", GINT_TO_POINTER(BUG_TYPE_REQUEST));
2005
if (gopt_data.include_file != NULL) {
2006
fill_include_file (gopt_data.include_file, ui);
2118
g_object_set_data (G_OBJECT (ui), "type", GINT_TO_POINTER (BUG_TYPE_REQUEST));
2010
2121
g_signal_connect (gtk_builder_get_object (ui, "close-button"), "clicked",
2011
2122
G_CALLBACK (close_callback), ui);
2015
g_object_unref (program);