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: 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 26 void GetPreferredSize(float *width, float *height) { 27 *width = Bounds().Width(); 28 *height = add_next_at; 29 } 30 31 void TargetedByScrollView(BScrollView *scroll_view) { scroll = scroll_view; /*scroll->ScrollBar(B_VERTICAL)->SetRange(0,add_next_at);*/ } 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 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 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 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 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 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 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 209 Error::Draw(BRect updateRect) 210 { 211 FillRect(updateRect, B_SOLID_LOW); 212 } 213 214 215 void 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