xref: /haiku/src/servers/debug/DebugWindow.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
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