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 fLeaveOnServerCheckBox(NULL), 123 fRemoveFromServerCheckBox(NULL), 124 fBodyDownloadConfig(NULL) 125 { 126 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 127 128 BGridLayout* layout = new BGridLayout(0.f); 129 SetLayout(layout); 130 131 if ((optionsMask & B_MAIL_PROTOCOL_HAS_HOSTNAME) != 0) { 132 fHostControl = _AddTextControl(layout, "host", 133 B_TRANSLATE("Mail server:")); 134 } 135 if ((optionsMask & B_MAIL_PROTOCOL_HAS_USERNAME) != 0) { 136 fUserControl = _AddTextControl(layout, "user", 137 B_TRANSLATE("Username:")); 138 } 139 140 if ((optionsMask & B_MAIL_PROTOCOL_HAS_PASSWORD) != 0) { 141 fPasswordControl = _AddTextControl(layout, "pass", 142 B_TRANSLATE("Password:")); 143 fPasswordControl->TextView()->HideTyping(true); 144 } 145 146 if ((optionsMask & B_MAIL_PROTOCOL_HAS_FLAVORS) != 0) { 147 fFlavorField = _AddMenuField(layout, "flavor", 148 B_TRANSLATE("Connection type:")); 149 } 150 151 if ((optionsMask & B_MAIL_PROTOCOL_HAS_AUTH_METHODS) != 0) { 152 fAuthenticationField = _AddMenuField(layout, "auth_method", 153 B_TRANSLATE("Login type:")); 154 } 155 156 if ((optionsMask & B_MAIL_PROTOCOL_CAN_LEAVE_MAIL_ON_SERVER) != 0) { 157 fLeaveOnServerCheckBox = new BCheckBox("leave_mail_on_server", 158 B_TRANSLATE("Leave mail on server"), 159 new BMessage(kMsgLeaveOnServer)); 160 layout->AddView(fLeaveOnServerCheckBox, 0, layout->CountRows(), 2); 161 162 fRemoveFromServerCheckBox = new BCheckBox("delete_remote_when_local", 163 B_TRANSLATE("Remove mail from server when deleted"), NULL); 164 fRemoveFromServerCheckBox->SetEnabled(false); 165 layout->AddView(fRemoveFromServerCheckBox, 0, layout->CountRows(), 2); 166 } 167 168 if ((optionsMask & B_MAIL_PROTOCOL_PARTIAL_DOWNLOAD) != 0) { 169 fBodyDownloadConfig = new BodyDownloadConfigView(); 170 layout->AddView(fBodyDownloadConfig, 0, layout->CountRows(), 2); 171 } 172 } 173 174 175 MailProtocolConfigView::~MailProtocolConfigView() 176 { 177 } 178 179 180 void 181 MailProtocolConfigView::SetTo(const BMailProtocolSettings& settings) 182 { 183 BString host = settings.FindString("server"); 184 if (settings.HasInt32("port")) 185 host << ':' << settings.FindInt32("port"); 186 187 if (fHostControl != NULL) 188 fHostControl->SetText(host.String()); 189 if (fUserControl != NULL) 190 fUserControl->SetText(settings.FindString("username")); 191 192 if (fPasswordControl != NULL) { 193 char* password = get_passwd(&settings, "cpasswd"); 194 if (password != NULL) { 195 fPasswordControl->SetText(password); 196 delete[] password; 197 } else 198 fPasswordControl->SetText(settings.FindString("password")); 199 } 200 201 if (settings.HasInt32("flavor") && fFlavorField != NULL) { 202 if (BMenuItem* item = fFlavorField->Menu()->ItemAt( 203 settings.FindInt32("flavor"))) 204 item->SetMarked(true); 205 } 206 207 if (settings.HasInt32("auth_method") && fAuthenticationField != NULL) { 208 if (BMenuItem* item = fAuthenticationField->Menu()->ItemAt( 209 settings.FindInt32("auth_method"))) { 210 item->SetMarked(true); 211 _SetCredentialsEnabled(item->Command() != kMsgNoPassword); 212 } 213 } 214 215 if (fLeaveOnServerCheckBox != NULL) { 216 fLeaveOnServerCheckBox->SetValue(settings.FindBool( 217 "leave_mail_on_server") ? B_CONTROL_ON : B_CONTROL_OFF); 218 } 219 220 if (fRemoveFromServerCheckBox != NULL) { 221 fRemoveFromServerCheckBox->SetValue(settings.FindBool( 222 "delete_remote_when_local") ? B_CONTROL_ON : B_CONTROL_OFF); 223 fRemoveFromServerCheckBox->SetEnabled( 224 settings.FindBool("leave_mail_on_server")); 225 } 226 227 if (fBodyDownloadConfig != NULL) 228 fBodyDownloadConfig->SetTo(settings); 229 } 230 231 232 void 233 MailProtocolConfigView::AddFlavor(const char* label) 234 { 235 if (fFlavorField != NULL) { 236 fFlavorField->Menu()->AddItem(new BMenuItem(label, NULL)); 237 238 if (fFlavorField->Menu()->FindMarked() == NULL) 239 fFlavorField->Menu()->ItemAt(0)->SetMarked(true); 240 } 241 } 242 243 244 void 245 MailProtocolConfigView::AddAuthMethod(const char* label, bool needUserPassword) 246 { 247 if (fAuthenticationField != NULL) { 248 fAuthenticationField->Menu()->AddItem(new BMenuItem(label, 249 new BMessage(needUserPassword 250 ? kMsgLeaveOnServer : kMsgNoPassword))); 251 252 if (fAuthenticationField->Menu()->FindMarked() == NULL) { 253 BMenuItem* item = fAuthenticationField->Menu()->ItemAt(0); 254 item->SetMarked(true); 255 MessageReceived(item->Message()); 256 } 257 } 258 } 259 260 261 BGridLayout* 262 MailProtocolConfigView::Layout() const 263 { 264 return (BGridLayout*)BView::GetLayout(); 265 } 266 267 268 status_t 269 MailProtocolConfigView::SaveInto(BMailAddOnSettings& settings) const 270 { 271 if (fHostControl != NULL) { 272 int32 port = -1; 273 BString hostName = fHostControl->Text(); 274 if (hostName.FindFirst(':') > -1) { 275 port = atol(hostName.String() + hostName.FindFirst(':') + 1); 276 hostName.Truncate(hostName.FindFirst(':')); 277 } 278 279 settings.SetString("server", hostName); 280 281 // since there is no need for the port option, remove it here 282 if (port != -1) 283 settings.SetInt32("port", port); 284 else 285 settings.RemoveName("port"); 286 } else { 287 settings.RemoveName("server"); 288 settings.RemoveName("port"); 289 } 290 291 if (fUserControl != NULL) 292 settings.SetString("username", fUserControl->Text()); 293 else 294 settings.RemoveName("username"); 295 296 // remove old unencrypted passwords 297 settings.RemoveName("password"); 298 299 if (fPasswordControl != NULL) 300 set_passwd(&settings, "cpasswd", fPasswordControl->Text()); 301 else 302 settings.RemoveName("cpasswd"); 303 304 _StoreIndexOfMarked(settings, "flavor", fFlavorField); 305 _StoreIndexOfMarked(settings, "auth_method", fAuthenticationField); 306 307 _StoreCheckBox(settings, "leave_mail_on_server", fLeaveOnServerCheckBox); 308 _StoreCheckBox(settings, "delete_remote_when_local", 309 fRemoveFromServerCheckBox); 310 311 if (fBodyDownloadConfig != NULL) 312 return fBodyDownloadConfig->SaveInto(settings); 313 314 return B_OK; 315 } 316 317 318 void 319 MailProtocolConfigView::AttachedToWindow() 320 { 321 if (fAuthenticationField != NULL) 322 fAuthenticationField->Menu()->SetTargetForItems(this); 323 324 if (fLeaveOnServerCheckBox != NULL) 325 fLeaveOnServerCheckBox->SetTarget(this); 326 } 327 328 329 void 330 MailProtocolConfigView::MessageReceived(BMessage* message) 331 { 332 switch (message->what) { 333 case kMsgNeedPassword: 334 _SetCredentialsEnabled(true); 335 break; 336 case kMsgNoPassword: 337 _SetCredentialsEnabled(false); 338 break; 339 340 case kMsgLeaveOnServer: 341 fRemoveFromServerCheckBox->SetEnabled( 342 message->FindInt32("be:value") == B_CONTROL_ON); 343 break; 344 } 345 } 346 347 348 BTextControl* 349 MailProtocolConfigView::_AddTextControl(BGridLayout* layout, const char* name, 350 const char* label) 351 { 352 BTextControl* control = new BTextControl(name, label, "", NULL); 353 int32 row = layout->CountRows(); 354 layout->AddItem(control->CreateLabelLayoutItem(), 0, row); 355 layout->AddItem(control->CreateTextViewLayoutItem(), 1, row); 356 return control; 357 } 358 359 360 BMenuField* 361 MailProtocolConfigView::_AddMenuField(BGridLayout* layout, const char* name, 362 const char* label) 363 { 364 BPopUpMenu* menu = new BPopUpMenu(""); 365 BMenuField* field = new BMenuField(name, label, menu); 366 int32 row = layout->CountRows(); 367 layout->AddItem(field->CreateLabelLayoutItem(), 0, row); 368 layout->AddItem(field->CreateMenuBarLayoutItem(), 1, row); 369 return field; 370 } 371 372 373 void 374 MailProtocolConfigView::_StoreIndexOfMarked(BMessage& message, const char* name, 375 BMenuField* field) const 376 { 377 int32 index = -1; 378 if (field != NULL && field->Menu() != NULL) { 379 BMenuItem* item = field->Menu()->FindMarked(); 380 if (item != NULL) 381 index = field->Menu()->IndexOf(item); 382 } 383 message.SetInt32(name, index); 384 } 385 386 387 void 388 MailProtocolConfigView::_StoreCheckBox(BMessage& message, const char* name, 389 BCheckBox* checkBox) const 390 { 391 bool value = checkBox != NULL && checkBox->Value() == B_CONTROL_ON; 392 if (value) 393 message.SetBool(name, value); 394 else 395 message.RemoveName(name); 396 } 397 398 399 void 400 MailProtocolConfigView::_SetCredentialsEnabled(bool enabled) 401 { 402 if (fUserControl != NULL && fPasswordControl != NULL) { 403 fUserControl->SetEnabled(enabled); 404 fPasswordControl->SetEnabled(enabled); 405 } 406 } 407 408 409 } // namespace BPrivate 410