BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / preferences / mail / AutoConfigView.cpp
blobc9ec5454aefed58ba241e366a69c4365ab9312b2
1 /*
2 * Copyright 2007-2015, Haiku, Inc. All rights reserved.
3 * Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de>
4 * Distributed under the terms of the MIT License.
5 */
8 #include "AutoConfigView.h"
10 #include <pwd.h>
12 #include <Catalog.h>
13 #include <Directory.h>
14 #include <Entry.h>
15 #include <FindDirectory.h>
16 #include <LayoutBuilder.h>
17 #include <Message.h>
18 #include <MenuItem.h>
19 #include <Path.h>
20 #include <PopUpMenu.h>
21 #include <String.h>
22 #include <Window.h>
24 #include <MailSettings.h>
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "E-Mail"
31 AutoConfigView::AutoConfigView(AutoConfig &config)
33 BBox("auto config"),
34 fAutoConfig(config)
36 // Search for SMTP entry_ref
37 _GetSMTPAddOnRef(&fSMTPAddOnRef);
39 fInProtocolsField = new BMenuField(NULL, NULL, _SetupProtocolMenu());
41 fEmailView = new BTextControl("email", B_TRANSLATE("E-mail address:"),
42 "", new BMessage(kEMailChangedMsg));
44 fLoginNameView = new BTextControl("login", B_TRANSLATE("Login name:"),
45 "", NULL);
47 fPasswordView = new BTextControl("password", B_TRANSLATE("Password:"),
48 "", NULL);
49 fPasswordView->TextView()->HideTyping(true);
51 fAccountNameView = new BTextControl("account", B_TRANSLATE("Account name:"),
52 "", NULL);
54 fNameView = new BTextControl("name", B_TRANSLATE("Real name:"), "", NULL);
56 struct passwd* passwd = getpwent();
57 if (passwd != NULL)
58 fNameView->SetText(passwd->pw_gecos);
60 AddChild(BLayoutBuilder::Grid<>()
61 .SetInsets(B_USE_DEFAULT_SPACING)
62 .SetSpacing(B_USE_HALF_ITEM_SPACING, B_USE_HALF_ITEM_SPACING)
64 .Add(fInProtocolsField->CreateLabelLayoutItem(), 0, 0)
65 .Add(fInProtocolsField->CreateMenuBarLayoutItem(), 1, 0)
67 .Add(fEmailView->CreateLabelLayoutItem(), 0, 1)
68 .Add(fEmailView->CreateTextViewLayoutItem(), 1, 1)
70 .Add(fLoginNameView->CreateLabelLayoutItem(), 0, 2)
71 .Add(fLoginNameView->CreateTextViewLayoutItem(), 1, 2)
73 .Add(fPasswordView->CreateLabelLayoutItem(), 0, 3)
74 .Add(fPasswordView->CreateTextViewLayoutItem(), 1, 3)
76 .Add(fAccountNameView->CreateLabelLayoutItem(), 0, 4)
77 .Add(fAccountNameView->CreateTextViewLayoutItem(), 1, 4)
79 .Add(fNameView->CreateLabelLayoutItem(), 0, 5)
80 .Add(fNameView->CreateTextViewLayoutItem(), 1, 5)
81 .View());
85 void
86 AutoConfigView::AttachedToWindow()
88 // Resize the view to fit the contents properly
89 BRect rect = Bounds();
90 float newHeight = fNameView->Frame().bottom + 20 + 2;
91 newHeight += InnerFrame().top;
92 ResizeTo(rect.Width(), newHeight);
94 AdoptParentColors();
95 fEmailView->SetTarget(this);
96 fEmailView->MakeFocus(true);
100 void
101 AutoConfigView::MessageReceived(BMessage *msg)
103 switch (msg->what) {
104 case kEMailChangedMsg:
106 BString text = fLoginNameView->Text();
107 if (text == "")
108 _ProposeUsername();
109 fLoginNameView->MakeFocus();
110 fLoginNameView->TextView()->SelectAll();
112 text = fAccountNameView->Text();
113 if (text == "")
114 fAccountNameView->SetText(fEmailView->Text());
115 break;
117 default:
118 BView::MessageReceived(msg);
119 break;
124 bool
125 AutoConfigView::GetBasicAccountInfo(account_info &info)
127 status_t status = B_OK;
129 BString inboundProtocolName = "";
130 BMenuItem* item = fInProtocolsField->Menu()->FindMarked();
131 if (item) {
132 inboundProtocolName = item->Label();
133 item->Message()->FindRef("protocol", &(info.inboundProtocol));
135 else
136 status = B_ERROR;
138 if (inboundProtocolName.FindFirst("IMAP") >= 0)
139 info.inboundType = IMAP;
140 else
141 info.inboundType = POP;
143 info.outboundProtocol = fSMTPAddOnRef;
144 info.name = fNameView->Text();
145 info.accountName = fAccountNameView->Text();
146 info.email = fEmailView->Text();
147 info.loginName = fLoginNameView->Text();
148 info.password = fPasswordView->Text();
150 return status;
154 BPopUpMenu*
155 AutoConfigView::_SetupProtocolMenu()
157 BPopUpMenu* menu = new BPopUpMenu(B_TRANSLATE("Choose Protocol"));
159 // TODO: use path finder!
160 for (int i = 0; i < 2; i++) {
161 BPath path;
162 status_t status = find_directory((i == 0) ? B_USER_ADDONS_DIRECTORY :
163 B_BEOS_ADDONS_DIRECTORY, &path);
164 if (status != B_OK)
165 return menu;
167 path.Append("mail_daemon");
168 path.Append("inbound_protocols");
170 BDirectory dir(path.Path());
171 entry_ref protocolRef;
172 while (dir.GetNextRef(&protocolRef) == B_OK)
174 BEntry entry(&protocolRef);
176 BMessage* msg = new BMessage(kProtokollChangedMsg);
177 BMenuItem* item = new BMenuItem(entry.Name(), msg);
178 menu->AddItem(item);
179 msg->AddRef("protocol", &protocolRef);
181 item->SetMarked(true);
185 // make imap default protocol if existing
186 BMenuItem* imapItem = menu->FindItem("IMAP");
187 if (imapItem)
188 imapItem->SetMarked(true);
190 return menu;
194 status_t
195 AutoConfigView::_GetSMTPAddOnRef(entry_ref *ref)
197 directory_which which[] = {
198 B_USER_ADDONS_DIRECTORY,
199 B_BEOS_ADDONS_DIRECTORY
202 for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) {
203 BPath path;
204 status_t status = find_directory(which[i], &path);
205 if (status != B_OK)
206 return B_ERROR;
208 path.Append("mail_daemon");
209 path.Append("outbound_protocols");
210 path.Append("SMTP");
212 BEntry entry(path.Path());
213 if (entry.Exists() && entry.GetRef(ref) == B_OK)
214 return B_OK;
217 return B_FILE_NOT_FOUND;
221 BString
222 AutoConfigView::_ExtractLocalPart(const char* email)
224 const char* at = strrchr(email, '@');
225 return BString(email, at - email);
229 void
230 AutoConfigView::_ProposeUsername()
232 const char* email = fEmailView->Text();
233 provider_info info;
234 status_t status = fAutoConfig.GetInfoFromMailAddress(email, &info);
235 if (status == B_OK) {
236 BString localPart = _ExtractLocalPart(email);
237 switch (info.username_pattern) {
238 case 0:
239 // username is the mail address
240 fLoginNameView->SetText(email);
241 break;
242 case 1:
243 // username is the local-part
244 fLoginNameView->SetText(localPart.String());
245 break;
246 case 2:
247 // do nothing
248 break;
251 else {
252 fLoginNameView->SetText(email);
257 bool
258 AutoConfigView::IsValidMailAddress(BString email)
260 int32 atPos = email.FindFirst("@");
261 if (atPos < 0)
262 return false;
263 BString provider;
264 email.CopyInto(provider, atPos + 1, email.Length() - atPos);
265 if (provider.FindLast(".") < 0)
266 return false;
267 return true;
271 // #pragma mark -
274 ServerSettingsView::ServerSettingsView(const account_info &info)
276 BGroupView("server", B_VERTICAL),
277 fInboundAccount(true),
278 fOutboundAccount(true),
279 fInboundAuthMenu(NULL),
280 fOutboundAuthMenu(NULL),
281 fInboundEncrItemStart(NULL),
282 fOutboundEncrItemStart(NULL),
283 fImageID(-1)
285 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
287 fInboundAccount = true;
288 fOutboundAccount = true;
290 // inbound
291 BBox* box = new BBox("inbound");
292 box->SetLabel(B_TRANSLATE("Incoming"));
293 AddChild(box);
295 BString serverName;
296 if (info.inboundType == IMAP)
297 serverName = info.providerInfo.imap_server;
298 else
299 serverName = info.providerInfo.pop_server;
301 BGridView* grid = new BGridView("inner");
302 grid->GridLayout()->SetInsets(B_USE_DEFAULT_SPACING);
303 box->AddChild(grid);
305 fInboundNameView = new BTextControl("inbound", B_TRANSLATE("Server Name:"),
306 serverName, new BMessage(kServerChangedMsg));
307 grid->GridLayout()->AddItem(fInboundNameView->CreateLabelLayoutItem(),
308 0, 0);
309 grid->GridLayout()->AddItem(fInboundNameView->CreateTextViewLayoutItem(),
310 1, 0);
312 int32 row = 1;
314 _GetAuthEncrMenu(info.inboundProtocol, fInboundAuthMenu,
315 fInboundEncryptionMenu);
316 if (fInboundAuthMenu != NULL) {
317 int authID = info.providerInfo.authentification_pop;
318 if (info.inboundType == POP)
319 fInboundAuthMenu->Menu()->ItemAt(authID)->SetMarked(true);
320 fInboundAuthItemStart = fInboundAuthMenu->Menu()->FindMarked();
322 grid->GridLayout()->AddItem(fInboundAuthMenu->CreateLabelLayoutItem(),
323 0, row);
324 grid->GridLayout()->AddItem(fInboundAuthMenu->CreateMenuBarLayoutItem(),
325 1, row++);
327 if (fInboundEncryptionMenu != NULL) {
328 BMenuItem *item = NULL;
329 if (info.inboundType == POP) {
330 item = fInboundEncryptionMenu->Menu()->ItemAt(
331 info.providerInfo.ssl_pop);
332 if (item != NULL)
333 item->SetMarked(true);
335 if (info.inboundType == IMAP) {
336 item = fInboundEncryptionMenu->Menu()->ItemAt(
337 info.providerInfo.ssl_imap);
338 if (item != NULL)
339 item->SetMarked(true);
341 fInboundEncrItemStart = fInboundEncryptionMenu->Menu()->FindMarked();
343 grid->GridLayout()->AddItem(
344 fInboundEncryptionMenu->CreateLabelLayoutItem(), 0, row);
345 grid->GridLayout()->AddItem(
346 fInboundEncryptionMenu->CreateMenuBarLayoutItem(), 1, row++);
348 grid->GridLayout()->AddItem(BSpaceLayoutItem::CreateGlue(), 0, row);
350 if (!fInboundAccount)
351 box->Hide();
353 // outbound
354 box = new BBox("outbound");
355 box->SetLabel(B_TRANSLATE("Outgoing"));
356 AddChild(box);
358 grid = new BGridView("inner");
359 grid->GridLayout()->SetInsets(B_USE_DEFAULT_SPACING);
360 box->AddChild(grid);
362 serverName = info.providerInfo.smtp_server;
363 fOutboundNameView = new BTextControl("outbound",
364 B_TRANSLATE("Server name:"), serverName.String(),
365 new BMessage(kServerChangedMsg));
366 grid->GridLayout()->AddItem(fOutboundNameView->CreateLabelLayoutItem(),
367 0, 0);
368 grid->GridLayout()->AddItem(fOutboundNameView->CreateTextViewLayoutItem(),
369 1, 0);
371 row = 1;
373 _GetAuthEncrMenu(info.outboundProtocol, fOutboundAuthMenu,
374 fOutboundEncryptionMenu);
375 if (fOutboundAuthMenu != NULL) {
376 BMenuItem* item = fOutboundAuthMenu->Menu()->ItemAt(
377 info.providerInfo.authentification_smtp);
378 if (item != NULL)
379 item->SetMarked(true);
380 fOutboundAuthItemStart = item;
382 grid->GridLayout()->AddItem(fOutboundAuthMenu->CreateLabelLayoutItem(),
383 0, row);
384 grid->GridLayout()->AddItem(
385 fOutboundAuthMenu->CreateMenuBarLayoutItem(), 1, row++);
387 if (fOutboundEncryptionMenu != NULL) {
388 BMenuItem* item = fOutboundEncryptionMenu->Menu()->ItemAt(
389 info.providerInfo.ssl_smtp);
390 if (item != NULL)
391 item->SetMarked(true);
392 fOutboundEncrItemStart = item;
394 grid->GridLayout()->AddItem(
395 fOutboundEncryptionMenu->CreateLabelLayoutItem(), 0, row);
396 grid->GridLayout()->AddItem(
397 fOutboundEncryptionMenu->CreateMenuBarLayoutItem(), 1, row++);
399 grid->GridLayout()->AddItem(BSpaceLayoutItem::CreateGlue(), 0, row);
401 if (!fOutboundAccount)
402 box->Hide();
406 ServerSettingsView::~ServerSettingsView()
408 // Remove manually, as their code may be located in an add-on
409 RemoveChild(fInboundAuthMenu);
410 RemoveChild(fInboundEncryptionMenu);
411 delete fInboundAuthMenu;
412 delete fInboundEncryptionMenu;
413 unload_add_on(fImageID);
417 void
418 ServerSettingsView::GetServerInfo(account_info& info)
420 if (info.inboundType == IMAP) {
421 info.providerInfo.imap_server = fInboundNameView->Text();
422 if (fInboundEncryptionMenu != NULL) {
423 BMenuItem* item = fInboundEncryptionMenu->Menu()->FindMarked();
424 if (item != NULL) {
425 info.providerInfo.ssl_imap
426 = fInboundEncryptionMenu->Menu()->IndexOf(item);
429 } else {
430 info.providerInfo.pop_server = fInboundNameView->Text();
431 BMenuItem* item = NULL;
432 if (fInboundAuthMenu != NULL) {
433 item = fInboundAuthMenu->Menu()->FindMarked();
434 if (item != NULL) {
435 info.providerInfo.authentification_pop
436 = fInboundAuthMenu->Menu()->IndexOf(item);
439 if (fInboundEncryptionMenu != NULL) {
440 item = fInboundEncryptionMenu->Menu()->FindMarked();
441 if (item != NULL) {
442 info.providerInfo.ssl_pop
443 = fInboundEncryptionMenu->Menu()->IndexOf(item);
447 info.providerInfo.smtp_server = fOutboundNameView->Text();
448 BMenuItem* item = NULL;
449 if (fOutboundAuthMenu != NULL) {
450 item = fOutboundAuthMenu->Menu()->FindMarked();
451 if (item != NULL) {
452 info.providerInfo.authentification_smtp
453 = fOutboundAuthMenu->Menu()->IndexOf(item);
457 if (fOutboundEncryptionMenu != NULL) {
458 item = fOutboundEncryptionMenu->Menu()->FindMarked();
459 if (item != NULL) {
460 info.providerInfo.ssl_smtp
461 = fOutboundEncryptionMenu->Menu()->IndexOf(item);
464 _DetectMenuChanges();
468 void
469 ServerSettingsView::_DetectMenuChanges()
471 bool changed = _HasMarkedChanged(fInboundAuthMenu, fInboundAuthItemStart)
472 | _HasMarkedChanged(fInboundEncryptionMenu, fInboundEncrItemStart)
473 | _HasMarkedChanged(fOutboundAuthMenu, fOutboundAuthItemStart)
474 | _HasMarkedChanged(fOutboundEncryptionMenu, fOutboundEncrItemStart);
476 if (changed) {
477 BMessage msg(kServerChangedMsg);
478 BMessenger messenger(NULL, Window()->Looper());
479 messenger.SendMessage(&msg);
484 bool
485 ServerSettingsView::_HasMarkedChanged(BMenuField* field,
486 BMenuItem* originalItem)
488 if (field != NULL) {
489 BMenuItem *item = field->Menu()->FindMarked();
490 if (item != originalItem)
491 return true;
493 return false;
497 void
498 ServerSettingsView::_GetAuthEncrMenu(entry_ref protocol,
499 BMenuField*& authField, BMenuField*& sslField)
501 BMailAccountSettings dummySettings;
502 BView *view = new BStringView("", "Not here!");//CreateConfigView(protocol, dummySettings.InboundSettings(),
503 // dummySettings, fImageId);
505 authField = (BMenuField*)view->FindView("auth_method");
506 sslField = (BMenuField*)view->FindView("flavor");
508 view->RemoveChild(authField);
509 view->RemoveChild(sslField);
510 delete view;