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