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