1 /* BMailProtocolConfigView - the standard config view for all protocols 2 ** 3 ** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved. 4 */ 5 6 7 #include <TextControl.h> 8 #include <MenuField.h> 9 #include <PopUpMenu.h> 10 #include <String.h> 11 #include <Message.h> 12 #include <MenuItem.h> 13 #include <CheckBox.h> 14 15 #include <stdlib.h> 16 #include <stdio.h> 17 18 #include <MDRLanguage.h> 19 20 class _EXPORT BMailProtocolConfigView; 21 22 #include <crypt.h> 23 24 #include "ProtocolConfigView.h" 25 26 27 const char* kPartialDownloadLimit = "partial_download_limit"; 28 29 30 BodyDownloadConfig::BodyDownloadConfig() 31 : 32 BView(BRect(0,0,50,50), "body_config", B_FOLLOW_ALL_SIDES, 0) 33 { 34 const char *partial_text = MDR_DIALECT_CHOICE ( 35 "Partially download messages larger than", 36 "部分ダウンロードする"); 37 38 BRect r(0, 0, 280, 15); 39 fPartialBox = new BCheckBox(r, "size_if", partial_text, 40 new BMessage('SIZF')); 41 fPartialBox->ResizeToPreferred(); 42 43 r = fPartialBox->Frame(); 44 r.OffsetBy(17,r.Height() + 1); 45 r.right = r.left + be_plain_font->StringWidth("0000") + 10; 46 fSizeBox = new BTextControl(r, "size", "", "", NULL); 47 48 r.OffsetBy(r.Width() + 5,0); 49 fBytesLabel = new BStringView(r, "kb", "KB"); 50 AddChild(fBytesLabel); 51 fSizeBox->SetDivider(0); 52 53 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 54 AddChild(fPartialBox); 55 AddChild(fSizeBox); 56 ResizeToPreferred(); 57 } 58 59 60 void 61 BodyDownloadConfig::SetTo(MailAddonSettings& addonSettings) 62 { 63 const BMessage* settings = &addonSettings.Settings(); 64 65 int32 limit = 0; 66 if (settings->HasInt32(kPartialDownloadLimit)) 67 limit = settings->FindInt32(kPartialDownloadLimit); 68 if (limit < 0) { 69 fPartialBox->SetValue(B_CONTROL_OFF); 70 fSizeBox->SetText("0"); 71 fSizeBox->SetEnabled(false); 72 } else { 73 limit = int32(limit / 1024); 74 BString kb; 75 kb << limit; 76 fSizeBox->SetText(kb); 77 fPartialBox->SetValue(B_CONTROL_ON); 78 fSizeBox->SetEnabled(true); 79 } 80 } 81 82 83 void 84 BodyDownloadConfig::MessageReceived(BMessage *msg) 85 { 86 if (msg->what != 'SIZF') 87 return BView::MessageReceived(msg); 88 fSizeBox->SetEnabled(fPartialBox->Value()); 89 } 90 91 92 void 93 BodyDownloadConfig::AttachedToWindow() 94 { 95 fPartialBox->SetTarget(this); 96 fPartialBox->ResizeToPreferred(); 97 } 98 99 100 void 101 BodyDownloadConfig::GetPreferredSize(float *width, float *height) 102 { 103 *height = fSizeBox->Frame().bottom + 5; 104 *width = 200; 105 } 106 107 108 status_t 109 BodyDownloadConfig::Archive(BMessage* into, bool) const 110 { 111 into->RemoveName(kPartialDownloadLimit); 112 if (fPartialBox->Value() == B_CONTROL_ON) 113 into->AddInt32(kPartialDownloadLimit, atoi(fSizeBox->Text()) * 1024); 114 else 115 into->AddInt32(kPartialDownloadLimit, -1); 116 117 return B_OK; 118 } 119 120 121 namespace { 122 123 //--------------------Support functions and #defines--------------- 124 #define enable_control(name) if (FindView(name) != NULL) ((BControl *)(FindView(name)))->SetEnabled(true) 125 #define disable_control(name) if (FindView(name) != NULL) ((BControl *)(FindView(name)))->SetEnabled(false) 126 127 BTextControl *AddTextField (BRect &rect, const char *name, const char *label); 128 BMenuField *AddMenuField (BRect &rect, const char *name, const char *label); 129 float FindWidestLabel(BView *view); 130 131 static float sItemHeight; 132 133 inline const char * 134 TextControl(BView *parent,const char *name) 135 { 136 BTextControl *control = (BTextControl *)(parent->FindView(name)); 137 if (control != NULL) 138 return control->Text(); 139 140 return ""; 141 } 142 143 144 BTextControl * 145 AddTextField(BRect &rect, const char *name, const char *label) 146 { 147 BTextControl *text_control = new BTextControl(rect,name,label,"",NULL,B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); 148 // text_control->SetDivider(be_plain_font->StringWidth(label)); 149 rect.OffsetBy(0,sItemHeight); 150 return text_control; 151 } 152 153 154 BMenuField *AddMenuField (BRect &rect, const char *name, const char *label) { 155 BPopUpMenu *menu = new BPopUpMenu("Select"); 156 BMenuField *control = new BMenuField(rect,name,label,menu,B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); 157 control->SetDivider(be_plain_font->StringWidth(label) + 6); 158 rect.OffsetBy(0,sItemHeight); 159 return control; 160 } 161 162 163 inline BCheckBox * 164 AddCheckBox(BRect &rect, const char *name, const char *label, BMessage *msg = NULL) 165 { 166 BCheckBox *control = new BCheckBox(rect,name,label,msg); 167 rect.OffsetBy(0,sItemHeight); 168 return control; 169 } 170 171 172 inline void 173 SetTextControl(BView *parent, const char *name, const char *text) 174 { 175 BTextControl *control = (BTextControl *)(parent->FindView(name)); 176 if (control != NULL) 177 control->SetText(text); 178 } 179 180 181 float 182 FindWidestLabel(BView *view) 183 { 184 float width = 0; 185 for (int32 i = view->CountChildren();i-- > 0;) { 186 if (BControl *control = dynamic_cast<BControl *>(view->ChildAt(i))) { 187 float labelWidth = control->StringWidth(control->Label()); 188 if (labelWidth > width) 189 width = labelWidth; 190 } 191 } 192 return width; 193 } 194 195 } // unnamed namspace 196 197 198 //----------------Real code---------------------- 199 BMailProtocolConfigView::BMailProtocolConfigView(uint32 options_mask) 200 : 201 BView (BRect(0,0,100,20), "protocol_config_view", B_FOLLOW_LEFT 202 | B_FOLLOW_TOP, B_WILL_DRAW), 203 fBodyDownloadConfig(NULL) 204 { 205 BRect rect(5,5,245,25); 206 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 207 208 // determine font height 209 font_height fontHeight; 210 GetFontHeight(&fontHeight); 211 sItemHeight = (int32)(fontHeight.ascent + fontHeight.descent + fontHeight.leading) + 13; 212 rect.bottom = rect.top - 2 + sItemHeight; 213 214 if (options_mask & B_MAIL_PROTOCOL_HAS_HOSTNAME) 215 AddChild(AddTextField(rect,"host",MDR_DIALECT_CHOICE ("Mail server:","サーバ名 :"))); 216 217 if (options_mask & B_MAIL_PROTOCOL_HAS_USERNAME) 218 AddChild(AddTextField(rect,"user",MDR_DIALECT_CHOICE ("Username:","ユーザーID:"))); 219 220 if (options_mask & B_MAIL_PROTOCOL_HAS_PASSWORD) { 221 BTextControl *control = AddTextField(rect,"pass",MDR_DIALECT_CHOICE ("Password:","パスワード:")); 222 control->TextView()->HideTyping(true); 223 AddChild(control); 224 } 225 226 if (options_mask & B_MAIL_PROTOCOL_HAS_FLAVORS) 227 AddChild(AddMenuField(rect,"flavor","Connection type:")); 228 229 if (options_mask & B_MAIL_PROTOCOL_HAS_AUTH_METHODS) 230 AddChild(AddMenuField(rect,"auth_method",MDR_DIALECT_CHOICE ("Login type:","認証方法 :"))); 231 232 // set divider 233 float width = FindWidestLabel(this); 234 for (int32 i = CountChildren();i-- > 0;) { 235 if (BTextControl *text = dynamic_cast<BTextControl *>(ChildAt(i))) 236 text->SetDivider(width + 6); 237 } 238 239 if (options_mask & B_MAIL_PROTOCOL_CAN_LEAVE_MAIL_ON_SERVER) { 240 AddChild(AddCheckBox(rect, "leave_mail_on_server", 241 MDR_DIALECT_CHOICE ("Leave mail on server", 242 "受信後にサーバ内のメールを削除しない"), new BMessage('lmos'))); 243 BCheckBox* box = AddCheckBox(rect, "delete_remote_when_local", 244 MDR_DIALECT_CHOICE ("Remove mail from server when deleted", 245 "端末で削除されたらサーバ保存分も削除")); 246 box->SetEnabled(false); 247 AddChild(box); 248 } 249 250 if (options_mask & B_MAIL_PROTOCOL_PARTIAL_DOWNLOAD) { 251 fBodyDownloadConfig = new BodyDownloadConfig(); 252 fBodyDownloadConfig->MoveBy(0, rect.bottom + 5); 253 AddChild(fBodyDownloadConfig); 254 } 255 256 // resize views 257 float height; 258 GetPreferredSize(&width,&height); 259 ResizeTo(width,height); 260 for (int32 i = CountChildren();i-- > 0;) { 261 // this doesn't work with BTextControl, does anyone know why? -- axeld. 262 if (BView *view = ChildAt(i)) 263 view->ResizeTo(width - 10,view->Bounds().Height()); 264 } 265 } 266 267 268 BMailProtocolConfigView::~BMailProtocolConfigView() 269 { 270 } 271 272 273 void 274 BMailProtocolConfigView::SetTo(MailAddonSettings& settings) 275 { 276 const BMessage* archive = &settings.Settings(); 277 278 BString host = archive->FindString("server"); 279 if (archive->HasInt32("port")) 280 host << ':' << archive->FindInt32("port"); 281 282 SetTextControl(this,"host", host.String()); 283 SetTextControl(this,"user", archive->FindString("username")); 284 285 char *password = get_passwd(archive, "cpasswd"); 286 if (password) { 287 SetTextControl(this,"pass", password); 288 delete[] password; 289 } else 290 SetTextControl(this,"pass", archive->FindString("password")); 291 292 if (archive->HasInt32("flavor")) { 293 BMenuField *menu = (BMenuField *)(FindView("flavor")); 294 if (menu != NULL) { 295 if (BMenuItem *item = menu->Menu()->ItemAt(archive->FindInt32("flavor"))) 296 item->SetMarked(true); 297 } 298 } 299 300 if (archive->HasInt32("auth_method")) { 301 BMenuField *menu = (BMenuField *)(FindView("auth_method")); 302 if (menu != NULL) { 303 if (BMenuItem *item = menu->Menu()->ItemAt(archive->FindInt32("auth_method"))) { 304 item->SetMarked(true); 305 if (item->Command() != 'none') { 306 enable_control("user"); 307 enable_control("pass"); 308 } 309 } 310 } 311 } 312 313 314 BCheckBox *box = (BCheckBox *)(FindView("leave_mail_on_server")); 315 if (box != NULL) 316 box->SetValue(archive->FindBool("leave_mail_on_server") ? B_CONTROL_ON : B_CONTROL_OFF); 317 318 box = (BCheckBox *)(FindView("delete_remote_when_local")); 319 if (box != NULL) { 320 box->SetValue(archive->FindBool("delete_remote_when_local") ? B_CONTROL_ON : B_CONTROL_OFF); 321 322 if (archive->FindBool("leave_mail_on_server")) 323 box->SetEnabled(true); 324 else 325 box->SetEnabled(false); 326 } 327 328 if (fBodyDownloadConfig) 329 fBodyDownloadConfig->SetTo(settings); 330 } 331 332 333 void 334 BMailProtocolConfigView::AddFlavor(const char *label) 335 { 336 BMenuField *menu = (BMenuField *)(FindView("flavor")); 337 if (menu != NULL) { 338 menu->Menu()->AddItem(new BMenuItem(label,NULL)); 339 if (menu->Menu()->FindMarked() == NULL) 340 menu->Menu()->ItemAt(0)->SetMarked(true); 341 } 342 } 343 344 345 void 346 BMailProtocolConfigView::AddAuthMethod(const char *label,bool needUserPassword) 347 { 348 BMenuField *menu = (BMenuField *)(FindView("auth_method")); 349 if (menu != NULL) { 350 BMenuItem *item = new BMenuItem(label,new BMessage(needUserPassword ? 'some' : 'none')); 351 352 menu->Menu()->AddItem(item); 353 354 if (menu->Menu()->FindMarked() == NULL) { 355 menu->Menu()->ItemAt(0)->SetMarked(true); 356 MessageReceived(menu->Menu()->ItemAt(0)->Message()); 357 } 358 } 359 } 360 361 362 void 363 BMailProtocolConfigView::AttachedToWindow() 364 { 365 BMenuField *menu = (BMenuField *)(FindView("auth_method")); 366 if (menu != NULL) 367 menu->Menu()->SetTargetForItems(this); 368 369 BCheckBox *box = (BCheckBox *)(FindView("leave_mail_on_server")); 370 if (box != NULL) 371 box->SetTarget(this); 372 } 373 374 375 void 376 BMailProtocolConfigView::MessageReceived(BMessage *msg) 377 { 378 switch (msg->what) { 379 case 'some': 380 enable_control("user"); 381 enable_control("pass"); 382 break; 383 case 'none': 384 disable_control("user"); 385 disable_control("pass"); 386 break; 387 388 case 'lmos': 389 if (msg->FindInt32("be:value") == 1) { 390 enable_control("delete_remote_when_local"); 391 } else { 392 disable_control("delete_remote_when_local"); 393 } 394 break; 395 } 396 } 397 398 399 status_t 400 BMailProtocolConfigView::Archive(BMessage *into, bool deep) const 401 { 402 const char *host = TextControl((BView *)this,"host"); 403 int32 port = -1; 404 BString host_name = host; 405 if (host_name.FindFirst(':') > -1) { 406 port = atol(host_name.String() + host_name.FindFirst(':') + 1); 407 host_name.Truncate(host_name.FindFirst(':')); 408 } 409 410 if (into->ReplaceString("server",host_name.String()) != B_OK) 411 into->AddString("server",host_name.String()); 412 413 // since there is no need for the port option, remove it here 414 into->RemoveName("port"); 415 if (port != -1) 416 into->AddInt32("port",port); 417 418 if (into->ReplaceString("username",TextControl((BView *)this,"user")) != B_OK) 419 into->AddString("username",TextControl((BView *)this,"user")); 420 421 // remove old unencrypted passwords 422 into->RemoveName("password"); 423 424 set_passwd(into,"cpasswd",TextControl((BView *)this,"pass")); 425 426 BMenuField *field; 427 int32 index = -1; 428 429 if ((field = (BMenuField *)(FindView("flavor"))) != NULL) { 430 BMenuItem *item = field->Menu()->FindMarked(); 431 if (item != NULL) 432 index = field->Menu()->IndexOf(item); 433 } 434 435 if (into->ReplaceInt32("flavor",index) != B_OK) 436 into->AddInt32("flavor",index); 437 438 index = -1; 439 440 if ((field = (BMenuField *)(FindView("auth_method"))) != NULL) { 441 BMenuItem *item = field->Menu()->FindMarked(); 442 if (item != NULL) 443 index = field->Menu()->IndexOf(item); 444 } 445 446 if (into->ReplaceInt32("auth_method",index) != B_OK) 447 into->AddInt32("auth_method",index); 448 449 if (FindView("leave_mail_on_server") != NULL) { 450 BControl* control = (BControl*)FindView("leave_mail_on_server"); 451 bool on = (control->Value() == B_CONTROL_ON); 452 if (into->ReplaceBool("leave_mail_on_server", on) != B_OK) 453 into->AddBool("leave_mail_on_server", on); 454 455 control = (BControl*)FindView("delete_remote_when_local"); 456 on = (control->Value() == B_CONTROL_ON); 457 if (into->ReplaceBool("delete_remote_when_local", on)) { 458 into->AddBool("delete_remote_when_local", on); 459 } 460 } else { 461 if (into->ReplaceBool("leave_mail_on_server", false) != B_OK) 462 into->AddBool("leave_mail_on_server", false); 463 464 if (into->ReplaceBool("delete_remote_when_local", false) != B_OK) 465 into->AddBool("delete_remote_when_local", false); 466 } 467 468 if (fBodyDownloadConfig) 469 fBodyDownloadConfig->Archive(into, deep); 470 return B_OK; 471 } 472 473 474 void 475 BMailProtocolConfigView::GetPreferredSize(float *width, float *height) 476 { 477 float minWidth = 250; 478 if (BView *view = FindView("delete_remote_when_local")) { 479 float ignore; 480 view->GetPreferredSize(&minWidth,&ignore); 481 } 482 if (minWidth < 250) 483 minWidth = 250; 484 *width = minWidth + 10; 485 *height = (CountChildren() * sItemHeight) + 5; 486 487 if (fBodyDownloadConfig) { 488 float bodyW, bodyH; 489 fBodyDownloadConfig->GetPreferredSize(&bodyW, &bodyH); 490 *height+= bodyH; 491 } 492 } 493 494