1 #include "AutoConfigView.h" 2 3 #include <Directory.h> 4 #include <Entry.h> 5 #include <FindDirectory.h> 6 #include <Message.h> 7 #include <MenuItem.h> 8 #include <Path.h> 9 #include <PopUpMenu.h> 10 #include <String.h> 11 #include <Window.h> 12 13 #include <MailSettings.h> 14 15 16 AutoConfigView::AutoConfigView(BRect rect, AutoConfig &config) 17 : BBox(rect), 18 fAutoConfig(config) 19 { 20 int32 stepSize = 30; 21 int32 divider = 100; 22 BPoint topLeft(20, 20); 23 BPoint rightDown(rect.Width() - 20, 20 + stepSize); 24 25 // type view 26 BPopUpMenu *chainsPopUp = new BPopUpMenu(B_EMPTY_STRING); 27 const char *chainModes[] = { 28 "Receive mail only", 29 "Send mail only", 30 "Send and receive mail"}; 31 BMenuItem *item; 32 for (int32 i = 0; i < 3; i++) 33 chainsPopUp->AddItem(item = new BMenuItem(chainModes[i], NULL)); 34 35 fTypeField = new BMenuField(BRect(topLeft, rightDown), NULL, 36 "Account Type:", chainsPopUp); 37 fTypeField->SetDivider(divider); 38 fTypeField->Menu()->ItemAt(2)->SetMarked(true); 39 //fAccount->SetType(2); 40 AddChild(fTypeField); 41 42 // protocol view 43 topLeft.y += stepSize; 44 rightDown.y += stepSize; 45 fInProtocolsField = SetupProtokolView(BRect(topLeft, rightDown)); 46 if (fInProtocolsField) { 47 fTypeField->SetDivider(divider); 48 AddChild(fInProtocolsField); 49 } 50 51 // search for smtp ref 52 GetSMTPAddonRef(&fSMTPAddonRef); 53 54 // email view 55 topLeft.y += stepSize; 56 rightDown.y += stepSize; 57 fEmailView = new BTextControl(BRect(topLeft, rightDown), 58 "email", "E-mail address:", "", 59 new BMessage(kEMailChangedMsg)); 60 fEmailView->SetDivider(divider); 61 AddChild(fEmailView); 62 63 // login name view 64 topLeft.y += stepSize; 65 rightDown.y += stepSize; 66 fLoginNameView = new BTextControl(BRect(topLeft, rightDown), 67 "login", "Login name:", "", 68 NULL); 69 fLoginNameView->SetDivider(divider); 70 AddChild(fLoginNameView); 71 72 // password view 73 topLeft.y += stepSize; 74 rightDown.y += stepSize; 75 fPasswordView = new BTextControl(BRect(topLeft, rightDown), 76 "password", "Password:", "", 77 NULL); 78 fPasswordView->SetDivider(divider); 79 fPasswordView->TextView()->HideTyping(true); 80 AddChild(fPasswordView); 81 82 // account view 83 topLeft.y += stepSize; 84 rightDown.y += stepSize; 85 fAccountNameView = new BTextControl(BRect(topLeft, rightDown), 86 "account", "Account name:", "", 87 NULL); 88 fAccountNameView->SetDivider(divider); 89 AddChild(fAccountNameView); 90 91 // name view 92 topLeft.y += stepSize; 93 rightDown.y += stepSize; 94 fNameView = new BTextControl(BRect(topLeft, rightDown), 95 "name", "Real name:", "", 96 NULL); 97 AddChild(fNameView); 98 fNameView->SetDivider(divider); 99 100 } 101 102 103 void 104 AutoConfigView::AttachedToWindow() 105 { 106 fEmailView->SetTarget(this); 107 fEmailView->MakeFocus(true); 108 } 109 110 111 void 112 AutoConfigView::MessageReceived(BMessage *msg) 113 { 114 BString text, login; 115 switch (msg->what) 116 { 117 case kEMailChangedMsg: 118 { 119 text = fLoginNameView->Text(); 120 if (text == "") 121 ProposeUsername(); 122 fLoginNameView->MakeFocus(); 123 fLoginNameView->TextView()->SelectAll(); 124 125 text = fAccountNameView->Text(); 126 if (text == "") 127 fAccountNameView->SetText(fEmailView->Text()); 128 break; 129 } 130 default: 131 BView::MessageReceived(msg); 132 break; 133 } 134 } 135 136 137 bool 138 AutoConfigView::GetBasicAccountInfo(account_info &info) 139 { 140 status_t status = B_OK; 141 142 BMenuItem* item = fTypeField->Menu()->FindMarked(); 143 info.type = fTypeField->Menu()->IndexOf(item); 144 145 BString inboundProtocolName = ""; 146 item = fInProtocolsField->Menu()->FindMarked(); 147 if (item) { 148 inboundProtocolName = item->Label(); 149 item->Message()->FindRef("protocol", &(info.inboundProtocol)); 150 } 151 else 152 status = B_ERROR; 153 154 if (inboundProtocolName.FindFirst("IMAP") >= 0) 155 info.inboundType = IMAP; 156 else 157 info.inboundType = POP; 158 159 info.outboundProtocol = fSMTPAddonRef; 160 info.name = fNameView->Text(); 161 info.accountName = fAccountNameView->Text(); 162 info.email = fEmailView->Text(); 163 info.loginName = fLoginNameView->Text(); 164 info.password = fPasswordView->Text(); 165 166 return status; 167 } 168 169 170 BMenuField* 171 AutoConfigView::SetupProtokolView(BRect rect) 172 { 173 BPopUpMenu *menu = new BPopUpMenu("Choose Protocol"); 174 175 for (int i = 0; i < 2; i++) { 176 BPath path; 177 status_t status = find_directory((i == 0) ? B_USER_ADDONS_DIRECTORY : 178 B_BEOS_ADDONS_DIRECTORY, &path); 179 if (status != B_OK) 180 return NULL; 181 182 path.Append("mail_daemon"); 183 path.Append("inbound_protocols"); 184 185 BDirectory dir(path.Path()); 186 entry_ref protocolRef; 187 while (dir.GetNextRef(&protocolRef) == B_OK) 188 { 189 char name[B_FILE_NAME_LENGTH]; 190 BEntry entry(&protocolRef); 191 entry.GetName(name); 192 193 BMenuItem *item; 194 BMessage *msg = new BMessage(kProtokollChangedMsg); 195 menu->AddItem(item = new BMenuItem(name, msg)); 196 msg->AddRef("protocol",&protocolRef); 197 198 //if (*ref == protocolRef) 199 item->SetMarked(true); 200 } 201 } 202 203 BMenuField *protocolsMenuField = new BMenuField(rect, NULL, NULL, menu); 204 protocolsMenuField->ResizeToPreferred(); 205 return protocolsMenuField; 206 } 207 208 209 status_t 210 AutoConfigView::GetSMTPAddonRef(entry_ref *ref) 211 { 212 for (int i = 0; i < 2; i++) { 213 BPath path; 214 status_t status = find_directory((i == 0) ? B_USER_ADDONS_DIRECTORY : 215 B_BEOS_ADDONS_DIRECTORY, &path); 216 if (status != B_OK) 217 { 218 return B_ERROR; 219 } 220 221 path.Append("mail_daemon"); 222 path.Append("outbound_protocols"); 223 224 BDirectory dir(path.Path()); 225 226 while (dir.GetNextRef(ref) == B_OK) 227 { 228 return B_OK; 229 } 230 } 231 232 return B_ERROR; 233 } 234 235 236 BString 237 AutoConfigView::ExtractLocalPart(const char* email) 238 { 239 BString emailS(email); 240 BString localPart; 241 int32 at = emailS.FindLast("@"); 242 emailS.CopyInto(localPart, 0, at); 243 return localPart; 244 } 245 246 247 void 248 AutoConfigView::ProposeUsername() 249 { 250 const char* email = fEmailView->Text(); 251 provider_info info; 252 status_t status = fAutoConfig.GetInfoFromMailAddress(email, &info); 253 if (status == B_OK) { 254 BString localPart = ExtractLocalPart(email); 255 switch (info.username_pattern) { 256 case 0: 257 // username is the mail address 258 fLoginNameView->SetText(email); 259 break; 260 case 1: 261 // username is the local-part 262 fLoginNameView->SetText(localPart.String()); 263 break; 264 case 2: 265 // do nothing 266 break; 267 } 268 } 269 else { 270 fLoginNameView->SetText(email); 271 } 272 } 273 274 275 bool 276 AutoConfigView::IsValidMailAddress(BString email) 277 { 278 int32 atPos = email.FindFirst("@"); 279 if (atPos < 0) 280 return false; 281 BString provider; 282 email.CopyInto(provider, atPos + 1, email.Length() - atPos); 283 if (provider.FindLast(".") < 0) 284 return false; 285 return true; 286 } 287 288 289 ServerSettingsView::ServerSettingsView(BRect rect, const account_info &info) 290 : BView(rect, NULL,B_FOLLOW_ALL,0), 291 fInboundAccount(false), 292 fOutboundAccount(false), 293 fInboundAuthMenu(NULL), 294 fOutboundAuthMenu(NULL), 295 fInboundEncrItemStart(NULL), 296 fOutboundEncrItemStart(NULL) 297 { 298 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 299 300 int32 divider = 120; 301 302 switch (info.type) { 303 case 0: 304 fInboundAccount = true; 305 break; 306 case 1: 307 fOutboundAccount = true; 308 break; 309 case 2: 310 fInboundAccount = true; 311 fOutboundAccount = true; 312 break; 313 } 314 // inbound 315 BRect boxRect = Bounds(); 316 boxRect.bottom /= 2; 317 boxRect.bottom -= 5; 318 319 BBox *box = new BBox(boxRect); 320 box->SetLabel("Inbound"); 321 AddChild(box); 322 323 BString serverName; 324 if (info.inboundType == IMAP) 325 serverName = info.providerInfo.imap_server; 326 else 327 serverName = info.providerInfo.pop_server; 328 329 fInboundNameView = new BTextControl(BRect(10, 20, rect.Width() - 20, 35), 330 "inbound", "Server Name:", 331 serverName.String(), 332 new BMessage(kServerChangedMsg)); 333 fInboundNameView->SetDivider(divider); 334 335 box->AddChild(fInboundNameView); 336 337 GetAuthEncrMenu(info.inboundProtocol, &fInboundAuthMenu, 338 &fInboundEncryptionMenu); 339 if (fInboundAuthMenu) { 340 int authID = info.providerInfo.authentification_pop; 341 if (info.inboundType == POP) 342 fInboundAuthMenu->Menu()->ItemAt(authID)->SetMarked(true); 343 fInboundAuthItemStart = fInboundAuthMenu->Menu()->FindMarked(); 344 box->AddChild(fInboundAuthMenu); 345 fInboundAuthMenu->SetDivider(divider); 346 fInboundAuthMenu->MoveTo(10, 50); 347 } 348 if (fInboundEncryptionMenu) { 349 BMenuItem *item = NULL; 350 if (info.inboundType == POP) { 351 item = fInboundEncryptionMenu->Menu() 352 ->ItemAt(info.providerInfo.ssl_pop); 353 if (item) 354 item->SetMarked(true); 355 fInboundEncryptionMenu->MoveTo(10, 80); 356 } 357 if (info.inboundType == IMAP) { 358 item = fInboundEncryptionMenu->Menu() 359 ->ItemAt(info.providerInfo.ssl_imap); 360 if (item) 361 item->SetMarked(true); 362 fInboundEncryptionMenu->MoveTo(10, 50); 363 } 364 fInboundEncrItemStart = fInboundEncryptionMenu->Menu()->FindMarked(); 365 box->AddChild(fInboundEncryptionMenu); 366 fInboundEncryptionMenu->SetDivider(divider); 367 } 368 369 if (!fInboundAccount) { 370 fInboundNameView->SetEnabled(false); 371 if (fInboundAuthMenu) 372 fInboundAuthMenu->SetEnabled(false); 373 } 374 375 // outbound 376 boxRect = Bounds(); 377 boxRect.top = boxRect.bottom / 2; 378 boxRect.top += 5; 379 380 box = new BBox(boxRect); 381 box->SetLabel("Outbound"); 382 AddChild(box); 383 384 serverName = info.providerInfo.smtp_server; 385 fOutboundNameView = new BTextControl(BRect(10, 20, rect.Width() - 20, 30), 386 "outbound", "Server name:", 387 serverName.String(), 388 new BMessage(kServerChangedMsg)); 389 fOutboundNameView->SetDivider(divider); 390 391 box->AddChild(fOutboundNameView); 392 393 GetAuthEncrMenu(info.outboundProtocol, &fOutboundAuthMenu, 394 &fOutboundEncryptionMenu); 395 if (fOutboundAuthMenu) { 396 BMenuItem *item = fOutboundAuthMenu->Menu() 397 ->ItemAt(info.providerInfo.authentification_smtp); 398 if (item) 399 item->SetMarked(true); 400 fOutboundAuthItemStart = item; 401 box->AddChild(fOutboundAuthMenu); 402 fOutboundAuthMenu->SetDivider(divider); 403 fOutboundAuthMenu->MoveTo(10, 50); 404 } 405 if (fOutboundEncryptionMenu) { 406 BMenuItem *item = fOutboundEncryptionMenu->Menu() 407 ->ItemAt(info.providerInfo.ssl_smtp); 408 if (item) 409 item->SetMarked(true); 410 fOutboundEncrItemStart = item; 411 box->AddChild(fOutboundEncryptionMenu); 412 fOutboundEncryptionMenu->SetDivider(divider); 413 fOutboundEncryptionMenu->MoveTo(10, 80); 414 } 415 416 if (!fOutboundAccount) { 417 fOutboundNameView->SetEnabled(false); 418 if (fOutboundAuthMenu) 419 fOutboundAuthMenu->SetEnabled(false); 420 } 421 422 } 423 424 425 void 426 ServerSettingsView::GetServerInfo(account_info &info) 427 { 428 if (info.inboundType == IMAP) { 429 info.providerInfo.imap_server = fInboundNameView->Text(); 430 if (fInboundEncryptionMenu) { 431 BMenuItem* item = fInboundEncryptionMenu->Menu()->FindMarked(); 432 if (item) 433 info.providerInfo.ssl_imap = fInboundEncryptionMenu->Menu() 434 ->IndexOf(item); 435 } 436 } else { 437 info.providerInfo.pop_server = fInboundNameView->Text(); 438 BMenuItem* item = NULL; 439 if (fInboundAuthMenu) { 440 item = fInboundAuthMenu->Menu()->FindMarked(); 441 if (item) 442 info.providerInfo.authentification_pop = fInboundAuthMenu 443 ->Menu() 444 ->IndexOf(item); 445 } 446 if (fInboundEncryptionMenu) { 447 item = fInboundEncryptionMenu->Menu()->FindMarked(); 448 if (item) 449 info.providerInfo.ssl_pop = fInboundEncryptionMenu->Menu() 450 ->IndexOf(item); 451 } 452 } 453 info.providerInfo.smtp_server = fOutboundNameView->Text(); 454 BMenuItem* item = NULL; 455 if (fOutboundAuthMenu) { 456 item = fOutboundAuthMenu->Menu()->FindMarked(); 457 if (item) 458 info.providerInfo.authentification_smtp = fOutboundAuthMenu->Menu() 459 ->IndexOf(item); 460 } 461 462 if (fOutboundEncryptionMenu) { 463 item = fOutboundEncryptionMenu->Menu()->FindMarked(); 464 if (item) 465 info.providerInfo.ssl_smtp = fOutboundEncryptionMenu->Menu() 466 ->IndexOf(item); 467 } 468 DetectMenuChanges(); 469 } 470 471 472 void 473 ServerSettingsView::DetectMenuChanges() 474 { 475 bool changed = false; 476 if (fInboundAuthMenu) { 477 BMenuItem *item = fInboundAuthMenu->Menu()->FindMarked(); 478 if (fInboundAuthItemStart != item) 479 changed = true; 480 } 481 if (fInboundEncryptionMenu) { 482 BMenuItem *item = fInboundEncryptionMenu->Menu()->FindMarked(); 483 if (fInboundEncrItemStart != item) 484 changed = true; 485 } 486 if (fOutboundAuthMenu) { 487 BMenuItem *item = fOutboundAuthMenu->Menu()->FindMarked(); 488 if (fOutboundAuthItemStart != item) 489 changed = true; 490 } 491 if (fOutboundEncryptionMenu) { 492 BMenuItem *item = fOutboundEncryptionMenu->Menu()->FindMarked(); 493 if (fOutboundEncrItemStart != item) 494 changed = true; 495 } 496 if (changed) { 497 BMessage msg(kServerChangedMsg); 498 BMessenger messenger(NULL, Window()->Looper()); 499 messenger.SendMessage(&msg); 500 } 501 } 502 503 504 void 505 ServerSettingsView::GetAuthEncrMenu(const entry_ref &ref, 506 BMenuField **authField, 507 BMenuField **sslField) 508 { 509 // TODO: These menus being NULL is not correctly handled everywhere 510 // in this class. 511 BMessage dummyMsg; 512 BView *(* instantiate_config)(BMessage *,BMessage *); 513 BPath addon(&ref); 514 image_id image = load_add_on(addon.Path()); 515 if (image < B_OK) { 516 *authField = NULL; 517 *sslField = NULL; 518 return; 519 } 520 521 if (get_image_symbol(image,"instantiate_config_panel", 522 B_SYMBOL_TYPE_TEXT,(void **)&instantiate_config) < B_OK) 523 { 524 unload_add_on(image); 525 image = B_MISSING_SYMBOL; 526 *authField = NULL; 527 *sslField = NULL; 528 return; 529 } 530 531 BView *view = (*instantiate_config)(&dummyMsg, &dummyMsg); 532 *authField = (BMenuField *)(view->FindView("auth_method")); 533 *sslField = (BMenuField *)(view->FindView("flavor")); 534 535 view->RemoveChild(*authField); 536 view->RemoveChild(*sslField); 537 delete view; 538 unload_add_on(image); 539 } 540