1 /* 2 * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "DebugWindow.h" 8 9 #include <algorithm> 10 #include <stdio.h> 11 12 #include <Button.h> 13 #include <Catalog.h> 14 #include <ControlLook.h> 15 #include <GroupLayout.h> 16 #include <LayoutBuilder.h> 17 #include <Locale.h> 18 #include <IconUtils.h> 19 #include <Resources.h> 20 #include <RadioButton.h> 21 #include <StripeView.h> 22 #include <TextView.h> 23 24 #undef B_TRANSLATION_CONTEXT 25 #define B_TRANSLATION_CONTEXT "DebugServer" 26 27 28 DebugWindow::DebugWindow(const char* appName) 29 : 30 BWindow(BRect(0, 0, 100, 50), "Crashed program", 31 B_MODAL_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL, 32 B_CLOSE_ON_ESCAPE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS), 33 fBitmap(IconSize(), B_RGBA32), 34 fSemaphore(create_sem(0, "DebugWindow")), 35 fAction(kActionKillTeam) 36 { 37 BString buffer(B_TRANSLATE( 38 "The application:\n\n %app\n\n" 39 "has encountered an error which prevents it from continuing. Haiku " 40 "will terminate the application and clean up.")); 41 buffer.ReplaceFirst("%app", appName); 42 43 BResources resources; 44 resources.SetToImage(B_TRANSLATION_CONTEXT); 45 size_t size; 46 const uint8* iconData = (const uint8*)resources.LoadResource('VICN', 2, 47 &size); 48 BIconUtils::GetVectorIcon(iconData, size, &fBitmap); 49 BStripeView *stripeView = new BStripeView(fBitmap); 50 51 BTextView *message = new BTextView("_tv_"); 52 message->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 53 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); 54 message->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor); 55 message->MakeEditable(false); 56 message->MakeSelectable(false); 57 message->SetWordWrap(true); 58 message->SetText(buffer); 59 message->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNSET)); 60 float width = message->StringWidth(appName) 61 + message->StringWidth(" ") * 12; 62 width = std::max(width, message->StringWidth("W") * 30); 63 message->SetExplicitMinSize(BSize(width, B_SIZE_UNSET)); 64 65 BRadioButton *terminate = new BRadioButton("terminate", 66 B_TRANSLATE("Terminate"), new BMessage(kActionKillTeam)); 67 #ifdef HANDOVER_USE_DEBUGGER 68 BRadioButton *report = new BRadioButton("report", 69 B_TRANSLATE("Save report"), new BMessage(kActionSaveReportTeam)); 70 #endif 71 BRadioButton *debug = new BRadioButton("debug", 72 B_TRANSLATE("Debug"), new BMessage(kActionDebugTeam)); 73 BRadioButton *core = new BRadioButton("core", 74 B_TRANSLATE("Write core file"), new BMessage(kActionWriteCoreFile)); 75 76 fOKButton = new BButton("close", B_TRANSLATE("Oh no!"), 77 new BMessage(B_QUIT_REQUESTED)); 78 fOKButton->MakeDefault(true); 79 80 terminate->SetValue(B_CONTROL_ON); 81 82 BLayoutBuilder::Group<>(this) 83 .AddGroup(B_HORIZONTAL) 84 .Add(stripeView) 85 .AddGroup(B_VERTICAL) 86 .SetInsets(B_USE_SMALL_SPACING) 87 .Add(message) 88 .AddGroup(B_VERTICAL, 0) 89 .Add(terminate) 90 .Add(debug) 91 .Add(report) 92 .Add(core) 93 .End() 94 .AddGroup(B_HORIZONTAL) 95 .AddGlue() 96 .Add(fOKButton) 97 .End() 98 .End() 99 .End(); 100 101 ResizeToPreferred(); 102 CenterOnScreen(); 103 } 104 105 106 DebugWindow::~DebugWindow() 107 { 108 delete_sem(fSemaphore); 109 } 110 111 112 void 113 DebugWindow::MessageReceived(BMessage* message) 114 { 115 switch(message->what) { 116 case B_QUIT_REQUESTED: 117 release_sem(fSemaphore); 118 break; 119 120 case kActionKillTeam: 121 case kActionDebugTeam: 122 case kActionWriteCoreFile: 123 case kActionSaveReportTeam: 124 fAction = message->what; 125 fOKButton->SetLabel(fAction == kActionDebugTeam 126 ? B_TRANSLATE("Oh yeah!") : B_TRANSLATE("Oh no!")); 127 return; 128 } 129 130 BWindow::MessageReceived(message); 131 } 132 133 134 int32 135 DebugWindow::Go() 136 { 137 Show(); 138 139 // Wait for user to close the window 140 acquire_sem(fSemaphore); 141 return fAction; 142 } 143 144 145 BRect 146 DebugWindow::IconSize() 147 { 148 return BRect(BPoint(0, 0), be_control_look->ComposeIconSize(32)); 149 } 150