1 /* 2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "ActivityWindow.h" 8 9 #include <stdio.h> 10 11 #include <Application.h> 12 #include <File.h> 13 #include <FindDirectory.h> 14 #ifdef __HAIKU__ 15 #include <GroupLayout.h> 16 #endif 17 #include <Menu.h> 18 #include <MenuBar.h> 19 #include <MenuItem.h> 20 #include <Path.h> 21 #include <Roster.h> 22 23 #include "ActivityMonitor.h" 24 #include "ActivityView.h" 25 26 27 static const uint32 kMsgAddView = 'advw'; 28 29 30 ActivityWindow::ActivityWindow() 31 : BWindow(BRect(100, 100, 500, 250), "ActivityMonitor", B_TITLED_WINDOW, 32 B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE) 33 { 34 BMessage settings; 35 _LoadSettings(settings); 36 37 BRect frame; 38 if (settings.FindRect("window frame", &frame) == B_OK) { 39 MoveTo(frame.LeftTop()); 40 ResizeTo(frame.Width(), frame.Height()); 41 } 42 43 #ifdef __HAIKU__ 44 BGroupLayout* layout = new BGroupLayout(B_VERTICAL); 45 SetLayout(layout); 46 47 // create GUI 48 49 BMenuBar* menuBar = new BMenuBar("menu"); 50 layout->AddView(menuBar); 51 52 fLayout = new BGroupLayout(B_VERTICAL); 53 float inset = ceilf(be_plain_font->Size() * 0.7); 54 fLayout->SetInsets(inset, inset, inset, inset); 55 fLayout->SetSpacing(inset); 56 57 BView* top = new BView("top", 0, fLayout); 58 top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 59 layout->AddView(top); 60 61 BMessage viewState; 62 int32 count = 0; 63 for (int32 i = 0; settings.FindMessage("activity view", i, &viewState) 64 == B_OK; i++) { 65 ActivityView* view = new ActivityView("ActivityMonitor", &viewState); 66 fLayout->AddItem(view->CreateHistoryLayoutItem()); 67 fLayout->AddItem(view->CreateLegendLayoutItem()); 68 count++; 69 } 70 if (count == 0) { 71 ActivityView* view = new ActivityView("ActivityMonitor", NULL); 72 fLayout->AddItem(view->CreateHistoryLayoutItem()); 73 fLayout->AddItem(view->CreateLegendLayoutItem()); 74 } 75 76 #else 77 BView *layout = new BView(Bounds(), "topmost", B_FOLLOW_NONE, 0); 78 AddChild(layout); 79 80 // create GUI 81 BRect mbRect(Bounds()); 82 mbRect.bottom = 10; 83 BMenuBar* menuBar = new BMenuBar(mbRect, "menu"); 84 layout->AddChild(menuBar); 85 86 BRect topRect(Bounds()); 87 topRect.top = menuBar->Bounds().bottom + 1; 88 89 BView* top = new BView(topRect, "top", B_FOLLOW_ALL, 0); 90 top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 91 layout->AddChild(top); 92 93 BMessage viewState; 94 int32 count = 0; 95 ActivityView *aview; 96 BRect rect; 97 for (int32 i = 0; settings.FindMessage("activity view", i, &viewState) 98 == B_OK; i++) { 99 aview = new ActivityView("ActivityMonitor", &viewState); 100 if (!rect.IsValid()) 101 rect = aview->Bounds(); 102 else 103 rect.OffsetBySelf(0.0, aview->Bounds().Height()); 104 top->AddChild(aview); 105 count++; 106 } 107 if (count == 0) 108 top->AddChild(new ActivityView("ActivityMonitor", NULL)); 109 110 #endif 111 // add menu 112 113 // "File" menu 114 BMenu* menu = new BMenu("File"); 115 BMenuItem* item; 116 117 menu->AddItem(new BMenuItem("Add View", new BMessage(kMsgAddView))); 118 menu->AddSeparatorItem(); 119 120 menu->AddItem(item = new BMenuItem("About ActivityMonitor" B_UTF8_ELLIPSIS, 121 new BMessage(B_ABOUT_REQUESTED))); 122 menu->AddSeparatorItem(); 123 124 menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q')); 125 menu->SetTargetForItems(this); 126 item->SetTarget(be_app); 127 menuBar->AddItem(menu); 128 } 129 130 131 ActivityWindow::~ActivityWindow() 132 { 133 } 134 135 136 status_t 137 ActivityWindow::_OpenSettings(BFile& file, uint32 mode) 138 { 139 BPath path; 140 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 141 return B_ERROR; 142 143 path.Append("ActivityMonitor settings"); 144 145 return file.SetTo(path.Path(), mode); 146 } 147 148 149 status_t 150 ActivityWindow::_LoadSettings(BMessage& settings) 151 { 152 BFile file; 153 status_t status = _OpenSettings(file, B_READ_ONLY); 154 if (status < B_OK) 155 return status; 156 157 return settings.Unflatten(&file); 158 } 159 160 161 status_t 162 ActivityWindow::_SaveSettings() 163 { 164 BFile file; 165 status_t status = _OpenSettings(file, B_WRITE_ONLY | B_CREATE_FILE 166 | B_ERASE_FILE); 167 if (status < B_OK) 168 return status; 169 170 BMessage settings('actm'); 171 status = settings.AddRect("window frame", Frame()); 172 if (status != B_OK) 173 return status; 174 175 #ifdef __HAIKU__ 176 BView* top = fLayout->View(); 177 #else 178 BView* top = ChildAt(0); 179 #endif 180 int32 count = top->CountChildren(); 181 for (int32 i = 0; i < count; i++) { 182 ActivityView* view = dynamic_cast<ActivityView*>(top->ChildAt(i)); 183 if (view == NULL) 184 continue; 185 186 BMessage* viewState = new BMessage; 187 status = view->SaveState(*viewState); 188 if (status == B_OK) 189 status = settings.AddMessage("activity view", viewState); 190 if (status != B_OK) { 191 delete viewState; 192 break; 193 } 194 } 195 196 if (status == B_OK) 197 status = settings.Flatten(&file); 198 199 return status; 200 } 201 202 203 int32 204 ActivityWindow::ActivityViewCount() 205 { 206 #ifdef __HAIKU__ 207 return fLayout->View()->CountChildren(); 208 #else 209 return 1; 210 #endif 211 } 212 213 214 void 215 ActivityWindow::_MessageDropped(BMessage* message) 216 { 217 entry_ref ref; 218 if (message->FindRef("refs", &ref) != B_OK) { 219 // TODO: If app, then launch it, and add ActivityView for this one? 220 } 221 } 222 223 224 void 225 ActivityWindow::MessageReceived(BMessage* message) 226 { 227 if (message->WasDropped()) { 228 _MessageDropped(message); 229 return; 230 } 231 232 switch (message->what) { 233 case B_REFS_RECEIVED: 234 case B_SIMPLE_DATA: 235 _MessageDropped(message); 236 break; 237 238 case kMsgAddView: 239 { 240 #ifdef __HAIKU__ 241 BView* firstView = fLayout->View()->ChildAt(0); 242 243 ActivityView* view = new ActivityView("ActivityMonitor", NULL); 244 fLayout->AddItem(view->CreateHistoryLayoutItem()); 245 fLayout->AddItem(view->CreateLegendLayoutItem()); 246 247 if (firstView != NULL) 248 ResizeBy(0, firstView->Bounds().Height() + fLayout->Spacing()); 249 #endif 250 break; 251 } 252 253 case kMsgRemoveView: 254 { 255 #ifdef __HAIKU__ 256 BView* view; 257 if (message->FindPointer("view", (void**)&view) != B_OK) 258 break; 259 260 view->RemoveSelf(); 261 ResizeBy(0, -view->Bounds().Height() - fLayout->Spacing()); 262 delete view; 263 #endif 264 break; 265 } 266 267 default: 268 BWindow::MessageReceived(message); 269 break; 270 } 271 } 272 273 274 bool 275 ActivityWindow::QuitRequested() 276 { 277 _SaveSettings(); 278 be_app->PostMessage(B_QUIT_REQUESTED); 279 return true; 280 } 281