1 /* 2 * Copyright 2011-2012, Haiku Inc. All Rights Reserved. 3 * Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 //! The standard config view for all protocols. 9 10 11 #include "ProtocolConfigView.h" 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 16 #include <Catalog.h> 17 #include <CheckBox.h> 18 #include <ControlLook.h> 19 #include <GridLayout.h> 20 #include <LayoutBuilder.h> 21 #include <MenuField.h> 22 #include <MenuItem.h> 23 #include <Message.h> 24 #include <PopUpMenu.h> 25 #include <String.h> 26 #include <TextControl.h> 27 28 #include <crypt.h> 29 30 31 #undef B_TRANSLATION_CONTEXT 32 #define B_TRANSLATION_CONTEXT "ProtocolConfigView" 33 34 35 static const char* kPartialDownloadLimit = "partial_download_limit"; 36 37 static const uint32 kMsgLeaveOnServer = 'lmos'; 38 static const uint32 kMsgNoPassword = 'none'; 39 static const uint32 kMsgNeedPassword = 'some'; 40 41 42 namespace BPrivate { 43 44 45 BodyDownloadConfigView::BodyDownloadConfigView() 46 : 47 BView("body_config", 0) 48 { 49 fPartialBox = new BCheckBox("size_if", B_TRANSLATE( 50 "Partially download messages larger than"), new BMessage('SIZF')); 51 52 fSizeControl = new BTextControl("size", 53 B_TRANSLATE_COMMENT("KB", "kilo byte"), "", NULL); 54 fSizeControl->SetExplicitMinSize(BSize(be_plain_font->StringWidth("0000"), 55 B_SIZE_UNSET)); 56 57 BLayoutBuilder::Group<>(this, B_HORIZONTAL, 58 be_control_look->DefaultLabelSpacing()) 59 .Add(fPartialBox) 60 .Add(fSizeControl->CreateTextViewLayoutItem()) 61 .Add(fSizeControl->CreateLabelLayoutItem()); 62 } 63 64 65 void 66 BodyDownloadConfigView::SetTo(const BMailProtocolSettings& settings) 67 { 68 int32 limit = settings.GetInt32(kPartialDownloadLimit, -1); 69 if (limit < 0) { 70 fPartialBox->SetValue(B_CONTROL_OFF); 71 fSizeControl->SetText("0"); 72 fSizeControl->SetEnabled(false); 73 } else { 74 BString kb; 75 kb << int32(limit / 1024); 76 fSizeControl->SetText(kb); 77 fPartialBox->SetValue(B_CONTROL_ON); 78 fSizeControl->SetEnabled(true); 79 } 80 } 81 82 83 status_t 84 BodyDownloadConfigView::SaveInto(BMailAddOnSettings& settings) const 85 { 86 if (fPartialBox->Value() == B_CONTROL_ON) { 87 settings.SetInt32(kPartialDownloadLimit, 88 atoi(fSizeControl->Text()) * 1024); 89 } else 90 settings.RemoveName(kPartialDownloadLimit); 91 92 return B_OK; 93 } 94 95 96 void 97 BodyDownloadConfigView::MessageReceived(BMessage *msg) 98 { 99 if (msg->what != 'SIZF') 100 return BView::MessageReceived(msg); 101 fSizeControl->SetEnabled(fPartialBox->Value()); 102 } 103 104 105 void 106 BodyDownloadConfigView::AttachedToWindow() 107 { 108 fPartialBox->SetTarget(this); 109 fPartialBox->ResizeToPreferred(); 110 } 111 112 113 // #pragma mark - 114 115 116 MailProtocolConfigView::MailProtocolConfigView(uint32 optionsMask) 117 : 118 BMailSettingsView("protocol_config_view"), 119 fHostControl(NULL), 120 fUserControl(NULL), 121 fPasswordControl(NULL), 122 fFlavorField(NULL), 123 fAuthenticationField(NULL), 124 fLeaveOnServerCheckBox(NULL), 125 fRemoveFromServerCheckBox(NULL), 126 fBodyDownloadConfig(NULL) 127 { 128 SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 129 130 BGridLayout* layout = new BGridLayout(0.f); 131 SetLayout(layout); 132 133 if ((optionsMask & B_MAIL_PROTOCOL_HAS_HOSTNAME) != 0) { 134 fHostControl = _AddTextControl(layout, "host", 135 B_TRANSLATE("Mail server:")); 136 } 137 if ((optionsMask & B_MAIL_PROTOCOL_HAS_USERNAME) != 0) { 138 fUserControl = _AddTextControl(layout, "user", 139 B_TRANSLATE("Username:")); 140 } 141 142 if ((optionsMask & B_MAIL_PROTOCOL_HAS_PASSWORD) != 0) { 143 fPasswordControl = _AddTextControl(layout, "pass", 144 B_TRANSLATE("Password:")); 145 fPasswordControl->TextView()->HideTyping(true); 146 } 147 148 if ((optionsMask & B_MAIL_PROTOCOL_HAS_FLAVORS) != 0) { 149 fFlavorField = _AddMenuField(layout, "flavor", 150 B_TRANSLATE("Connection type:")); 151 } 152 153 if ((optionsMask & B_MAIL_PROTOCOL_HAS_AUTH_METHODS) != 0) { 154 fAuthenticationField = _AddMenuField(layout, "auth_method", 155 B_TRANSLATE("Login type:")); 156 } 157 158 if ((optionsMask & B_MAIL_PROTOCOL_CAN_LEAVE_MAIL_ON_SERVER) != 0) { 159 fLeaveOnServerCheckBox = new BCheckBox("leave_mail_on_server", 160 B_TRANSLATE("Leave mail on server"), 161 new BMessage(kMsgLeaveOnServer)); 162 layout->AddView(fLeaveOnServerCheckBox, 0, layout->CountRows(), 2); 163 164 fRemoveFromServerCheckBox = new BCheckBox("delete_remote_when_local", 165 B_TRANSLATE("Remove mail from server when deleted"), NULL); 166 fRemoveFromServerCheckBox->SetEnabled(false); 167 layout->AddView(fRemoveFromServerCheckBox, 0, layout->CountRows(), 2); 168 } 169 170 if ((optionsMask & B_MAIL_PROTOCOL_PARTIAL_DOWNLOAD) != 0) { 171 fBodyDownloadConfig = new BodyDownloadConfigView(); 172 layout->AddView(fBodyDownloadConfig, 0, layout->CountRows(), 2); 173 } 174 } 175 176 177 MailProtocolConfigView::~MailProtocolConfigView() 178 { 179 } 180 181 182 void 183 MailProtocolConfigView::SetTo(const BMailProtocolSettings& settings) 184 { 185 BString host = settings.FindString("server"); 186 if (settings.HasInt32("port")) 187 host << ':' << settings.FindInt32("port"); 188 189 if (fHostControl != NULL) 190 fHostControl->SetText(host.String()); 191 if (fUserControl != NULL) 192 fUserControl->SetText(settings.FindString("username")); 193 194 if (fPasswordControl != NULL) { 195 char* password = get_passwd(&settings, "cpasswd"); 196 if (password != NULL) { 197 fPasswordControl->SetText(password); 198 delete[] password; 199 } else 200 fPasswordControl->SetText(settings.FindString("password")); 201 } 202 203 if (settings.HasInt32("flavor") && fFlavorField != NULL) { 204 if (BMenuItem* item = fFlavorField->Menu()->ItemAt( 205 settings.FindInt32("flavor"))) 206 item->SetMarked(true); 207 } 208 209 if (settings.HasInt32("auth_method") && fAuthenticationField != NULL) { 210 if (BMenuItem* item = fAuthenticationField->Menu()->ItemAt( 211 settings.FindInt32("auth_method"))) { 212 item->SetMarked(true); 213 _SetCredentialsEnabled(item->Command() != kMsgNoPassword); 214 } 215 } 216 217 if (fLeaveOnServerCheckBox != NULL) { 218 fLeaveOnServerCheckBox->SetValue(settings.FindBool( 219 "leave_mail_on_server") ? B_CONTROL_ON : B_CONTROL_OFF); 220 } 221 222 if (fRemoveFromServerCheckBox != NULL) { 223 fRemoveFromServerCheckBox->SetValue(settings.FindBool( 224 "delete_remote_when_local") ? B_CONTROL_ON : B_CONTROL_OFF); 225 fRemoveFromServerCheckBox->SetEnabled( 226 settings.FindBool("leave_mail_on_server")); 227 } 228 229 if (fBodyDownloadConfig != NULL) 230 fBodyDownloadConfig->SetTo(settings); 231 } 232 233 234 void 235 MailProtocolConfigView::AddFlavor(const char* label) 236 { 237 if (fFlavorField != NULL) { 238 fFlavorField->Menu()->AddItem(new BMenuItem(label, NULL)); 239 240 if (fFlavorField->Menu()->FindMarked() == NULL) 241 fFlavorField->Menu()->ItemAt(0)->SetMarked(true); 242 } 243 } 244 245 246 void 247 MailProtocolConfigView::AddAuthMethod(const char* label, bool needUserPassword) 248 { 249 if (fAuthenticationField != NULL) { 250 fAuthenticationField->Menu()->AddItem(new BMenuItem(label, 251 new BMessage(needUserPassword 252 ? kMsgNeedPassword : kMsgNoPassword))); 253 254 if (fAuthenticationField->Menu()->FindMarked() == NULL) { 255 BMenuItem* item = fAuthenticationField->Menu()->ItemAt(0); 256 item->SetMarked(true); 257 MessageReceived(item->Message()); 258 } 259 } 260 } 261 262 263 BGridLayout* 264 MailProtocolConfigView::Layout() const 265 { 266 return (BGridLayout*)BView::GetLayout(); 267 } 268 269 270 status_t 271 MailProtocolConfigView::SaveInto(BMailAddOnSettings& settings) const 272 { 273 if (fHostControl != NULL) { 274 int32 port = -1; 275 BString hostName = fHostControl->Text(); 276 if (hostName.FindFirst(':') > -1) { 277 port = atol(hostName.String() + hostName.FindFirst(':') + 1); 278 hostName.Truncate(hostName.FindFirst(':')); 279 } 280 281 settings.SetString("server", hostName); 282 283 // since there is no need for the port option, remove it here 284 if (port != -1) 285 settings.SetInt32("port", port); 286 else 287 settings.RemoveName("port"); 288 } else { 289 settings.RemoveName("server"); 290 settings.RemoveName("port"); 291 } 292 293 if (fUserControl != NULL) 294 settings.SetString("username", fUserControl->Text()); 295 else 296 settings.RemoveName("username"); 297 298 // remove old unencrypted passwords 299 settings.RemoveName("password"); 300 301 if (fPasswordControl != NULL) 302 set_passwd(&settings, "cpasswd", fPasswordControl->Text()); 303 else 304 settings.RemoveName("cpasswd"); 305 306 _StoreIndexOfMarked(settings, "flavor", fFlavorField); 307 _StoreIndexOfMarked(settings, "auth_method", fAuthenticationField); 308 309 _StoreCheckBox(settings, "leave_mail_on_server", fLeaveOnServerCheckBox); 310 _StoreCheckBox(settings, "delete_remote_when_local", 311 fRemoveFromServerCheckBox); 312 313 if (fBodyDownloadConfig != NULL) 314 return fBodyDownloadConfig->SaveInto(settings); 315 316 return B_OK; 317 } 318 319 320 void 321 MailProtocolConfigView::AttachedToWindow() 322 { 323 if (fAuthenticationField != NULL) 324 fAuthenticationField->Menu()->SetTargetForItems(this); 325 326 if (fLeaveOnServerCheckBox != NULL) 327 fLeaveOnServerCheckBox->SetTarget(this); 328 } 329 330 331 void 332 MailProtocolConfigView::MessageReceived(BMessage* message) 333 { 334 switch (message->what) { 335 case kMsgNeedPassword: 336 _SetCredentialsEnabled(true); 337 break; 338 case kMsgNoPassword: 339 _SetCredentialsEnabled(false); 340 break; 341 342 case kMsgLeaveOnServer: 343 fRemoveFromServerCheckBox->SetEnabled( 344 message->FindInt32("be:value") == B_CONTROL_ON); 345 break; 346 } 347 } 348 349 350 BTextControl* 351 MailProtocolConfigView::_AddTextControl(BGridLayout* layout, const char* name, 352 const char* label) 353 { 354 BTextControl* control = new BTextControl(name, label, "", NULL); 355 control->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 356 357 int32 row = layout->CountRows(); 358 layout->AddItem(control->CreateLabelLayoutItem(), 0, row); 359 layout->AddItem(control->CreateTextViewLayoutItem(), 1, row); 360 return control; 361 } 362 363 364 BMenuField* 365 MailProtocolConfigView::_AddMenuField(BGridLayout* layout, const char* name, 366 const char* label) 367 { 368 BPopUpMenu* menu = new BPopUpMenu(""); 369 BMenuField* field = new BMenuField(name, label, menu); 370 field->SetAlignment(B_ALIGN_RIGHT); 371 372 int32 row = layout->CountRows(); 373 layout->AddItem(field->CreateLabelLayoutItem(), 0, row); 374 layout->AddItem(field->CreateMenuBarLayoutItem(), 1, row); 375 return field; 376 } 377 378 379 void 380 MailProtocolConfigView::_StoreIndexOfMarked(BMessage& message, const char* name, 381 BMenuField* field) const 382 { 383 int32 index = -1; 384 if (field != NULL && field->Menu() != NULL) { 385 BMenuItem* item = field->Menu()->FindMarked(); 386 if (item != NULL) 387 index = field->Menu()->IndexOf(item); 388 } 389 message.SetInt32(name, index); 390 } 391 392 393 void 394 MailProtocolConfigView::_StoreCheckBox(BMessage& message, const char* name, 395 BCheckBox* checkBox) const 396 { 397 bool value = checkBox != NULL && checkBox->Value() == B_CONTROL_ON; 398 if (value) 399 message.SetBool(name, value); 400 else 401 message.RemoveName(name); 402 } 403 404 405 void 406 MailProtocolConfigView::_SetCredentialsEnabled(bool enabled) 407 { 408 if (fUserControl != NULL && fPasswordControl != NULL) { 409 fUserControl->SetEnabled(enabled); 410 fPasswordControl->SetEnabled(enabled); 411 } 412 } 413 414 415 } // namespace BPrivate 416