1 #include "NetworkWindow.h" 2 #include "NetListView.h" 3 #include <ScrollView.h> 4 #include <StringView.h> 5 #include <Screen.h> 6 #include <malloc.h> 7 #include <stdlib.h> 8 #include <TextControl.h> 9 #include <Alert.h> 10 #include <Application.h> 11 #include <stdio.h> 12 #include <Directory.h> 13 #include <Entry.h> 14 #include <File.h> 15 #include <Region.h> 16 #include <Path.h> 17 18 #include "InterfaceWin.h" 19 #include "BackupWindow.h" 20 #include "LoginInfo.h" 21 22 //#define NETWORK_WINDOW_RIGHT 435 23 //#define NETWORK_WINDOW_BOTTOM 309 24 25 class RestartWindow : public BWindow 26 { 27 public: 28 RestartWindow(); 29 30 BView *fView; 31 BStringView *fRestarting; 32 BStringView *fWhatsHappening; 33 }; 34 35 36 RestartWindow::RestartWindow() 37 : BWindow(BRect(400,300,650,350),"Restart Networking",B_MODAL_WINDOW,B_NOT_ANCHORED_ON_ACTIVATE | B_NOT_RESIZABLE,B_CURRENT_WORKSPACE) 38 { 39 fView = new BView(Bounds(),"Restart_View",B_FOLLOW_ALL_SIDES,B_WILL_DRAW); 40 41 fView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 42 43 fRestarting = new BStringView(BRect(60,5,200,25),"Restarting_Text_1", 44 "Restarting Networking"); 45 fWhatsHappening = new BStringView(BRect(60,30,200,50),"Restarting_Text_2", 46 "Please Wait..."); 47 48 BFont font(be_bold_font); 49 50 fRestarting->SetFont(&font); 51 fWhatsHappening->SetFont(&font); 52 53 fView->AddChild(fRestarting); 54 fView->AddChild(fWhatsHappening); 55 56 AddChild(fView); 57 } 58 59 NetworkWindow::NetworkWindow() 60 : BWindow(BRect(0, 0, 435, 309),"Network", 61 B_TITLED_WINDOW,B_NOT_ANCHORED_ON_ACTIVATE | B_NOT_ZOOMABLE | B_NOT_RESIZABLE, 62 B_CURRENT_WORKSPACE) 63 { 64 BScreen screen; 65 66 BRect screenframe = screen.Frame(), bounds = Bounds(), workrect(0,0,1,1); 67 float width,height; 68 float screenx, screeny; 69 70 screenx = ((screenframe.right + 1) / 2) - (bounds.right / 2) - 1; 71 screeny = ((screenframe.bottom + 1) / 2) - (bounds.bottom / 2) - 1; 72 MoveTo(screenx, screeny); 73 74 fView = new BView(bounds,"View",B_FOLLOW_ALL_SIDES,B_WILL_DRAW); 75 fView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 76 AddChild(fView); 77 78 fRestart = new BButton(workrect,"Restart_Networking", 79 "Restart Networking",new BMessage(kRestart_Networking_M), 80 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 81 fRestart->GetPreferredSize(&width,&height); 82 fRestart->ResizeTo(width,height); 83 fRestart->MoveTo(10,bounds.bottom - 10 - height); 84 85 // We fake the divider line by using a BBox. We have to call ConstrainClippingRegion 86 // because otherwise we also see the corners drawn, which doesn't look nice 87 BBox *vr = new BBox(BRect(width + 18, bounds.bottom - 11 - height, width + 19, 88 bounds.bottom - 9), 89 "vertical_rule", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 90 fView->AddChild(vr); 91 92 BRegion clipreg(vr->Bounds().InsetByCopy(0,2)); 93 vr->ConstrainClippingRegion(&clipreg); 94 95 fRevert = new BButton(BRect(width + 25,bounds.bottom - 10 - height,width + 26, 96 bounds.bottom - 10), 97 "Revert","Revert", new BMessage(kRevert_M), 98 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 99 fRevert->ResizeToPreferred(); 100 fRevert->SetEnabled(false); 101 102 fSave = new BButton(workrect,"Save","Save",new BMessage(kSave_M), 103 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 104 fSave->GetPreferredSize(&width,&height); 105 fSave->ResizeTo(width,height); 106 fSave->MoveTo(bounds.right - 10 - width, bounds.bottom - 10 - height); 107 fSave->MakeDefault(true); 108 fSave->SetEnabled(false); 109 110 BBox *hr = new BBox(BRect(0,bounds.bottom - height - 20,bounds.right, 111 bounds.bottom - height - 19), 112 "horizontal_rule",B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM); 113 fView->AddChild(hr); 114 115 workrect = Bounds(); 116 workrect.bottom = hr->Frame().top; 117 workrect.top = 10; 118 119 fTabView = new BTabView(workrect,"tab_view",B_WIDTH_FROM_WIDEST, B_FOLLOW_ALL); 120 fTabView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 121 fView->AddChild(fTabView); 122 bounds.bottom -= fTabView->TabHeight(); 123 124 fView->AddChild(fRestart); 125 fView->AddChild(fRevert); 126 fView->AddChild(fSave); 127 128 bounds = fTabView->Bounds(); 129 bounds.bottom -= fTabView->TabHeight(); 130 131 fIdentityView = new BView(bounds,"Identity",B_FOLLOW_ALL_SIDES,B_WILL_DRAW); 132 fIdentityView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 133 134 fIdentity = new BTab(); 135 fTabView->AddTab(fIdentityView,fIdentity); 136 137 // We can just pick a view to call StringWidth because we're not using anything 138 // except the unaltered be_plain_font. Note that for each BTextControl pair we 139 // just use the longer word of the two in order to save us some speed and code size 140 float labelwidth = fTabView->StringWidth("Domain name: "); 141 142 workrect.Set(10,20,11,21); 143 fDomain = new BTextControl(workrect,"Domain_Name","Domain name:"," ", 144 new BMessage(kSOMETHING_HAS_CHANGED_M)); 145 146 // BTextControl::ResizeToPreferred() is a little strange for our purposes, so we 147 // get the preferred size and ignore the width that we get. 148 fDomain->GetPreferredSize(&width, &height); 149 fDomain->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_LEFT); 150 fDomain->SetDivider(labelwidth); 151 152 workrect.left = 10; 153 workrect.right = 11; 154 workrect.top = height + 30; 155 workrect.bottom = workrect.top + height; 156 157 fHost = new BTextControl(workrect,"Host_Name","Host name:",NULL, 158 new BMessage(kSOMETHING_HAS_CHANGED_M)); 159 fHost->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_LEFT); 160 fHost->SetDivider(labelwidth); 161 162 labelwidth = fTabView->StringWidth("Secondary DNS: "); 163 164 workrect.OffsetTo((bounds.right / 2),20); 165 workrect.right = bounds.right - 30; 166 fPrimaryDNS = new BTextControl(workrect,"Primary_DNS","Primary DNS:", 167 NULL,new BMessage(kSOMETHING_HAS_CHANGED_M), 168 B_FOLLOW_TOP | B_FOLLOW_RIGHT); 169 fPrimaryDNS->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_LEFT); 170 fPrimaryDNS->SetDivider(labelwidth); 171 172 workrect.OffsetBy(0,height + 10); 173 fSecondaryDNS = new BTextControl(workrect,"Secondary_DNS","Secondary DNS:", 174 NULL,new BMessage(kSOMETHING_HAS_CHANGED_M), 175 B_FOLLOW_TOP | B_FOLLOW_RIGHT); 176 fSecondaryDNS->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_LEFT); 177 fSecondaryDNS->SetDivider(labelwidth); 178 179 fNames = new BBox(BRect(10,10,bounds.right - 10, (height * 2) + 50), 180 "Names",B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,B_WILL_DRAW | 181 B_FRAME_EVENTS); 182 fIdentityView->AddChild(fNames); 183 fNames->SetLabel("Names"); 184 185 fNames->AddChild(fDomain); 186 fNames->AddChild(fHost); 187 fNames->AddChild(fPrimaryDNS); 188 fNames->AddChild(fSecondaryDNS); 189 190 // BTextControl resizing operations don't do anything under R5 unless they 191 // have an owner. To make things worse, BTabView does some of its BView hierarchy 192 // stuff in AttachedToWindow such that if you add a tab before it's attached to 193 // a window, it won't be visible. :( As such, we make an extra call to 194 // AttachedToWindow to be assured that everything works the way it is intended. 195 fTabView->AttachedToWindow(); 196 fDomain->ResizeTo( (bounds.right / 2) - 25, height); 197 fHost->ResizeTo( (bounds.right / 2) - 25, height); 198 199 workrect.left = 10; 200 workrect.right = bounds.right - 10; 201 workrect.top = fNames->Frame().bottom + 10; 202 workrect.bottom = fIdentityView->Bounds().bottom - 15; 203 fInterfaces = new BBox(workrect,"Network_Interfaces",B_FOLLOW_ALL, 204 B_WILL_DRAW | B_FRAME_EVENTS); 205 fInterfaces->SetLabel("Network Interfaces"); 206 fIdentityView->AddChild(fInterfaces); 207 208 workrect = fInterfaces->Bounds().InsetByCopy(5,5); 209 fSettings = new BButton(BRect(0,0,1,1),"Settings","Settings...", 210 new BMessage(kSettings_M), 211 B_FOLLOW_TOP | B_FOLLOW_RIGHT); 212 fSettings->ResizeToPreferred(); 213 fSettings->MoveTo(workrect.right - 5 - fSettings->Bounds().Width(), 15); 214 fInterfaces->AddChild(fSettings); 215 216 workrect = fSettings->Frame(); 217 workrect.OffsetBy(0,workrect.Height()+5); 218 219 fClear = new BButton(workrect,"Clear","Clear",new BMessage(kClear_M), 220 B_FOLLOW_TOP | B_FOLLOW_RIGHT); 221 fInterfaces->AddChild(fClear); 222 223 workrect.OffsetBy(0,workrect.Height()+15); 224 fCustom = new BButton(workrect,"Custom","Custom...",new BMessage(kCustom_M), 225 B_FOLLOW_TOP | B_FOLLOW_RIGHT); 226 fInterfaces->AddChild(fCustom); 227 228 if(workrect.bottom > fInterfaces->Bounds().bottom) 229 ResizeBy(0,workrect.bottom - fInterfaces->Bounds().bottom + 10); 230 231 workrect.left = 10; 232 workrect.top = 20; 233 workrect.right = fCustom->Frame().left - 15 - B_V_SCROLL_BAR_WIDTH; 234 workrect.bottom = fCustom->Frame().bottom - 5; 235 236 fInterfacesList = new NetListView(workrect,"Interfaces_List"); 237 BScrollView *interfaces_scroller = new BScrollView("Interfaces_Scroller", 238 fInterfacesList, B_FOLLOW_ALL, 239 0, 0, 1, B_FANCY_BORDER); 240 fInterfaces->AddChild(interfaces_scroller); 241 242 fServicesView = new BView(bounds,"Services",B_FOLLOW_ALL_SIDES,B_WILL_DRAW); 243 fServicesView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 244 fServices = new BTab(); 245 fTabView->AddTab(fServicesView,fServices); 246 247 workrect.Set(10,10,11,11); 248 fFTPServer = new BCheckBox(workrect,"FTP_Server","FTP Server", 249 new BMessage(kSOMETHING_HAS_CHANGED_M)); 250 fFTPServer->GetPreferredSize(&width,&height); 251 fFTPServer->ResizeTo(width,height); 252 fServicesView->AddChild(fFTPServer); 253 254 fTelnetServer = new BCheckBox(workrect,"Telnet_Server","Telnet Server", 255 new BMessage(kSOMETHING_HAS_CHANGED_M)); 256 fTelnetServer->ResizeToPreferred(); 257 fTelnetServer->MoveTo(10,height + 15); 258 fServicesView->AddChild(fTelnetServer); 259 260 fLoginInfo = new BButton(workrect,"Login_Info","Login Info...", 261 new BMessage(kLogin_Info_M)); 262 fLoginInfo->ResizeToPreferred(); 263 fLoginInfo->MoveTo(10,(height * 2) + 25); 264 fServicesView->AddChild(fLoginInfo); 265 266 workrect = fLoginInfo->Frame(); 267 workrect.left -= 5; 268 workrect.top = workrect.bottom + 10; 269 workrect.bottom = workrect.top + 1; 270 workrect.right += 70; 271 BBox *hr2 = new BBox(workrect,"horizontal_rule2",B_FOLLOW_LEFT | B_FOLLOW_TOP); 272 fServicesView->AddChild(hr2); 273 274 275 fAppleTalk = new BCheckBox(workrect,"Apple_Talk","Apple Talk", 276 new BMessage(kSOMETHING_HAS_CHANGED_M)); 277 fAppleTalk->ResizeToPreferred(); 278 fAppleTalk->MoveTo(10, workrect.bottom + 10); 279 fServicesView->AddChild(fAppleTalk); 280 281 fIPForwarding = new BCheckBox(workrect,"IP_Forwarding","IP Forwarding", 282 new BMessage(kSOMETHING_HAS_CHANGED_M)); 283 fIPForwarding->ResizeToPreferred(); 284 fIPForwarding->MoveTo(10, fAppleTalk->Frame().bottom + 5); 285 fServicesView->AddChild(fIPForwarding); 286 287 workrect = bounds.InsetByCopy(10,10); 288 workrect.bottom += 10; 289 workrect.left = hr2->Frame().right + 10; 290 fConfigurations = new BBox(workrect,"Configurations",B_FOLLOW_ALL, 291 B_WILL_DRAW | B_FRAME_EVENTS); 292 fConfigurations->SetLabel("Configurations"); 293 fServicesView->AddChild(fConfigurations); 294 295 workrect = fConfigurations->Bounds(); 296 fBackup = new BButton(BRect(0,0,1,1),"Backup","Backup", new BMessage(kBackup_M)); 297 fBackup->GetPreferredSize(&width,&height); 298 fBackup->ResizeTo(width,height); 299 fBackup->MoveTo(workrect.right - width - 10,15); 300 fConfigurations->AddChild(fBackup); 301 302 fRestore = new BButton(BRect(0,0,width,height),"Restore","Restore", 303 new BMessage(kRestore_M)); 304 fConfigurations->AddChild(fRestore); 305 fRestore->MoveTo(workrect.right - width - 10, 20 + height); 306 fRestore->SetEnabled(false); 307 308 fRemove = new BButton(BRect(0,0,width,height),"Delete","Delete", 309 new BMessage(kDelete_M)); 310 fRemove->MoveTo(workrect.right - width - 10, 25 + (height * 2)); 311 fRemove->SetEnabled(false); 312 fConfigurations->AddChild(fRemove); 313 314 workrect = fConfigurations->Bounds().InsetByCopy(15,15); 315 workrect.top += 5; 316 workrect.right = fBackup->Frame().left - 10 - B_V_SCROLL_BAR_WIDTH; 317 fConfigurationsList = new NetListView(workrect,"Configurations_List"); 318 BScrollView *configurations_scroller = new BScrollView("Configurations_Scroller", 319 fConfigurationsList, 320 B_FOLLOW_ALL, 0, 0, 1, 321 B_FANCY_BORDER); 322 fConfigurations->AddChild(configurations_scroller); 323 324 LoadConfigEntries(); 325 LoadSettings(); 326 327 fTabView->AttachedToWindow(); 328 } 329 330 void NetworkWindow::MessageReceived(BMessage *message) 331 { 332 switch (message->what) { 333 case kRestart_Networking_M: { 334 RestartWindow *restartWindow = new RestartWindow(); 335 restartWindow->Show(); 336 337 BMessenger messenger("application/x-vnd.Be-NETS"); 338 if (messenger.IsValid() == true) 339 messenger.SendMessage(B_QUIT_REQUESTED); 340 341 const char **arg_v; 342 int32 argc; 343 thread_id thread; 344 status_t return_value; 345 346 argc = 1; 347 arg_v = (const char **)malloc(sizeof(char *) * (argc + 1)); 348 349 arg_v[0] = strdup("/boot/beos/system/servers/net_server"); 350 arg_v[1] = NULL; 351 352 thread = load_image(argc,arg_v,(const char **)environ); 353 354 while (--argc >= 0) 355 free((void *)arg_v[argc]); 356 free (arg_v); 357 358 return_value = resume_thread(thread); 359 360 restartWindow->Quit(); 361 break; 362 } 363 case kRevert_M: { 364 LoadSettings(); 365 fRevert->SetEnabled(false); 366 fSave->SetEnabled(false); 367 break; 368 } 369 case kSave_M: { 370 SaveBackup(NULL,fData); 371 fRevert->SetEnabled(false); 372 fSave->SetEnabled(false); 373 break; 374 } 375 case kSettings_M: { 376 BRect r(Frame()); 377 r.right = r.left + 325; 378 r.bottom = r.top + 225; 379 380 NetListItem *selection = dynamic_cast <NetListItem *> (fInterfacesList->ItemAt(fInterfacesList->CurrentSelection())); 381 if(!selection) 382 break; 383 384 InterfaceWin *win = new InterfaceWin(r,selection->fData); 385 r=win->Frame(); 386 win->MoveBy((Frame().Width()-r.Width())/2, 387 (Frame().Height()-r.Height())/2); 388 389 win->fParentWindow = dynamic_cast <NetworkWindow *> (fView->Window()); 390 391 if (selection->fData.fEnabled) 392 win->fEnabled->SetValue(1); 393 394 if (selection->fData.fDHCP) 395 win->fDHCP->SetValue(1); 396 else 397 win->fManual->SetValue(1); 398 399 win->fName->SetText(selection->fData.fPrettyName.String()); 400 win->fIPAddress->SetText(selection->fData.fIPAddress.String()); 401 win->fNetMask->SetText(selection->fData.fNetMask.String()); 402 403 win->fChanged = false; 404 405 win->fIPAddress->SetTarget(win); 406 win->fNetMask->SetTarget(win); 407 win->fGateway->SetTarget(win); 408 409 win->Show(); 410 break; 411 } 412 case kClear_M: { 413 break; 414 } 415 case kCustom_M: { 416 break; 417 } 418 case kLogin_Info_M: { 419 LoginInfo *login_info_pop = new LoginInfo(); 420 login_info_pop->fParentWindow = dynamic_cast <NetworkWindow *> (fView->Window()); 421 login_info_pop->fName->SetText(fusername.String()); 422 login_info_pop->fName->MakeFocus(); 423 login_info_pop->Show(); 424 break; 425 } 426 case kBackup_M: { 427 BRect r(Frame()); 428 r.right = r.left + 260; 429 r.bottom = r.top + 77; 430 r.OffsetBy( (Frame().Width()-260)/2, (Frame().Height()-77)/2); 431 BackupWin *backup_pop = new BackupWin(r); 432 backup_pop->fParentWindow = dynamic_cast <NetworkWindow *> (fView->Window()); 433 backup_pop->Show(); 434 break; 435 } 436 case kRestore_M: { 437 BStringItem *string_item = dynamic_cast <BStringItem *> (fConfigurationsList->ItemAt(fConfigurationsList->CurrentSelection())); 438 LoadSettings(string_item->Text()); 439 PostMessage(kSOMETHING_HAS_CHANGED_M); 440 break; 441 } 442 case kDelete_M: { 443 DeleteConfigFile(); 444 LoadConfigEntries(); 445 fConfigurationsList->SelectionChanged(); 446 break; 447 } 448 case kSOMETHING_HAS_CHANGED_M: { 449 fRevert->SetEnabled(true); 450 fSave->SetEnabled(true); 451 break; 452 } 453 } 454 } 455 456 bool 457 NetworkWindow::QuitRequested(void) 458 { 459 if (fSave->IsEnabled() == true) { 460 BAlert *alert = new BAlert("Save Info Alert","Save changes before quitting?", 461 "Don't Save","Cancel","Save"); 462 int32 result = alert->Go(); 463 464 switch (result) { 465 case 0: { 466 // Don't Save 467 break; 468 } 469 case 1:{ 470 // Cancel 471 return false; 472 break; 473 } 474 case 2:{ 475 // Save 476 SaveBackup(NULL,fData); 477 break; 478 } 479 default: 480 break; 481 } 482 } 483 be_app->PostMessage(B_QUIT_REQUESTED); 484 return true; 485 } 486 487 void NetworkWindow::DeleteConfigFile() 488 { 489 BAlert *alert = new BAlert("Alert","Really delete networking configuration?", 490 "Delete","Cancel"); 491 int32 result = alert->Go(); 492 493 if (result == 0) { 494 BStringItem *item = dynamic_cast <BStringItem *> (fConfigurationsList->ItemAt(fConfigurationsList->CurrentSelection())); 495 496 BString path; 497 path = "/boot/home/config/settings/network."; 498 path << item->Text(); 499 500 BEntry entry(path.String()); 501 entry.Remove(); 502 } 503 } 504 505 void 506 NetworkWindow::LoadConfigEntries() 507 { 508 fConfigurationsList->MakeEmpty(); 509 510 BDirectory settings("/boot/home/config/settings/"); 511 BEntry entry; 512 513 if (settings.InitCheck() == B_OK) { 514 while (settings.GetNextEntry(&entry) == B_OK) { 515 // All the config files start with "network." so we only compare the 516 // first 8 characters 517 char buffer[9]; 518 entry.GetName(buffer); 519 buffer[8]='\0'; 520 521 if (strcmp(buffer,"network.") == 0) { 522 BString string; 523 char name[B_FILE_NAME_LENGTH]; 524 entry.GetName(name); 525 string << name; 526 string = string.Remove(0,8); 527 528 BStringItem *item = new BStringItem(string.String()); 529 fConfigurationsList->AddItem(item); 530 } 531 } 532 } 533 } 534 535 void 536 NetworkWindow::LoadSettings(const char *filename) 537 { 538 if(LoadBackup(filename,fData)!=B_OK) 539 return; 540 541 Lock(); 542 for(int32 i=0; i<fData.fInterfaceList.CountItems(); i++) { 543 InterfaceData *idata = (InterfaceData*)fData.fInterfaceList.ItemAt(i); 544 fInterfacesList->AddItem(new NetListItem(*idata)); 545 } 546 fInterfacesList->Select(0L); 547 548 fDomain->SetText(fData.fDomainName.String()); 549 fHost->SetText(fData.fHostname.String()); 550 fPrimaryDNS->SetText(fData.fPrimaryDNS.String()); 551 fSecondaryDNS->SetText(fData.fSecondaryDNS.String()); 552 553 if(fData.fFTPServer) 554 fFTPServer->SetValue(B_CONTROL_ON); 555 if(fData.fIPForwarding) 556 fIPForwarding->SetValue(B_CONTROL_ON); 557 if(fData.fTelnetServer) 558 fTelnetServer->SetValue(B_CONTROL_ON); 559 560 Unlock(); 561 } 562