xref: /haiku/src/servers/mail/ErrorLogWindow.cpp (revision 65d8c2f34fa78c0155cc64dc63e2fea4e0774347)
1 #include <ScrollView.h>
2 #include <TextView.h>
3 #include <String.h>
4 #include <limits.h>
5 
6 #include "ErrorLogWindow.h"
7 
8 rgb_color white = {255,255,255,255};
9 rgb_color notwhite = {255,255,200,255};
10 
11 class Error : public BView {
12 	public:
13 		Error(BRect rect,alert_type type,const char *tag,const char *message,bool timestamp,rgb_color bkg);
14 
15 		void GetPreferredSize(float *width, float *height);
16 		void Draw(BRect updateRect);
17 		void FrameResized(float w, float h);
18 	private:
19 		alert_type type;
20 };
21 
22 class ErrorPanel : public BView {
23 	public:
ErrorPanel(BRect rect)24 		ErrorPanel(BRect rect) : BView(rect,"ErrorScrollPanel",B_FOLLOW_ALL_SIDES,B_DRAW_ON_CHILDREN | B_FRAME_EVENTS), alerts_displayed(0), add_next_at(0) {}
25 
GetPreferredSize(float * width,float * height)26 		void GetPreferredSize(float *width, float *height) {
27 			*width = Bounds().Width();
28 			*height = add_next_at;
29 		}
30 
TargetedByScrollView(BScrollView * scroll_view)31 		void TargetedByScrollView(BScrollView *scroll_view) { scroll = scroll_view; /*scroll->ScrollBar(B_VERTICAL)->SetRange(0,add_next_at);*/ }
FrameResized(float w,float)32 		void FrameResized(float w, float /*h*/) {
33 			add_next_at = 0;
34 			for (int32 i = 0; i < CountChildren(); i++) {
35 				ChildAt(i)->MoveTo(BPoint(0,add_next_at));
36 				ChildAt(i)->ResizeTo(w, ChildAt(i)->Frame().Height());
37 				ChildAt(i)->ResizeToPreferred();
38 				add_next_at += ChildAt(i)->Bounds().Height();
39 			}
40 		}
41 		int32 alerts_displayed;
42 		float add_next_at;
43 		BScrollView *scroll;
44 };
45 
46 
47 //	#pragma mark -
48 
49 
ErrorLogWindow(BRect rect,const char * name,window_type type)50 ErrorLogWindow::ErrorLogWindow(BRect rect, const char *name, window_type type)
51 	:
52 	BWindow(rect, name, type, B_NO_WORKSPACE_ACTIVATION | B_NOT_MINIMIZABLE
53 		| B_ASYNCHRONOUS_CONTROLS),
54 	fIsRunning(false)
55 {
56 	rect = Bounds();
57 	rect.right -= B_V_SCROLL_BAR_WIDTH;
58 
59 	view = new ErrorPanel(rect);
60 	AddChild(new BScrollView("ErrorScroller", view, B_FOLLOW_ALL_SIDES, 0, false, true));
61 	Show();
62 	Hide();
63 }
64 
65 
66 void
AddError(alert_type type,const char * message,const char * tag,bool timestamp)67 ErrorLogWindow::AddError(alert_type type, const char *message, const char *tag, bool timestamp)
68 {
69 	ErrorPanel *panel = (ErrorPanel *)view;
70 
71 	// first call?
72 	if (!fIsRunning) {
73 		fIsRunning = true;
74 		Show();
75 	}
76 
77 	Lock();
78 
79 	Error *newError = new Error(BRect(0, panel->add_next_at, panel->Bounds().right,
80 		panel->add_next_at + 1), type, tag, message, timestamp,
81 		(panel->alerts_displayed++ % 2 == 0) ? white : notwhite);
82 
83 	newError->ResizeToPreferred();
84 	panel->add_next_at += newError->Bounds().Height();
85 	panel->AddChild(newError);
86 	panel->ResizeToPreferred();
87 
88 	if (panel->add_next_at > Frame().Height()) {
89 		BScrollBar *bar = panel->scroll->ScrollBar(B_VERTICAL);
90 
91 		bar->SetRange(0, panel->add_next_at - Frame().Height());
92 		bar->SetSteps(1, Frame().Height());
93 		bar->SetProportion(Frame().Height() / panel->add_next_at);
94 	} else
95 		panel->scroll->ScrollBar(B_VERTICAL)->SetRange(0,0);
96 
97 	if (IsHidden())
98 		Show();
99 
100 	Unlock();
101 }
102 
103 
104 bool
QuitRequested()105 ErrorLogWindow::QuitRequested()
106 {
107 	Hide();
108 
109 	while (view->CountChildren() != 0) {
110 		BView* child = view->ChildAt(0);
111 		view->RemoveChild(child);
112 		delete child;
113 	}
114 
115 	ErrorPanel *panel = (ErrorPanel *)(view);
116 	panel->add_next_at = 0;
117 	panel->alerts_displayed = 0;
118 
119 	view->ResizeToPreferred();
120 	return false;
121 }
122 
123 
124 void
FrameResized(float newWidth,float newHeight)125 ErrorLogWindow::FrameResized(float newWidth, float newHeight)
126 {
127 	ErrorPanel *panel = (ErrorPanel *)view;
128 	panel->Invalidate();
129 
130 	if (panel->add_next_at > newHeight) {
131 		BScrollBar *bar = panel->scroll->ScrollBar(B_VERTICAL);
132 
133 		bar->SetRange(0, panel->add_next_at - Frame().Height());
134 		bar->SetSteps(1, Frame().Height());
135 		bar->SetProportion(Frame().Height() / panel->add_next_at);
136 	} else
137 		panel->scroll->ScrollBar(B_VERTICAL)->SetRange(0,0);
138 }
139 
140 
141 //	#pragma mark -
142 
143 
Error(BRect rect,alert_type atype,const char * tag,const char * message,bool timestamp,rgb_color bkg)144 Error::Error(BRect rect, alert_type atype, const char *tag, const char *message,
145 	bool timestamp,rgb_color bkg)
146 	:
147 	BView(rect,"error",B_FOLLOW_LEFT | B_FOLLOW_RIGHT
148 		| B_FOLLOW_TOP,B_NAVIGABLE | B_WILL_DRAW | B_FRAME_EVENTS),
149 	type(atype)
150 {
151 	SetViewColor(bkg);
152 	SetLowColor(bkg);
153 
154 	text_run_array array;
155 	array.count = 1;
156 	array.runs[0].offset = 0;
157 	array.runs[0].font = *be_bold_font;
158 	array.runs[0].color = HighColor();
159 
160 	BString msgString(message);
161 	msgString.RemoveAll("\r");
162 
163 	BTextView *view = new BTextView(BRect(20, 0, rect.Width(), rect.Height()),
164 		"error_display", BRect(0,3,rect.Width() - 20 - 3, LONG_MAX),
165 		B_FOLLOW_ALL_SIDES);
166 	view->SetLowColor(bkg);
167 	view->SetViewColor(bkg);
168 	view->SetText(msgString.String());
169 	view->MakeSelectable(true);
170 	view->SetStylable(true);
171 	view->MakeEditable(false);
172 
173 	if (tag != NULL) {
174 		BString tagString(tag);
175 		tagString += " ";
176 		view->Insert(0, tagString.String(), tagString.Length(), &array);
177 	}
178 
179 	if (timestamp) {
180 		array.runs[0].color = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),B_DARKEN_2_TINT);
181 		array.runs[0].font.SetSize(9);
182 		time_t thetime = time(NULL);
183 		BString atime = asctime(localtime(&thetime));
184 		atime.Prepend(" [");
185 		atime.RemoveAll("\n");
186 		atime.Append("]");
187 		view->Insert(view->TextLength(),atime.String(),atime.Length(),&array);
188 	}
189 
190 	float height,width;
191 	width = view->Frame().Width();
192 	height = view->TextHeight(0,view->CountLines()) + 3;
193 	view->ResizeTo(width,height);
194 	AddChild(view);
195 }
196 
197 
198 void
GetPreferredSize(float * width,float * height)199 Error::GetPreferredSize(float *width, float *height)
200 {
201 	BTextView *view = static_cast<BTextView *>(FindView("error_display"));
202 
203 	*width = view->Frame().Width() + 20;
204 	*height = view->TextHeight(0, INT32_MAX) + 3;
205 }
206 
207 
208 void
Draw(BRect updateRect)209 Error::Draw(BRect updateRect)
210 {
211 	FillRect(updateRect, B_SOLID_LOW);
212 }
213 
214 
215 void
FrameResized(float w,float h)216 Error::FrameResized(float w, float h)
217 {
218 	BTextView *view = static_cast<BTextView *>(FindView("error_display"));
219 
220 	view->ResizeTo(w - 20, h);
221 	view->SetTextRect(BRect(0, 3, w - 20, h));
222 }
223