bool wxGUIAppTraits::ShowAssertDialog(const wxString& msg) { #if wxDEBUG_LEVEL // under GTK2 we prefer to use a dialog widget written using directly in // GTK+ as use a dialog written using wxWidgets would need the wxWidgets // idle processing to work correctly which might not be the case when // assert happens GtkWidget *dialog = gtk_assert_dialog_new(); gtk_assert_dialog_set_message(GTK_ASSERT_DIALOG(dialog), msg.mb_str()); #if wxUSE_STACKWALKER // don't show more than maxLines or we could get a dialog too tall to be // shown on screen: 20 should be ok everywhere as even with 15 pixel high // characters it is still only 300 pixels... static const int maxLines = 20; // save current stack frame... StackDump dump(GTK_ASSERT_DIALOG(dialog)); dump.SaveStack(maxLines); // ...but process it only if the user needs it gtk_assert_dialog_set_backtrace_callback(GTK_ASSERT_DIALOG(dialog), (GtkAssertDialogStackFrameCallback)get_stackframe_callback, &dump); #endif // wxUSE_STACKWALKER gint result = gtk_dialog_run(GTK_DIALOG (dialog)); bool returnCode = false; switch (result) { case GTK_ASSERT_DIALOG_STOP: wxTrap(); break; case GTK_ASSERT_DIALOG_CONTINUE: // nothing to do break; case GTK_ASSERT_DIALOG_CONTINUE_SUPPRESSING: // no more asserts returnCode = true; break; default: wxFAIL_MSG( _T("unexpected return code from GtkAssertDialog") ); } gtk_widget_destroy(dialog); return returnCode; #else // !wxDEBUG_LEVEL // this function is never called in this case wxUnusedVar(msg); return false; #endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL }
bool wxGUIAppTraits::ShowAssertDialog(const wxString& msg) { #if wxDEBUG_LEVEL // we can't show the dialog from another thread if ( wxIsMainThread() ) { // under GTK2 we prefer to use a dialog widget written using directly // in GTK+ as use a dialog written using wxWidgets would need the // wxWidgets idle processing to work correctly which might not be the // case when assert happens GtkWidget *dialog = gtk_assert_dialog_new(); gtk_assert_dialog_set_message(GTK_ASSERT_DIALOG(dialog), msg.mb_str()); #if wxUSE_STACKWALKER // save the current stack ow... StackDump dump(GTK_ASSERT_DIALOG(dialog)); dump.SaveStack(100); // showing more than 100 frames is not very useful // ...but process it only if the user needs it gtk_assert_dialog_set_backtrace_callback ( GTK_ASSERT_DIALOG(dialog), (GtkAssertDialogStackFrameCallback)get_stackframe_callback, &dump ); #endif // wxUSE_STACKWALKER gint result = gtk_dialog_run(GTK_DIALOG (dialog)); bool returnCode = false; switch (result) { case GTK_ASSERT_DIALOG_STOP: wxTrap(); break; case GTK_ASSERT_DIALOG_CONTINUE: // nothing to do break; case GTK_ASSERT_DIALOG_CONTINUE_SUPPRESSING: // no more asserts returnCode = true; break; default: wxFAIL_MSG( wxT("unexpected return code from GtkAssertDialog") ); } gtk_widget_destroy(dialog); return returnCode; } #endif // wxDEBUG_LEVEL return wxAppTraitsBase::ShowAssertDialog(msg); }
static void gtk_assert_dialog_init(GTypeInstance* instance, void*) { GtkAssertDialog* dlg = GTK_ASSERT_DIALOG(instance); GtkWidget *continuebtn; { GtkWidget *vbox, *hbox, *image; /* start the main vbox */ gtk_widget_push_composite_child (); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); gtk_container_set_border_width (GTK_CONTAINER(vbox), 8); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dlg))), vbox, true, true, 5); /* add the icon+message hbox */ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX(vbox), hbox, FALSE, FALSE, 0); /* icon */ image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX(hbox), image, FALSE, FALSE, 12); { GtkWidget *vbox2, *info; /* message */ vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0); info = gtk_label_new ("An assertion failed!"); gtk_box_pack_start (GTK_BOX(vbox2), info, TRUE, TRUE, 8); /* assert message */ dlg->message = gtk_label_new (NULL); gtk_label_set_selectable (GTK_LABEL (dlg->message), TRUE); gtk_label_set_line_wrap (GTK_LABEL (dlg->message), TRUE); gtk_label_set_justify (GTK_LABEL (dlg->message), GTK_JUSTIFY_LEFT); gtk_widget_set_size_request (GTK_WIDGET(dlg->message), 450, -1); gtk_box_pack_end (GTK_BOX(vbox2), GTK_WIDGET(dlg->message), TRUE, TRUE, 8); } #if wxUSE_STACKWALKER /* add the expander */ dlg->expander = gtk_expander_new_with_mnemonic ("Back_trace:"); gtk_box_pack_start (GTK_BOX(vbox), dlg->expander, TRUE, TRUE, 0); g_signal_connect (dlg->expander, "activate", G_CALLBACK(gtk_assert_dialog_expander_callback), dlg); #endif // wxUSE_STACKWALKER } #if wxUSE_STACKWALKER { GtkWidget *hbox, *vbox, *button, *sw; /* create expander's vbox */ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (dlg->expander), vbox); /* add a scrollable window under the expander */ sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX(vbox), sw, TRUE, TRUE, 8); /* add the treeview to the scrollable window */ dlg->treeview = gtk_assert_dialog_create_backtrace_list_model (); gtk_widget_set_size_request (GTK_WIDGET(dlg->treeview), -1, 180); gtk_container_add (GTK_CONTAINER (sw), dlg->treeview); /* create button's hbox */ hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); gtk_box_pack_end (GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_button_box_set_layout (GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END); /* add the buttons */ button = gtk_assert_dialog_add_button_to (GTK_BOX(hbox), "Save to _file", GTK_STOCK_SAVE); g_signal_connect (button, "clicked", G_CALLBACK(gtk_assert_dialog_save_backtrace_callback), dlg); button = gtk_assert_dialog_add_button_to (GTK_BOX(hbox), "Copy to clip_board", GTK_STOCK_COPY); g_signal_connect (button, "clicked", G_CALLBACK(gtk_assert_dialog_copy_callback), dlg); } #endif // wxUSE_STACKWALKER /* add the checkbutton */ dlg->shownexttime = gtk_check_button_new_with_mnemonic("Show this _dialog the next time"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(dlg->shownexttime), TRUE); gtk_box_pack_end(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(dlg))), dlg->shownexttime, false, true, 8); /* add the stop button */ gtk_assert_dialog_add_button (dlg, "_Stop", GTK_STOCK_QUIT, GTK_ASSERT_DIALOG_STOP); /* add the continue button */ continuebtn = gtk_assert_dialog_add_button (dlg, "_Continue", GTK_STOCK_YES, GTK_ASSERT_DIALOG_CONTINUE); gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_ASSERT_DIALOG_CONTINUE); g_signal_connect (continuebtn, "clicked", G_CALLBACK(gtk_assert_dialog_continue_callback), dlg); /* complete creation */ dlg->callback = NULL; dlg->userdata = NULL; /* the resizable property of this window is modified by the expander: when it's collapsed, the window must be non-resizable! */ gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE); gtk_widget_pop_composite_child (); gtk_widget_show_all (GTK_WIDGET(dlg)); }