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.
8 #include "AutoConfigView.h"
13 #include <Directory.h>
15 #include <FindDirectory.h>
16 #include <LayoutBuilder.h>
20 #include <PopUpMenu.h>
24 #include <MailSettings.h>
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "E-Mail"
31 AutoConfigView::AutoConfigView(AutoConfig
&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:"),
47 fPasswordView
= new BTextControl("password", B_TRANSLATE("Password:"),
49 fPasswordView
->TextView()->HideTyping(true);
51 fAccountNameView
= new BTextControl("account", B_TRANSLATE("Account name:"),
54 fNameView
= new BTextControl("name", B_TRANSLATE("Real name:"), "", NULL
);
56 struct passwd
* passwd
= getpwent();
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)
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
);
95 fEmailView
->SetTarget(this);
96 fEmailView
->MakeFocus(true);
101 AutoConfigView::MessageReceived(BMessage
*msg
)
104 case kEMailChangedMsg
:
106 BString text
= fLoginNameView
->Text();
109 fLoginNameView
->MakeFocus();
110 fLoginNameView
->TextView()->SelectAll();
112 text
= fAccountNameView
->Text();
114 fAccountNameView
->SetText(fEmailView
->Text());
118 BView::MessageReceived(msg
);
125 AutoConfigView::GetBasicAccountInfo(account_info
&info
)
127 status_t status
= B_OK
;
129 BString inboundProtocolName
= "";
130 BMenuItem
* item
= fInProtocolsField
->Menu()->FindMarked();
132 inboundProtocolName
= item
->Label();
133 item
->Message()->FindRef("protocol", &(info
.inboundProtocol
));
138 if (inboundProtocolName
.FindFirst("IMAP") >= 0)
139 info
.inboundType
= IMAP
;
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();
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
++) {
162 status_t status
= find_directory((i
== 0) ? B_USER_ADDONS_DIRECTORY
:
163 B_BEOS_ADDONS_DIRECTORY
, &path
);
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
);
179 msg
->AddRef("protocol", &protocolRef
);
181 item
->SetMarked(true);
185 // make imap default protocol if existing
186 BMenuItem
* imapItem
= menu
->FindItem("IMAP");
188 imapItem
->SetMarked(true);
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
++) {
204 status_t status
= find_directory(which
[i
], &path
);
208 path
.Append("mail_daemon");
209 path
.Append("outbound_protocols");
212 BEntry
entry(path
.Path());
213 if (entry
.Exists() && entry
.GetRef(ref
) == B_OK
)
217 return B_FILE_NOT_FOUND
;
222 AutoConfigView::_ExtractLocalPart(const char* email
)
224 const char* at
= strrchr(email
, '@');
225 return BString(email
, at
- email
);
230 AutoConfigView::_ProposeUsername()
232 const char* email
= fEmailView
->Text();
234 status_t status
= fAutoConfig
.GetInfoFromMailAddress(email
, &info
);
235 if (status
== B_OK
) {
236 BString localPart
= _ExtractLocalPart(email
);
237 switch (info
.username_pattern
) {
239 // username is the mail address
240 fLoginNameView
->SetText(email
);
243 // username is the local-part
244 fLoginNameView
->SetText(localPart
.String());
252 fLoginNameView
->SetText(email
);
258 AutoConfigView::IsValidMailAddress(BString email
)
260 int32 atPos
= email
.FindFirst("@");
264 email
.CopyInto(provider
, atPos
+ 1, email
.Length() - atPos
);
265 if (provider
.FindLast(".") < 0)
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
),
285 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
287 fInboundAccount
= true;
288 fOutboundAccount
= true;
291 BBox
* box
= new BBox("inbound");
292 box
->SetLabel(B_TRANSLATE("Incoming"));
296 if (info
.inboundType
== IMAP
)
297 serverName
= info
.providerInfo
.imap_server
;
299 serverName
= info
.providerInfo
.pop_server
;
301 BGridView
* grid
= new BGridView("inner");
302 grid
->GridLayout()->SetInsets(B_USE_DEFAULT_SPACING
);
305 fInboundNameView
= new BTextControl("inbound", B_TRANSLATE("Server Name:"),
306 serverName
, new BMessage(kServerChangedMsg
));
307 grid
->GridLayout()->AddItem(fInboundNameView
->CreateLabelLayoutItem(),
309 grid
->GridLayout()->AddItem(fInboundNameView
->CreateTextViewLayoutItem(),
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(),
324 grid
->GridLayout()->AddItem(fInboundAuthMenu
->CreateMenuBarLayoutItem(),
327 if (fInboundEncryptionMenu
!= NULL
) {
328 BMenuItem
*item
= NULL
;
329 if (info
.inboundType
== POP
) {
330 item
= fInboundEncryptionMenu
->Menu()->ItemAt(
331 info
.providerInfo
.ssl_pop
);
333 item
->SetMarked(true);
335 if (info
.inboundType
== IMAP
) {
336 item
= fInboundEncryptionMenu
->Menu()->ItemAt(
337 info
.providerInfo
.ssl_imap
);
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
)
354 box
= new BBox("outbound");
355 box
->SetLabel(B_TRANSLATE("Outgoing"));
358 grid
= new BGridView("inner");
359 grid
->GridLayout()->SetInsets(B_USE_DEFAULT_SPACING
);
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(),
368 grid
->GridLayout()->AddItem(fOutboundNameView
->CreateTextViewLayoutItem(),
373 _GetAuthEncrMenu(info
.outboundProtocol
, fOutboundAuthMenu
,
374 fOutboundEncryptionMenu
);
375 if (fOutboundAuthMenu
!= NULL
) {
376 BMenuItem
* item
= fOutboundAuthMenu
->Menu()->ItemAt(
377 info
.providerInfo
.authentification_smtp
);
379 item
->SetMarked(true);
380 fOutboundAuthItemStart
= item
;
382 grid
->GridLayout()->AddItem(fOutboundAuthMenu
->CreateLabelLayoutItem(),
384 grid
->GridLayout()->AddItem(
385 fOutboundAuthMenu
->CreateMenuBarLayoutItem(), 1, row
++);
387 if (fOutboundEncryptionMenu
!= NULL
) {
388 BMenuItem
* item
= fOutboundEncryptionMenu
->Menu()->ItemAt(
389 info
.providerInfo
.ssl_smtp
);
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
)
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
);
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();
425 info
.providerInfo
.ssl_imap
426 = fInboundEncryptionMenu
->Menu()->IndexOf(item
);
430 info
.providerInfo
.pop_server
= fInboundNameView
->Text();
431 BMenuItem
* item
= NULL
;
432 if (fInboundAuthMenu
!= NULL
) {
433 item
= fInboundAuthMenu
->Menu()->FindMarked();
435 info
.providerInfo
.authentification_pop
436 = fInboundAuthMenu
->Menu()->IndexOf(item
);
439 if (fInboundEncryptionMenu
!= NULL
) {
440 item
= fInboundEncryptionMenu
->Menu()->FindMarked();
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();
452 info
.providerInfo
.authentification_smtp
453 = fOutboundAuthMenu
->Menu()->IndexOf(item
);
457 if (fOutboundEncryptionMenu
!= NULL
) {
458 item
= fOutboundEncryptionMenu
->Menu()->FindMarked();
460 info
.providerInfo
.ssl_smtp
461 = fOutboundEncryptionMenu
->Menu()->IndexOf(item
);
464 _DetectMenuChanges();
469 ServerSettingsView::_DetectMenuChanges()
471 bool changed
= _HasMarkedChanged(fInboundAuthMenu
, fInboundAuthItemStart
)
472 | _HasMarkedChanged(fInboundEncryptionMenu
, fInboundEncrItemStart
)
473 | _HasMarkedChanged(fOutboundAuthMenu
, fOutboundAuthItemStart
)
474 | _HasMarkedChanged(fOutboundEncryptionMenu
, fOutboundEncrItemStart
);
477 BMessage
msg(kServerChangedMsg
);
478 BMessenger
messenger(NULL
, Window()->Looper());
479 messenger
.SendMessage(&msg
);
485 ServerSettingsView::_HasMarkedChanged(BMenuField
* field
,
486 BMenuItem
* originalItem
)
489 BMenuItem
*item
= field
->Menu()->FindMarked();
490 if (item
!= originalItem
)
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
);