Esempio n. 1
0
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
}
Esempio n. 2
0
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));
}