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 saveConsoleFilePanel = new BFilePanel( 187 B_SAVE_PANEL, 188 new BMessenger(this), 189 NULL, 190 B_FILE_NODE, 191 false, 192 new BMessage(MSG_FILE_PANEL_SAVE_CONSOLE)); 193 194 change_title = saveConsoleFilePanel->Window(); 195 change_title->SetTitle(STR_FILEPANEL_SAVE_CONSOLE); 196 197 saveConsoleSelectionFilePanel = new BFilePanel( 198 B_SAVE_PANEL, 199 new BMessenger(this), 200 NULL, 201 B_FILE_NODE, 202 false, 203 new BMessage(MSG_FILE_PANEL_SAVE_CONSOLE_SELECTION)); 204 205 change_title = saveConsoleSelectionFilePanel->Window(); 206 change_title->SetTitle(STR_FILEPANEL_SAVE_CONSOLE_SELECTION); 207 208 209 AddChild(FileMenuBar); 210 211 pthread_rwlock_init(&fLogFileLock, NULL); 212 } 213 214 215 PoorManWindow::~PoorManWindow() 216 { 217 delete fServer; 218 delete fLogViewFont; 219 delete fLogFile; 220 pthread_rwlock_destroy(&fLogFileLock); 221 } 222 223 224 void 225 PoorManWindow::MessageReceived(BMessage* message) 226 { 227 switch (message->what) { 228 case MSG_MENU_FILE_SAVE_AS: 229 saveConsoleFilePanel->Show(); 230 break; 231 case MSG_FILE_PANEL_SAVE_CONSOLE: 232 printf("FilePanel: Save console\n"); 233 SaveConsole(message, false); 234 break; 235 case MSG_MENU_FILE_SAVE_SELECTION: 236 saveConsoleSelectionFilePanel->Show(); 237 break; 238 case MSG_FILE_PANEL_SAVE_CONSOLE_SELECTION: 239 printf("FilePanel: Save console selection\n"); 240 SaveConsole(message, true); 241 break; 242 case MSG_FILE_PANEL_SELECT_WEB_DIR: 243 prefWindow->MessageReceived(message); 244 break; 245 case MSG_MENU_EDIT_PREF: 246 prefWindow = new PoorManPreferencesWindow( 247 setwindow_frame, 248 STR_WIN_NAME_PREF); 249 prefWindow->Show(); 250 break; 251 case MSG_MENU_CTRL_RUN: 252 if (status) 253 StopServer(); 254 else 255 StartServer(); 256 break; 257 case MSG_MENU_CTRL_CLEAR_HIT: 258 SetHits(0); 259 //UpdateHitsLabel(); 260 break; 261 case MSG_MENU_CTRL_CLEAR_CONSOLE: 262 loggingView->SelectAll(); 263 loggingView->Delete(); 264 break; 265 case MSG_MENU_CTRL_CLEAR_LOG: 266 FILE * f; 267 f = fopen(log_path.String(), "w"); 268 fclose(f); 269 break; 270 case MSG_LOG: { 271 if (!log_console_flag && !log_file_flag) 272 break; 273 274 time_t time; 275 in_addr_t address; 276 rgb_color color; 277 const void* pointer; 278 ssize_t size; 279 const char* msg; 280 BString line; 281 282 if (message->FindString("cstring", &msg) != B_OK) 283 break; 284 if (message->FindData("time_t", B_TIME_TYPE, &pointer, &size) != B_OK) 285 time = -1; 286 else 287 time = *static_cast<const time_t*>(pointer); 288 289 if (message->FindData("in_addr_t", B_ANY_TYPE, &pointer, &size) != B_OK) 290 address = INADDR_NONE; 291 else 292 address = *static_cast<const in_addr_t*>(pointer); 293 294 if (message->FindData("rgb_color", B_RGB_COLOR_TYPE, &pointer, &size) != B_OK) 295 color = BLACK; 296 else 297 color = *static_cast<const rgb_color*>(pointer); 298 299 if (time != -1) { 300 char timeString[26]; 301 if (ctime_r(&time, timeString) != NULL) { 302 timeString[24] = '\0'; 303 line << '[' << timeString << "]: "; 304 } 305 } 306 307 if (address != INADDR_NONE) { 308 char addr[INET_ADDRSTRLEN]; 309 struct in_addr sin_addr; 310 sin_addr.s_addr = address; 311 if (inet_ntop(AF_INET, &sin_addr, addr, sizeof(addr)) != NULL) { 312 addr[strlen(addr)] = '\0'; 313 line << '(' << addr << ") "; 314 } 315 } 316 317 line << msg; 318 319 text_run run; 320 text_run_array runs; 321 322 run.offset = 0; 323 run.font = *fLogViewFont; 324 run.color = color; 325 326 runs.count = 1; 327 runs.runs[0] = run; 328 329 if (Lock()) { 330 if (log_console_flag) { 331 loggingView->Insert(loggingView->TextLength(), 332 line.String(), line.Length(), &runs); 333 loggingView->ScrollToOffset(loggingView->TextLength()); 334 } 335 336 if (log_file_flag) { 337 if (pthread_rwlock_rdlock(&fLogFileLock) == 0) { 338 fLogFile->Write(line.String(), line.Length()); 339 pthread_rwlock_unlock(&fLogFileLock); 340 } 341 } 342 343 Unlock(); 344 } 345 346 break; 347 } 348 default: 349 BWindow::MessageReceived(message); 350 break; 351 } 352 } 353 354 355 void 356 PoorManWindow::FrameMoved(BPoint origin) 357 { 358 frame.left = origin.x; 359 frame.top = origin.y; 360 } 361 362 363 void 364 PoorManWindow::FrameResized(float width, float height) 365 { 366 if (is_zoomed) { 367 last_width = width; 368 last_height = height; 369 } 370 } 371 372 373 bool 374 PoorManWindow::QuitRequested() 375 { 376 if (status) { 377 time_t now = time(NULL); 378 char line[] = "[Thu Jan 1 00:00:00 1970]: Shutting down.\n"; 379 380 ctime_r(&now, line + 1); 381 line[25] = ']'; 382 line[26] = ' '; 383 384 if (log_console_flag) { 385 loggingView->Insert(loggingView->TextLength(), 386 line, strlen(line)); 387 loggingView->ScrollToOffset(loggingView->TextLength()); 388 } 389 390 if (log_file_flag) { 391 if (pthread_rwlock_rdlock(&fLogFileLock) == 0) { 392 fLogFile->Write(line, strlen(line)); 393 pthread_rwlock_unlock(&fLogFileLock); 394 } 395 } 396 397 fServer->Stop(); 398 status = false; 399 UpdateStatusLabelAndMenuItem(); 400 } 401 402 SaveSettings(); 403 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 404 return true; 405 } 406 407 408 void 409 PoorManWindow::Zoom(BPoint origin, float width, float height) 410 { 411 if (is_zoomed) { 412 // Change to the Minimal size 413 is_zoomed = false; 414 ResizeTo(318, 53); 415 } else { 416 // Change to the Zoomed size 417 is_zoomed = true; 418 ResizeTo(last_width, last_height); 419 } 420 } 421 422 423 void 424 PoorManWindow::SetHits(uint32 num) 425 { 426 hits = num; 427 UpdateHitsLabel(); 428 } 429 430 431 // Private: Methods ------------------------------------------ 432 433 434 BMenu * 435 PoorManWindow::BuildFileMenu() const 436 { 437 BMenu * ptrFileMenu = new BMenu(STR_MNU_FILE); 438 439 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_SAVE_AS, 440 new BMessage(MSG_MENU_FILE_SAVE_AS), CMD_FILE_SAVE_AS)); 441 442 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_SAVE_SELECTION, 443 new BMessage(MSG_MENU_FILE_SAVE_SELECTION))); 444 445 ptrFileMenu->AddSeparatorItem(); 446 447 // about box 448 BMenuItem * AboutItem = new BMenuItem(STR_MNU_FILE_ABOUT, 449 new BMessage(B_ABOUT_REQUESTED)); 450 AboutItem->SetTarget(NULL, be_app); 451 ptrFileMenu->AddItem(AboutItem); 452 453 ptrFileMenu->AddSeparatorItem(); 454 455 456 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_QUIT, 457 new BMessage(B_QUIT_REQUESTED), CMD_FILE_QUIT)); 458 459 return ptrFileMenu; 460 } 461 462 463 BMenu * 464 PoorManWindow::BuildEditMenu() const 465 { 466 BMenu * ptrEditMenu = new BMenu(STR_MNU_EDIT); 467 468 BMenuItem * CopyMenuItem = new BMenuItem(STR_MNU_EDIT_COPY, 469 new BMessage(B_COPY), CMD_EDIT_COPY); 470 471 ptrEditMenu->AddItem(CopyMenuItem); 472 CopyMenuItem->SetTarget(loggingView, NULL); 473 474 ptrEditMenu->AddSeparatorItem(); 475 476 BMenuItem * SelectAllMenuItem = new BMenuItem(STR_MNU_EDIT_SELECT_ALL, 477 new BMessage(B_SELECT_ALL), CMD_EDIT_SELECT_ALL); 478 479 ptrEditMenu->AddItem(SelectAllMenuItem); 480 SelectAllMenuItem->SetTarget(loggingView, NULL); 481 482 ptrEditMenu->AddSeparatorItem(); 483 484 BMenuItem * PrefMenuItem = new BMenuItem(STR_MNU_EDIT_PREF, 485 new BMessage(MSG_MENU_EDIT_PREF)); 486 ptrEditMenu->AddItem(PrefMenuItem); 487 488 return ptrEditMenu; 489 } 490 491 492 BMenu * 493 PoorManWindow::BuildControlsMenu() const 494 { 495 BMenu * ptrControlMenu = new BMenu(STR_MNU_CTRL); 496 497 BMenuItem * RunServerMenuItem = new BMenuItem(STR_MNU_CTRL_RUN_SERVER, 498 new BMessage(MSG_MENU_CTRL_RUN)); 499 RunServerMenuItem->SetMarked(false); 500 ptrControlMenu->AddItem(RunServerMenuItem); 501 502 BMenuItem * ClearHitCounterMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_HIT_COUNTER, 503 new BMessage(MSG_MENU_CTRL_CLEAR_HIT)); 504 ptrControlMenu->AddItem(ClearHitCounterMenuItem); 505 506 ptrControlMenu->AddSeparatorItem(); 507 508 BMenuItem * ClearConsoleLogMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_CONSOLE, 509 new BMessage(MSG_MENU_CTRL_CLEAR_CONSOLE)); 510 ptrControlMenu->AddItem(ClearConsoleLogMenuItem); 511 512 BMenuItem * ClearLogFileMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_LOG_FILE, 513 new BMessage(MSG_MENU_CTRL_CLEAR_LOG)); 514 ptrControlMenu->AddItem(ClearLogFileMenuItem); 515 516 return ptrControlMenu; 517 } 518 519 520 void 521 PoorManWindow::SetDirLabel(const char * name) 522 { 523 BString dirPath("Directory: "); 524 dirPath.Append(name); 525 526 if (Lock()) { 527 dirView->SetText(dirPath.String()); 528 Unlock(); 529 } 530 } 531 532 533 void 534 PoorManWindow::UpdateStatusLabelAndMenuItem() 535 { 536 if (Lock()) { 537 if (status) 538 statusView->SetText("Status: Running"); 539 else 540 statusView->SetText("Status: Stopped"); 541 ControlsMenu->FindItem(STR_MNU_CTRL_RUN_SERVER)->SetMarked(status); 542 Unlock(); 543 } 544 } 545 546 547 void 548 PoorManWindow::UpdateHitsLabel() 549 { 550 if (Lock()) { 551 sprintf(hitsLabel, "Hits: %lu", GetHits()); 552 hitsView->SetText(hitsLabel); 553 554 Unlock(); 555 } 556 } 557 558 559 status_t 560 PoorManWindow::SaveConsole(BMessage * message, bool selection) 561 { 562 entry_ref ref; 563 const char * name; 564 BPath path; 565 BEntry entry; 566 status_t err = B_OK; 567 FILE *f; 568 569 if ((err = message->FindRef("directory", &ref)) != B_OK) 570 return err; 571 572 if ((err = message->FindString("name", &name)) != B_OK) 573 return err; 574 575 if ((err = entry.SetTo(&ref)) != B_OK) 576 return err; 577 578 entry.GetPath(&path); 579 path.Append(name); 580 581 if (!(f = fopen(path.Path(), "w"))) 582 return B_ERROR; 583 584 if (!selection) { 585 // write the data to the file 586 err = fwrite(loggingView->Text(), 1, loggingView->TextLength(), f); 587 } else { 588 // find the selected text and write it to a file 589 int32 start = 0, end = 0; 590 loggingView->GetSelection(&start, &end); 591 592 BString buffer; 593 char * buffData = buffer.LockBuffer(end - start + 1); 594 // copy the selected text from the TextView to the buffer 595 loggingView->GetText(start, end - start, buffData); 596 buffer.UnlockBuffer(end - start + 1); 597 598 err = fwrite(buffer.String(), 1, end - start + 1, f); 599 } 600 fclose(f); 601 602 return err; 603 } 604 605 606 void 607 PoorManWindow::DefaultSettings() 608 { 609 BAlert* serverAlert = new BAlert("Error Server", STR_ERR_CANT_START, "OK"); 610 BAlert* dirAlert = new BAlert("Error Dir", STR_ERR_WEB_DIR, 611 "Cancel", "Select", "Default", B_WIDTH_AS_USUAL, B_OFFSET_SPACING); 612 dirAlert->SetShortcut(0, B_ESCAPE); 613 int32 buttonIndex = dirAlert->Go(); 614 615 switch (buttonIndex) { 616 case 0: 617 if (Lock()) 618 Quit(); 619 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 620 break; 621 622 case 1: 623 prefWindow = new PoorManPreferencesWindow( 624 setwindow_frame, 625 STR_WIN_NAME_PREF); 626 prefWindow->ShowWebDirFilePanel(); 627 break; 628 629 case 2: 630 if (create_directory(STR_DEFAULT_WEB_DIRECTORY, 0755) != B_OK) { 631 serverAlert->Go(); 632 if (Lock()) 633 Quit(); 634 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 635 break; 636 } 637 BAlert* dirCreatedAlert = 638 new BAlert("Dir Created", STR_DIR_CREATED, "OK"); 639 dirCreatedAlert->Go(); 640 SetWebDir(STR_DEFAULT_WEB_DIRECTORY); 641 be_app->PostMessage(kStartServer); 642 break; 643 } 644 } 645 646 647 status_t 648 PoorManWindow::ReadSettings() 649 { 650 BPath p; 651 BFile f; 652 BMessage m; 653 654 if (find_directory(B_USER_SETTINGS_DIRECTORY, &p) != B_OK) 655 return B_ERROR; 656 p.Append(STR_SETTINGS_FILE_NAME); 657 658 f.SetTo(p.Path(), B_READ_ONLY); 659 if (f.InitCheck() != B_OK) 660 return B_ERROR; 661 662 if (m.Unflatten(&f) != B_OK) 663 return B_ERROR; 664 665 if (MSG_PREF_FILE != m.what) 666 return B_ERROR; 667 668 //site tab 669 if (m.FindString("web_directory", &web_directory) != B_OK) 670 web_directory.SetTo(STR_DEFAULT_WEB_DIRECTORY); 671 if (m.FindString("index_file_name", &index_file_name) != B_OK) 672 index_file_name.SetTo("index.html"); 673 if (m.FindBool("dir_list_flag", &dir_list_flag) != B_OK) 674 dir_list_flag = false; 675 676 //logging tab 677 if (m.FindBool("log_console_flag", &log_console_flag) != B_OK) 678 log_console_flag = true; 679 if (m.FindBool("log_file_flag", &log_file_flag) != B_OK) 680 log_file_flag = false; 681 if (m.FindString("log_path", &log_path) != B_OK) 682 log_path.SetTo(""); 683 684 //advance tab 685 if (m.FindInt16("max_connections", &max_connections) != B_OK) 686 max_connections = (int16)32; 687 688 //windows' position and size 689 if (m.FindRect("frame", &frame) != B_OK) 690 frame.Set(82.0f, 30.0f, 400.0f, 350.0f); 691 if (m.FindRect("setwindow_frame", &setwindow_frame) != B_OK) 692 setwindow_frame.Set(112.0f, 60.0f, 492.0f, 340.0f); 693 if (m.FindBool("is_zoomed", &is_zoomed) != B_OK) 694 is_zoomed = true; 695 if (m.FindFloat("last_width", &last_width) != B_OK) 696 last_width = 318.0f; 697 if (m.FindFloat("last_height", &last_height) != B_OK) 698 last_height = 320.0f; 699 700 is_zoomed?ResizeTo(last_width, last_height):ResizeTo(318, 53); 701 MoveTo(frame.left, frame.top); 702 703 fLogFile = new BFile(log_path.String(), B_CREATE_FILE | B_WRITE_ONLY 704 | B_OPEN_AT_END); 705 if (fLogFile->InitCheck() != B_OK) { 706 log_file_flag = false; 707 //log it to console, "log to file unavailable." 708 return B_OK; 709 } 710 711 SetDirLabel(web_directory.String()); 712 713 return B_OK; 714 } 715 716 717 status_t 718 PoorManWindow::SaveSettings() 719 { 720 BPath p; 721 BFile f; 722 BMessage m(MSG_PREF_FILE); 723 724 //site tab 725 m.AddString("web_directory", web_directory); 726 m.AddString("index_file_name", index_file_name); 727 m.AddBool("dir_list_flag", dir_list_flag); 728 729 //logging tab 730 m.AddBool("log_console_flag", log_console_flag); 731 m.AddBool("log_file_flag", log_file_flag); 732 m.AddString("log_path", log_path); 733 734 //advance tab 735 m.AddInt16("max_connections", max_connections); 736 737 //windows' position and size 738 m.AddRect("frame", frame); 739 m.AddRect("setwindow_frame", setwindow_frame); 740 m.AddBool("is_zoomed", is_zoomed); 741 m.AddFloat("last_width", last_width); 742 m.AddFloat("last_height", last_height); 743 744 if (find_directory(B_USER_SETTINGS_DIRECTORY, &p) != B_OK) 745 return B_ERROR; 746 p.Append(STR_SETTINGS_FILE_NAME); 747 748 f.SetTo(p.Path(), B_WRITE_ONLY | B_ERASE_FILE | B_CREATE_FILE); 749 if (f.InitCheck() != B_OK) 750 return B_ERROR; 751 752 if (m.Flatten(&f) != B_OK) 753 return B_ERROR; 754 755 return B_OK; 756 } 757 758 759 status_t 760 PoorManWindow::StartServer() 761 { 762 if (fServer == NULL) 763 fServer = new PoorManServer( 764 web_directory.String(), 765 max_connections, 766 dir_list_flag, 767 index_file_name.String()); 768 769 poorman_log("Starting up... "); 770 if (fServer->Run() != B_OK) { 771 return B_ERROR; 772 } 773 774 status = true; 775 UpdateStatusLabelAndMenuItem(); 776 poorman_log("done.\n", false, INADDR_NONE, GREEN); 777 778 return B_OK; 779 } 780 781 782 status_t 783 PoorManWindow::StopServer() 784 { 785 if (fServer == NULL) 786 return B_ERROR; 787 788 poorman_log("Shutting down.\n"); 789 fServer->Stop(); 790 status = false; 791 UpdateStatusLabelAndMenuItem(); 792 return B_OK; 793 } 794 795 796 void 797 PoorManWindow::SetLogPath(const char* str) 798 { 799 if (!strcmp(log_path, str)) 800 return; 801 802 BFile* temp = new BFile(str, B_CREATE_FILE | B_WRITE_ONLY | B_OPEN_AT_END); 803 804 if (temp->InitCheck() != B_OK) { 805 delete temp; 806 return; 807 } 808 809 if (pthread_rwlock_wrlock(&fLogFileLock) == 0) { 810 delete fLogFile; 811 fLogFile = temp; 812 pthread_rwlock_unlock(&fLogFileLock); 813 } else { 814 delete temp; 815 return; 816 } 817 818 log_path.SetTo(str); 819 } 820