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
BodyDownloadConfigView()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
SetTo(const BMailProtocolSettings & settings)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
SaveInto(BMailAddOnSettings & settings) const84 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
MessageReceived(BMessage * msg)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
AttachedToWindow()106 BodyDownloadConfigView::AttachedToWindow()
107 {
108 fPartialBox->SetTarget(this);
109 fPartialBox->ResizeToPreferred();
110 }
111
112
113 // #pragma mark -
114
115
MailProtocolConfigView(uint32 optionsMask)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
~MailProtocolConfigView()177 MailProtocolConfigView::~MailProtocolConfigView()
178 {
179 }
180
181
182 void
SetTo(const BMailProtocolSettings & settings)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
AddFlavor(const char * label)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
AddAuthMethod(const char * label,bool needUserPassword)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*
Layout() const264 MailProtocolConfigView::Layout() const
265 {
266 return (BGridLayout*)BView::GetLayout();
267 }
268
269
270 status_t
SaveInto(BMailAddOnSettings & settings) const271 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
AttachedToWindow()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
MessageReceived(BMessage * message)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*
_AddTextControl(BGridLayout * layout,const char * name,const char * label)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*
_AddMenuField(BGridLayout * layout,const char * name,const char * label)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
_StoreIndexOfMarked(BMessage & message,const char * name,BMenuField * field) const380 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
_StoreCheckBox(BMessage & message,const char * name,BCheckBox * checkBox) const394 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
_SetCredentialsEnabled(bool enabled)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