xref: /haiku/src/kits/mail/ProtocolConfigView.cpp (revision 81ec973846ea4816c53ed8901822e43c8b06878d)
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