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