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