1 /* PoorManWindow.cpp 2 * 3 * Philip Harrison 4 * Started: 4/25/2004 5 * Version: 0.1 6 */ 7 8 #include "PoorManWindow.h" 9 10 #include <string.h> 11 #include <time.h> 12 #include <arpa/inet.h> 13 14 #include <Alert.h> 15 #include <Box.h> 16 #include <Directory.h> 17 #include <File.h> 18 #include <FindDirectory.h> 19 #include <Menu.h> 20 #include <MenuBar.h> 21 #include <MenuItem.h> 22 #include <Path.h> 23 #include <ScrollBar.h> 24 #include <ScrollView.h> 25 #include <StringView.h> 26 #include <TypeConstants.h> 27 #include <OS.h> 28 29 #include "PoorManApplication.h" 30 #include "PoorManPreferencesWindow.h" 31 #include "PoorManView.h" 32 #include "PoorManServer.h" 33 #include "PoorManLogger.h" 34 #include "constants.h" 35 36 37 PoorManWindow::PoorManWindow(BRect frame) 38 : BWindow(frame, STR_APP_NAME, B_TITLED_WINDOW, 0), 39 status(false), hits(0), prefWindow(NULL), fLogFile(NULL), fServer(NULL) 40 { 41 //preferences init 42 web_directory.SetTo(STR_DEFAULT_WEB_DIRECTORY); 43 index_file_name.SetTo("index.html"); 44 dir_list_flag = false; 45 46 log_console_flag = true; 47 log_file_flag = false; 48 log_path.SetTo(""); 49 50 max_connections = (int16)32; 51 52 is_zoomed = true; 53 last_width = 318.0f; 54 last_height = 320.0f; 55 this->frame = frame; 56 setwindow_frame.Set(112.0f, 60.0f, 492.0f, 340.0f); 57 58 // PoorMan Window 59 SetSizeLimits(318, 1600, 53, 1200); 60 // limit the size of the size of the window 61 62 //SetZoomLimits(1024, 768); 63 64 //frame.Set(30.0f, 30.0f, 355.0f, 185.0f); 65 frame.OffsetTo(B_ORIGIN); 66 frame = Bounds(); 67 frame.top += 19.0; 68 69 mainView = new PoorManView(frame, STR_APP_NAME); 70 mainView->SetViewColor(216,216,216,255); 71 72 mainView->SetFont(be_bold_font); 73 mainView->SetFontSize(12); 74 AddChild(mainView); 75 76 // BBox tests 77 BRect br; 78 br = mainView->Bounds(); 79 br.top = 1.0; 80 81 BBox * bb = new BBox(br, "Background", B_FOLLOW_ALL_SIDES, 82 B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE); 83 bb->SetHighColor(WHITE); 84 bb->SetLowColor(GRAY); 85 bb->SetBorder(B_PLAIN_BORDER); 86 mainView->AddChild(bb); 87 88 // ----------------------------------------------------------------- 89 // Three Labels 90 91 // Status String 92 BRect statusRect; 93 statusRect = Bounds(); 94 statusRect.left += 5; 95 statusRect.top += 3; 96 statusRect.bottom = statusRect.top + 15; 97 statusRect.right = statusRect.left + 100; // make the width wide enough for the string to display 98 99 statusView = new BStringView(statusRect, "Status View", "Status: Stopped"); 100 bb->AddChild(statusView); 101 102 // Directory String 103 BRect dirRect; 104 dirRect = Bounds(); 105 dirRect.top = statusRect.bottom - 1; 106 dirRect.bottom = dirRect.top + 15; 107 dirRect.left = statusRect.left; 108 dirRect.right -= 5; 109 110 dirView = new BStringView(dirRect, "Dir View", "Directory: (none)", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); 111 bb->AddChild(dirView); 112 113 // Hits String 114 BRect hitsRect; 115 hitsRect = bb->Bounds(); 116 hitsRect.InsetBy(5.0f, 5.0f); 117 hitsRect.top = statusRect.top; 118 hitsRect.bottom = statusRect.bottom; 119 hitsRect.left = statusRect.right + 20; 120 121 hitsView = new BStringView(hitsRect, "Hit View", "Hits: 0", B_FOLLOW_RIGHT | B_FOLLOW_TOP); 122 hitsView->SetAlignment(B_ALIGN_RIGHT); 123 bb->AddChild(hitsView); 124 125 // ----------------------------------------------------------------- 126 // Logging View 127 128 // logRect 129 BRect logRect = bb->Bounds();//(5.0, 36.0, 306.0, 131.0); 130 logRect.InsetBy(5, 5); 131 logRect.top = 36.0f; 132 logRect.right -= B_V_SCROLL_BAR_WIDTH; 133 134 // textRect 135 BRect textRect; //(1.0, 1.0, 175.0, 75.0); 136 textRect = logRect; 137 textRect.top = 0.0; 138 textRect.left = 2.0; 139 textRect.right = logRect.right - logRect.left - 2.0; 140 textRect.bottom = logRect.bottom - logRect.top; 141 142 fLogViewFont = new BFont(be_plain_font); 143 fLogViewFont->SetSize(11.0); 144 145 loggingView = new BTextView(logRect, STR_TXT_VIEW, textRect, 146 fLogViewFont, NULL, B_FOLLOW_ALL_SIDES, B_WILL_DRAW ); 147 148 loggingView->MakeEditable(false); // user cannot change the text 149 loggingView->MakeSelectable(true); 150 loggingView->SetViewColor(WHITE); 151 loggingView->SetStylable(true); 152 153 // create the scroll view 154 scrollView = new BScrollView("Scroll View", loggingView, B_FOLLOW_ALL_SIDES, 155 B_WILL_DRAW | B_FRAME_EVENTS, 156 // Make sure articles on border do not occur when resizing 157 false, true); 158 bb->AddChild(scrollView); 159 loggingView->MakeFocus(true); 160 161 162 // ----------------------------------------------------------------- 163 // menu bar 164 BRect menuRect; 165 menuRect = Bounds(); 166 menuRect.bottom = 18.0f; 167 168 FileMenuBar = new BMenuBar(menuRect, "File Menu Bar"); 169 170 // menus 171 FileMenu = BuildFileMenu(); 172 if (FileMenu) 173 FileMenuBar->AddItem(FileMenu); 174 175 EditMenu = BuildEditMenu(); 176 if (EditMenu) 177 FileMenuBar->AddItem(EditMenu); 178 179 ControlsMenu = BuildControlsMenu(); 180 if (ControlsMenu) 181 FileMenuBar->AddItem(ControlsMenu); 182 183 // File Panels 184 BWindow* change_title; 185 186 BMessenger messenger(this); 187 saveConsoleFilePanel = new BFilePanel( 188 B_SAVE_PANEL, 189 &messenger, 190 NULL, 191 B_FILE_NODE, 192 false, 193 new BMessage(MSG_FILE_PANEL_SAVE_CONSOLE)); 194 195 change_title = saveConsoleFilePanel->Window(); 196 change_title->SetTitle(STR_FILEPANEL_SAVE_CONSOLE); 197 198 saveConsoleSelectionFilePanel = new BFilePanel( 199 B_SAVE_PANEL, 200 &messenger, 201 NULL, 202 B_FILE_NODE, 203 false, 204 new BMessage(MSG_FILE_PANEL_SAVE_CONSOLE_SELECTION)); 205 206 change_title = saveConsoleSelectionFilePanel->Window(); 207 change_title->SetTitle(STR_FILEPANEL_SAVE_CONSOLE_SELECTION); 208 209 210 AddChild(FileMenuBar); 211 212 pthread_rwlock_init(&fLogFileLock, NULL); 213 } 214 215 216 PoorManWindow::~PoorManWindow() 217 { 218 delete fServer; 219 delete fLogViewFont; 220 delete fLogFile; 221 pthread_rwlock_destroy(&fLogFileLock); 222 } 223 224 225 void 226 PoorManWindow::MessageReceived(BMessage* message) 227 { 228 switch (message->what) { 229 case MSG_MENU_FILE_SAVE_AS: 230 saveConsoleFilePanel->Show(); 231 break; 232 case MSG_FILE_PANEL_SAVE_CONSOLE: 233 printf("FilePanel: Save console\n"); 234 SaveConsole(message, false); 235 break; 236 case MSG_MENU_FILE_SAVE_SELECTION: 237 saveConsoleSelectionFilePanel->Show(); 238 break; 239 case MSG_FILE_PANEL_SAVE_CONSOLE_SELECTION: 240 printf("FilePanel: Save console selection\n"); 241 SaveConsole(message, true); 242 break; 243 case MSG_FILE_PANEL_SELECT_WEB_DIR: 244 prefWindow->MessageReceived(message); 245 break; 246 case MSG_MENU_EDIT_PREF: 247 prefWindow = new PoorManPreferencesWindow( 248 setwindow_frame, 249 STR_WIN_NAME_PREF); 250 prefWindow->Show(); 251 break; 252 case MSG_MENU_CTRL_RUN: 253 if (status) 254 StopServer(); 255 else 256 StartServer(); 257 break; 258 case MSG_MENU_CTRL_CLEAR_HIT: 259 SetHits(0); 260 //UpdateHitsLabel(); 261 break; 262 case MSG_MENU_CTRL_CLEAR_CONSOLE: 263 loggingView->SelectAll(); 264 loggingView->Delete(); 265 break; 266 case MSG_MENU_CTRL_CLEAR_LOG: 267 FILE * f; 268 f = fopen(log_path.String(), "w"); 269 fclose(f); 270 break; 271 case MSG_LOG: { 272 if (!log_console_flag && !log_file_flag) 273 break; 274 275 time_t time; 276 in_addr_t address; 277 rgb_color color; 278 const void* pointer; 279 ssize_t size; 280 const char* msg; 281 BString line; 282 283 if (message->FindString("cstring", &msg) != B_OK) 284 break; 285 if (message->FindData("time_t", B_TIME_TYPE, &pointer, &size) != B_OK) 286 time = -1; 287 else 288 time = *static_cast<const time_t*>(pointer); 289 290 if (message->FindData("in_addr_t", B_ANY_TYPE, &pointer, &size) != B_OK) 291 address = INADDR_NONE; 292 else 293 address = *static_cast<const in_addr_t*>(pointer); 294 295 if (message->FindData("rgb_color", B_RGB_COLOR_TYPE, &pointer, &size) != B_OK) 296 color = BLACK; 297 else 298 color = *static_cast<const rgb_color*>(pointer); 299 300 if (time != -1) { 301 char timeString[26]; 302 if (ctime_r(&time, timeString) != NULL) { 303 timeString[24] = '\0'; 304 line << '[' << timeString << "]: "; 305 } 306 } 307 308 if (address != INADDR_NONE) { 309 char addr[INET_ADDRSTRLEN]; 310 struct in_addr sin_addr; 311 sin_addr.s_addr = address; 312 if (inet_ntop(AF_INET, &sin_addr, addr, sizeof(addr)) != NULL) { 313 addr[strlen(addr)] = '\0'; 314 line << '(' << addr << ") "; 315 } 316 } 317 318 line << msg; 319 320 text_run run; 321 text_run_array runs; 322 323 run.offset = 0; 324 run.font = *fLogViewFont; 325 run.color = color; 326 327 runs.count = 1; 328 runs.runs[0] = run; 329 330 if (Lock()) { 331 if (log_console_flag) { 332 loggingView->Insert(loggingView->TextLength(), 333 line.String(), line.Length(), &runs); 334 loggingView->ScrollToOffset(loggingView->TextLength()); 335 } 336 337 if (log_file_flag) { 338 if (pthread_rwlock_rdlock(&fLogFileLock) == 0) { 339 fLogFile->Write(line.String(), line.Length()); 340 pthread_rwlock_unlock(&fLogFileLock); 341 } 342 } 343 344 Unlock(); 345 } 346 347 break; 348 } 349 default: 350 BWindow::MessageReceived(message); 351 break; 352 } 353 } 354 355 356 void 357 PoorManWindow::FrameMoved(BPoint origin) 358 { 359 frame.left = origin.x; 360 frame.top = origin.y; 361 } 362 363 364 void 365 PoorManWindow::FrameResized(float width, float height) 366 { 367 if (is_zoomed) { 368 last_width = width; 369 last_height = height; 370 } 371 } 372 373 374 bool 375 PoorManWindow::QuitRequested() 376 { 377 if (status) { 378 time_t now = time(NULL); 379 char line[] = "[Thu Jan 1 00:00:00 1970]: Shutting down.\n"; 380 381 ctime_r(&now, line + 1); 382 line[25] = ']'; 383 line[26] = ' '; 384 385 if (log_console_flag) { 386 loggingView->Insert(loggingView->TextLength(), 387 line, strlen(line)); 388 loggingView->ScrollToOffset(loggingView->TextLength()); 389 } 390 391 if (log_file_flag) { 392 if (pthread_rwlock_rdlock(&fLogFileLock) == 0) { 393 fLogFile->Write(line, strlen(line)); 394 pthread_rwlock_unlock(&fLogFileLock); 395 } 396 } 397 398 fServer->Stop(); 399 status = false; 400 UpdateStatusLabelAndMenuItem(); 401 } 402 403 SaveSettings(); 404 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 405 return true; 406 } 407 408 409 void 410 PoorManWindow::Zoom(BPoint origin, float width, float height) 411 { 412 if (is_zoomed) { 413 // Change to the Minimal size 414 is_zoomed = false; 415 ResizeTo(318, 53); 416 } else { 417 // Change to the Zoomed size 418 is_zoomed = true; 419 ResizeTo(last_width, last_height); 420 } 421 } 422 423 424 void 425 PoorManWindow::SetHits(uint32 num) 426 { 427 hits = num; 428 UpdateHitsLabel(); 429 } 430 431 432 // Private: Methods ------------------------------------------ 433 434 435 BMenu * 436 PoorManWindow::BuildFileMenu() const 437 { 438 BMenu * ptrFileMenu = new BMenu(STR_MNU_FILE); 439 440 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_SAVE_AS, 441 new BMessage(MSG_MENU_FILE_SAVE_AS), CMD_FILE_SAVE_AS)); 442 443 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_SAVE_SELECTION, 444 new BMessage(MSG_MENU_FILE_SAVE_SELECTION))); 445 446 ptrFileMenu->AddSeparatorItem(); 447 448 // about box 449 BMenuItem * AboutItem = new BMenuItem(STR_MNU_FILE_ABOUT, 450 new BMessage(B_ABOUT_REQUESTED)); 451 AboutItem->SetTarget(NULL, be_app); 452 ptrFileMenu->AddItem(AboutItem); 453 454 ptrFileMenu->AddSeparatorItem(); 455 456 457 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_QUIT, 458 new BMessage(B_QUIT_REQUESTED), CMD_FILE_QUIT)); 459 460 return ptrFileMenu; 461 } 462 463 464 BMenu * 465 PoorManWindow::BuildEditMenu() const 466 { 467 BMenu * ptrEditMenu = new BMenu(STR_MNU_EDIT); 468 469 BMenuItem * CopyMenuItem = new BMenuItem(STR_MNU_EDIT_COPY, 470 new BMessage(B_COPY), CMD_EDIT_COPY); 471 472 ptrEditMenu->AddItem(CopyMenuItem); 473 CopyMenuItem->SetTarget(loggingView, NULL); 474 475 ptrEditMenu->AddSeparatorItem(); 476 477 BMenuItem * SelectAllMenuItem = new BMenuItem(STR_MNU_EDIT_SELECT_ALL, 478 new BMessage(B_SELECT_ALL), CMD_EDIT_SELECT_ALL); 479 480 ptrEditMenu->AddItem(SelectAllMenuItem); 481 SelectAllMenuItem->SetTarget(loggingView, NULL); 482 483 ptrEditMenu->AddSeparatorItem(); 484 485 BMenuItem * PrefMenuItem = new BMenuItem(STR_MNU_EDIT_PREF, 486 new BMessage(MSG_MENU_EDIT_PREF)); 487 ptrEditMenu->AddItem(PrefMenuItem); 488 489 return ptrEditMenu; 490 } 491 492 493 BMenu * 494 PoorManWindow::BuildControlsMenu() const 495 { 496 BMenu * ptrControlMenu = new BMenu(STR_MNU_CTRL); 497 498 BMenuItem * RunServerMenuItem = new BMenuItem(STR_MNU_CTRL_RUN_SERVER, 499 new BMessage(MSG_MENU_CTRL_RUN)); 500 RunServerMenuItem->SetMarked(false); 501 ptrControlMenu->AddItem(RunServerMenuItem); 502 503 BMenuItem * ClearHitCounterMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_HIT_COUNTER, 504 new BMessage(MSG_MENU_CTRL_CLEAR_HIT)); 505 ptrControlMenu->AddItem(ClearHitCounterMenuItem); 506 507 ptrControlMenu->AddSeparatorItem(); 508 509 BMenuItem * ClearConsoleLogMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_CONSOLE, 510 new BMessage(MSG_MENU_CTRL_CLEAR_CONSOLE)); 511 ptrControlMenu->AddItem(ClearConsoleLogMenuItem); 512 513 BMenuItem * ClearLogFileMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_LOG_FILE, 514 new BMessage(MSG_MENU_CTRL_CLEAR_LOG)); 515 ptrControlMenu->AddItem(ClearLogFileMenuItem); 516 517 return ptrControlMenu; 518 } 519 520 521 void 522 PoorManWindow::SetDirLabel(const char * name) 523 { 524 BString dirPath("Directory: "); 525 dirPath.Append(name); 526 527 if (Lock()) { 528 dirView->SetText(dirPath.String()); 529 Unlock(); 530 } 531 } 532 533 534 void 535 PoorManWindow::UpdateStatusLabelAndMenuItem() 536 { 537 if (Lock()) { 538 if (status) 539 statusView->SetText("Status: Running"); 540 else 541 statusView->SetText("Status: Stopped"); 542 ControlsMenu->FindItem(STR_MNU_CTRL_RUN_SERVER)->SetMarked(status); 543 Unlock(); 544 } 545 } 546 547 548 void 549 PoorManWindow::UpdateHitsLabel() 550 { 551 if (Lock()) { 552 sprintf(hitsLabel, "Hits: %lu", GetHits()); 553 hitsView->SetText(hitsLabel); 554 555 Unlock(); 556 } 557 } 558 559 560 status_t 561 PoorManWindow::SaveConsole(BMessage * message, bool selection) 562 { 563 entry_ref ref; 564 const char * name; 565 BPath path; 566 BEntry entry; 567 status_t err = B_OK; 568 FILE *f; 569 570 if ((err = message->FindRef("directory", &ref)) != B_OK) 571 return err; 572 573 if ((err = message->FindString("name", &name)) != B_OK) 574 return err; 575 576 if ((err = entry.SetTo(&ref)) != B_OK) 577 return err; 578 579 entry.GetPath(&path); 580 path.Append(name); 581 582 if (!(f = fopen(path.Path(), "w"))) 583 return B_ERROR; 584 585 if (!selection) { 586 // write the data to the file 587 err = fwrite(loggingView->Text(), 1, loggingView->TextLength(), f); 588 } else { 589 // find the selected text and write it to a file 590 int32 start = 0, end = 0; 591 loggingView->GetSelection(&start, &end); 592 593 BString buffer; 594 char * buffData = buffer.LockBuffer(end - start + 1); 595 // copy the selected text from the TextView to the buffer 596 loggingView->GetText(start, end - start, buffData); 597 buffer.UnlockBuffer(end - start + 1); 598 599 err = fwrite(buffer.String(), 1, end - start + 1, f); 600 } 601 fclose(f); 602 603 return err; 604 } 605 606 607 void 608 PoorManWindow::DefaultSettings() 609 { 610 BAlert* serverAlert = new BAlert("Error Server", STR_ERR_CANT_START, "OK"); 611 BAlert* dirAlert = new BAlert("Error Dir", STR_ERR_WEB_DIR, 612 "Cancel", "Select", "Default", B_WIDTH_AS_USUAL, B_OFFSET_SPACING); 613 dirAlert->SetShortcut(0, B_ESCAPE); 614 int32 buttonIndex = dirAlert->Go(); 615 616 switch (buttonIndex) { 617 case 0: 618 if (Lock()) 619 Quit(); 620 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 621 break; 622 623 case 1: 624 prefWindow = new PoorManPreferencesWindow( 625 setwindow_frame, 626 STR_WIN_NAME_PREF); 627 prefWindow->ShowWebDirFilePanel(); 628 break; 629 630 case 2: 631 if (create_directory(STR_DEFAULT_WEB_DIRECTORY, 0755) != B_OK) { 632 serverAlert->Go(); 633 if (Lock()) 634 Quit(); 635 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 636 break; 637 } 638 BAlert* dirCreatedAlert = 639 new BAlert("Dir Created", STR_DIR_CREATED, "OK"); 640 dirCreatedAlert->Go(); 641 SetWebDir(STR_DEFAULT_WEB_DIRECTORY); 642 be_app->PostMessage(kStartServer); 643 break; 644 } 645 } 646 647 648 status_t 649 PoorManWindow::ReadSettings() 650 { 651 BPath p; 652 BFile f; 653 BMessage m; 654 655 if (find_directory(B_USER_SETTINGS_DIRECTORY, &p) != B_OK) 656 return B_ERROR; 657 p.Append(STR_SETTINGS_FILE_NAME); 658 659 f.SetTo(p.Path(), B_READ_ONLY); 660 if (f.InitCheck() != B_OK) 661 return B_ERROR; 662 663 if (m.Unflatten(&f) != B_OK) 664 return B_ERROR; 665 666 if (MSG_PREF_FILE != m.what) 667 return B_ERROR; 668 669 //site tab 670 if (m.FindString("web_directory", &web_directory) != B_OK) 671 web_directory.SetTo(STR_DEFAULT_WEB_DIRECTORY); 672 if (m.FindString("index_file_name", &index_file_name) != B_OK) 673 index_file_name.SetTo("index.html"); 674 if (m.FindBool("dir_list_flag", &dir_list_flag) != B_OK) 675 dir_list_flag = false; 676 677 //logging tab 678 if (m.FindBool("log_console_flag", &log_console_flag) != B_OK) 679 log_console_flag = true; 680 if (m.FindBool("log_file_flag", &log_file_flag) != B_OK) 681 log_file_flag = false; 682 if (m.FindString("log_path", &log_path) != B_OK) 683 log_path.SetTo(""); 684 685 //advance tab 686 if (m.FindInt16("max_connections", &max_connections) != B_OK) 687 max_connections = (int16)32; 688 689 //windows' position and size 690 if (m.FindRect("frame", &frame) != B_OK) 691 frame.Set(82.0f, 30.0f, 400.0f, 350.0f); 692 if (m.FindRect("setwindow_frame", &setwindow_frame) != B_OK) 693 setwindow_frame.Set(112.0f, 60.0f, 492.0f, 340.0f); 694 if (m.FindBool("is_zoomed", &is_zoomed) != B_OK) 695 is_zoomed = true; 696 if (m.FindFloat("last_width", &last_width) != B_OK) 697 last_width = 318.0f; 698 if (m.FindFloat("last_height", &last_height) != B_OK) 699 last_height = 320.0f; 700 701 is_zoomed?ResizeTo(last_width, last_height):ResizeTo(318, 53); 702 MoveTo(frame.left, frame.top); 703 704 fLogFile = new BFile(log_path.String(), B_CREATE_FILE | B_WRITE_ONLY 705 | B_OPEN_AT_END); 706 if (fLogFile->InitCheck() != B_OK) { 707 log_file_flag = false; 708 //log it to console, "log to file unavailable." 709 return B_OK; 710 } 711 712 SetDirLabel(web_directory.String()); 713 714 return B_OK; 715 } 716 717 718 status_t 719 PoorManWindow::SaveSettings() 720 { 721 BPath p; 722 BFile f; 723 BMessage m(MSG_PREF_FILE); 724 725 //site tab 726 m.AddString("web_directory", web_directory); 727 m.AddString("index_file_name", index_file_name); 728 m.AddBool("dir_list_flag", dir_list_flag); 729 730 //logging tab 731 m.AddBool("log_console_flag", log_console_flag); 732 m.AddBool("log_file_flag", log_file_flag); 733 m.AddString("log_path", log_path); 734 735 //advance tab 736 m.AddInt16("max_connections", max_connections); 737 738 //windows' position and size 739 m.AddRect("frame", frame); 740 m.AddRect("setwindow_frame", setwindow_frame); 741 m.AddBool("is_zoomed", is_zoomed); 742 m.AddFloat("last_width", last_width); 743 m.AddFloat("last_height", last_height); 744 745 if (find_directory(B_USER_SETTINGS_DIRECTORY, &p) != B_OK) 746 return B_ERROR; 747 p.Append(STR_SETTINGS_FILE_NAME); 748 749 f.SetTo(p.Path(), B_WRITE_ONLY | B_ERASE_FILE | B_CREATE_FILE); 750 if (f.InitCheck() != B_OK) 751 return B_ERROR; 752 753 if (m.Flatten(&f) != B_OK) 754 return B_ERROR; 755 756 return B_OK; 757 } 758 759 760 status_t 761 PoorManWindow::StartServer() 762 { 763 if (fServer == NULL) 764 fServer = new PoorManServer( 765 web_directory.String(), 766 max_connections, 767 dir_list_flag, 768 index_file_name.String()); 769 770 poorman_log("Starting up... "); 771 if (fServer->Run() != B_OK) { 772 return B_ERROR; 773 } 774 775 status = true; 776 UpdateStatusLabelAndMenuItem(); 777 poorman_log("done.\n", false, INADDR_NONE, GREEN); 778 779 return B_OK; 780 } 781 782 783 status_t 784 PoorManWindow::StopServer() 785 { 786 if (fServer == NULL) 787 return B_ERROR; 788 789 poorman_log("Shutting down.\n"); 790 fServer->Stop(); 791 status = false; 792 UpdateStatusLabelAndMenuItem(); 793 return B_OK; 794 } 795 796 797 void 798 PoorManWindow::SetLogPath(const char* str) 799 { 800 if (!strcmp(log_path, str)) 801 return; 802 803 BFile* temp = new BFile(str, B_CREATE_FILE | B_WRITE_ONLY | B_OPEN_AT_END); 804 805 if (temp->InitCheck() != B_OK) { 806 delete temp; 807 return; 808 } 809 810 if (pthread_rwlock_wrlock(&fLogFileLock) == 0) { 811 delete fLogFile; 812 fLogFile = temp; 813 pthread_rwlock_unlock(&fLogFileLock); 814 } else { 815 delete temp; 816 return; 817 } 818 819 log_path.SetTo(str); 820 } 821