2 * Copyright 2003-2004 Waldemar Kornewald. All rights reserved.
3 * Copyright 2017 Haiku, Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
7 //-----------------------------------------------------------------------
8 // GeneralAddon saves the loaded settings.
9 // GeneralView saves the current settings.
10 //-----------------------------------------------------------------------
12 #include "GeneralAddon.h"
14 #include "InterfaceUtils.h"
15 #include "MessageDriverSettingsUtils.h"
19 #include <MenuField.h>
21 #include <LayoutBuilder.h>
22 #include <PopUpMenu.h>
23 #include <StringView.h>
29 static const uint32 kMsgSelectDevice
= 'SELD';
30 static const uint32 kMsgSelectAuthenticator
= 'SELA';
33 static const char *kLabelGeneral
= "General";
34 static const char *kLabelDevice
= "Device: ";
35 static const char *kLabelNoDevicesFound
= "No Devices Found!";
36 static const char *kLabelAuthenticator
= "Login: ";
37 static const char *kLabelNoAuthenticatorsFound
= "No Authenticators Found!";
38 static const char *kLabelName
= "Username: ";
39 static const char *kLabelPassword
= "Password: ";
40 static const char *kLabelSavePassword
= "Save Password";
41 static const char *kLabelNone
= "None";
43 // string constants for information saved in the settings message
44 static const char *kGeneralTabAuthentication
= "Authentication";
45 static const char *kGeneralTabAuthenticators
= "Authenticators";
48 #define DEFAULT_AUTHENTICATOR "PAP"
49 // this authenticator is selected by default when creating a new interface
52 GeneralAddon::GeneralAddon(BMessage
*addons
)
53 : DialUpAddon(addons
),
55 fAuthenticatorsCount(0),
63 GeneralAddon::~GeneralAddon()
69 GeneralAddon::NeedsAuthenticationRequest() const
71 return fGeneralView
->AuthenticatorName();
76 GeneralAddon::FindDevice(const BString
& moduleName
) const
79 for(int32 index
= 0; Addons()->FindPointer(DUN_DEVICE_ADDON_TYPE
, index
,
80 reinterpret_cast<void**>(&addon
)) == B_OK
; index
++)
81 if(addon
&& moduleName
== addon
->KernelModuleName())
89 GeneralAddon::LoadSettings(BMessage
*settings
, BMessage
*profile
, bool isNew
)
93 fDeviceName
= fUsername
= fPassword
= "";
95 fAuthenticatorsCount
= 0;
100 fGeneralView
->Reload();
101 // reset all views (empty settings)
103 if(!settings
|| !profile
|| isNew
)
106 if(!LoadDeviceSettings())
109 if(!LoadAuthenticationSettings())
113 fGeneralView
->Reload();
114 // reload new settings
121 GeneralAddon::LoadDeviceSettings()
125 if(!FindMessageParameter(PPP_DEVICE_KEY
, *fSettings
, &device
, &index
))
127 // TODO: tell user that device specification is missing
129 if(device
.FindString(MDSU_VALUES
, &fDeviceName
) != B_OK
)
131 // TODO: tell user that device specification is missing
133 device
.AddBool(MDSU_VALID
, true);
134 fSettings
->ReplaceMessage(MDSU_PARAMETERS
, index
, &device
);
136 fDeviceAddon
= FindDevice(fDeviceName
);
140 return fDeviceAddon
->LoadSettings(fSettings
, fProfile
, false);
145 GeneralAddon::LoadAuthenticationSettings()
147 // we only handle the profile (although settings could contain different data)
149 BMessage authentication
, item
;
151 if(!FindMessageParameter(PPP_AUTHENTICATOR_KEY
, *fProfile
, &item
, &itemIndex
))
154 // find authenticators (though we load all authenticators, we only use one)
156 for(int32 index
= 0; item
.FindString(MDSU_VALUES
, index
, &name
) == B_OK
; index
++) {
157 BMessage authenticator
;
158 if(!GetAuthenticator(name
, &authenticator
))
160 // fatal error: we do not know how to handle this authenticator
162 MarkAuthenticatorAsValid(name
);
163 authentication
.AddString(kGeneralTabAuthenticators
, name
);
164 ++fAuthenticatorsCount
;
167 fSettings
->AddMessage(kGeneralTabAuthentication
, &authentication
);
169 bool hasUsername
= false;
170 // a username must be present
172 // load username and password
174 int32 parameterIndex
= 0;
175 if(FindMessageParameter("User", item
, ¶meter
, ¶meterIndex
)
176 && parameter
.FindString(MDSU_VALUES
, &fUsername
) == B_OK
) {
178 parameter
.AddBool(MDSU_VALID
, true);
179 item
.ReplaceMessage(MDSU_PARAMETERS
, parameterIndex
, ¶meter
);
183 if(FindMessageParameter("Password", item
, ¶meter
, ¶meterIndex
)
184 && parameter
.FindString(MDSU_VALUES
, &fPassword
) == B_OK
) {
186 parameter
.AddBool(MDSU_VALID
, true);
187 item
.ReplaceMessage(MDSU_PARAMETERS
, parameterIndex
, ¶meter
);
190 // tell DUN whether everything is valid
192 item
.AddBool(MDSU_VALID
, true);
194 fProfile
->ReplaceMessage(MDSU_PARAMETERS
, itemIndex
, &item
);
201 GeneralAddon::HasTemporaryProfile() const
203 return fGeneralView
->HasTemporaryProfile();
208 GeneralAddon::IsModified(bool *settings
, bool *profile
) const
211 *settings
= *profile
= false;
215 bool deviceSettings
, authenticationSettings
, deviceProfile
, authenticationProfile
;
217 IsDeviceModified(&deviceSettings
, &deviceProfile
);
218 IsAuthenticationModified(&authenticationSettings
, &authenticationProfile
);
220 *settings
= (deviceSettings
|| authenticationSettings
);
221 *profile
= (deviceProfile
|| authenticationProfile
);
226 GeneralAddon::IsDeviceModified(bool *settings
, bool *profile
) const
228 fGeneralView
->IsDeviceModified(settings
, profile
);
233 GeneralAddon::IsAuthenticationModified(bool *settings
, bool *profile
) const
235 // currently we only support selecting one authenticator
236 if(fAuthenticatorsCount
== 0)
237 *settings
= fGeneralView
->AuthenticatorName();
239 BMessage authentication
;
240 if(fSettings
->FindMessage(kGeneralTabAuthentication
, &authentication
) != B_OK
) {
241 *settings
= *profile
= false;
246 BString authenticator
;
247 if(authentication
.FindString(kGeneralTabAuthenticators
,
248 &authenticator
) != B_OK
) {
249 *settings
= *profile
= false;
254 *settings
= (!fGeneralView
->AuthenticatorName()
255 || authenticator
!= fGeneralView
->AuthenticatorName());
258 *profile
= (*settings
|| fUsername
!= fGeneralView
->Username()
259 || (fPassword
!= fGeneralView
->Password() && fHasPassword
)
260 || fHasPassword
!= fGeneralView
->DoesSavePassword());
265 GeneralAddon::SaveSettings(BMessage
*settings
, BMessage
*profile
, bool saveTemporary
)
267 if(!fSettings
|| !settings
|| !fGeneralView
->DeviceName())
269 // TODO: tell user that a device is needed (if we fail because of this)
271 if(!fGeneralView
->DeviceAddon() || !fGeneralView
->DeviceAddon()->SaveSettings(
272 settings
, profile
, saveTemporary
))
275 if(fGeneralView
->AuthenticatorName()) {
276 BMessage authenticator
;
277 authenticator
.AddString(MDSU_NAME
, PPP_AUTHENTICATOR_KEY
);
278 authenticator
.AddString(MDSU_VALUES
, fGeneralView
->AuthenticatorName());
279 settings
->AddMessage(MDSU_PARAMETERS
, &authenticator
);
282 username
.AddString(MDSU_NAME
, "User");
283 username
.AddString(MDSU_VALUES
, fGeneralView
->Username());
284 authenticator
.AddMessage(MDSU_PARAMETERS
, &username
);
286 if(saveTemporary
|| fGeneralView
->DoesSavePassword()) {
287 // save password, too
289 password
.AddString(MDSU_NAME
, "Password");
290 password
.AddString(MDSU_VALUES
, fGeneralView
->Password());
291 authenticator
.AddMessage(MDSU_PARAMETERS
, &password
);
294 profile
->AddMessage(MDSU_PARAMETERS
, &authenticator
);
302 GeneralAddon::GetPreferredSize(float *width
, float *height
) const
305 if(Addons()->FindRect(DUN_TAB_VIEW_RECT
, &rect
) != B_OK
)
306 rect
.Set(0, 0, 200, 300);
307 // set default values
310 *width
= rect
.Width();
312 *height
= rect
.Height();
319 GeneralAddon::CreateView()
322 fGeneralView
= new GeneralView(this);
323 fGeneralView
->Reload();
331 GeneralAddon::GetAuthenticator(const BString
& moduleName
, BMessage
*entry
) const
337 for(int32 index
= 0; Addons()->FindMessage(DUN_AUTHENTICATOR_ADDON_TYPE
, index
,
338 entry
) == B_OK
; index
++) {
339 entry
->FindString("KernelModuleName", &name
);
340 if (name
== moduleName
)
349 GeneralAddon::MarkAuthenticatorAsValid(const BString
& moduleName
)
351 BMessage authenticator
;
355 for(; FindMessageParameter(PPP_AUTHENTICATOR_KEY
, *fSettings
, &authenticator
,
357 authenticator
.FindString("KernelModuleName", &name
);
358 if(name
== moduleName
) {
359 authenticator
.AddBool(MDSU_VALID
, true);
360 fSettings
->ReplaceMessage(MDSU_PARAMETERS
, index
, &authenticator
);
369 GeneralView::GeneralView(GeneralAddon
*addon
)
370 : BView(kLabelGeneral
, 0),
373 fDeviceBox
= new BBox("Device");
374 Addon()->Addons()->AddFloat(DUN_DEVICE_VIEW_WIDTH
,
375 fDeviceBox
->Bounds().Width() - 10); // FIXME: remove
377 fDeviceField
= new BMenuField("Device",
378 kLabelDevice
, new BPopUpMenu(kLabelNoDevicesFound
));
379 fDeviceField
->Menu()->SetRadioMode(true);
381 fDeviceBox
->SetLabel(fDeviceField
);
383 fAuthenticatorField
= new BMenuField("Authenticator",
384 kLabelAuthenticator
, new BPopUpMenu(kLabelNoAuthenticatorsFound
));
385 fAuthenticatorField
->Menu()->SetRadioMode(true);
388 fUsername
= new BTextControl("username", kLabelName
, NULL
, NULL
);
389 fPassword
= new BTextControl("password", kLabelPassword
, NULL
, NULL
);
390 fPassword
->TextView()->HideTyping(true);
392 fSavePassword
= new BCheckBox("SavePassword", kLabelSavePassword
, NULL
);
394 BLayoutBuilder::Group
<>(this, B_VERTICAL
, B_USE_HALF_ITEM_SPACING
)
395 .SetInsets(B_USE_HALF_ITEM_INSETS
)
396 .AddGroup(B_HORIZONTAL
)
400 .Add(fAuthenticatorField
)
409 GeneralView::~GeneralView()
415 GeneralView::Reload()
419 BMenuItem
*item
= NULL
;
420 for(int32 index
= 0; index
< fDeviceField
->Menu()->CountItems(); index
++) {
421 item
= fDeviceField
->Menu()->ItemAt(index
);
422 if(item
&& item
->Message() && item
->Message()->FindPointer("Addon",
423 reinterpret_cast<void**>(&fDeviceAddon
)) == B_OK
424 && fDeviceAddon
== Addon()->DeviceAddon())
428 if(fDeviceAddon
&& fDeviceAddon
== Addon()->DeviceAddon())
429 item
->SetMarked(true);
430 else if(Addon()->IsNew() && fDeviceField
->Menu()->CountItems() > 0) {
431 item
= fDeviceField
->Menu()->ItemAt(0);
432 item
->SetMarked(true);
433 item
->Message()->FindPointer("Addon", reinterpret_cast<void**>(&fDeviceAddon
));
434 fDeviceAddon
->LoadSettings(Addon()->Settings(), Addon()->Profile(), true);
437 item
= fDeviceField
->Menu()->FindMarked();
439 item
->SetMarked(false);
442 if(Addon()->CountAuthenticators() > 0) {
443 BString kernelModule
, authenticator
;
444 BMessage authentication
;
445 if(Addon()->Settings()->FindMessage(kGeneralTabAuthentication
,
446 &authentication
) == B_OK
)
447 authentication
.FindString(kGeneralTabAuthenticators
, &authenticator
);
448 BMenu
*menu
= fAuthenticatorField
->Menu();
449 for(int32 index
= 0; index
< menu
->CountItems(); index
++) {
450 item
= menu
->ItemAt(index
);
451 if(item
&& item
->Message()
452 && item
->Message()->FindString("KernelModuleName",
453 &kernelModule
) == B_OK
&& kernelModule
== authenticator
) {
454 item
->SetMarked(true);
458 } else if(Addon()->IsNew() && fAuthenticatorDefault
)
459 fAuthenticatorDefault
->SetMarked(true);
461 fAuthenticatorNone
->SetMarked(true);
463 fUsername
->SetText(Addon()->Username());
464 fPassword
->SetText(Addon()->Password());
465 fSavePassword
->SetValue(Addon()->HasPassword());
473 GeneralView::DeviceName() const
476 return fDeviceAddon
->KernelModuleName();
483 GeneralView::AuthenticatorName() const
485 BMenuItem
*marked
= fAuthenticatorField
->Menu()->FindMarked();
486 if(marked
&& marked
!= fAuthenticatorNone
)
487 return marked
->Message()->FindString("KernelModuleName");
494 GeneralView::IsDeviceModified(bool *settings
, bool *profile
) const
496 if(fDeviceAddon
!= Addon()->DeviceAddon())
497 *settings
= *profile
= true;
498 else if(fDeviceAddon
)
499 fDeviceAddon
->IsModified(settings
, profile
);
501 *settings
= *profile
= false;
506 GeneralView::AttachedToWindow()
508 SetViewColor(Parent()->ViewColor());
509 fDeviceField
->Menu()->SetTargetForItems(this);
510 fAuthenticatorField
->Menu()->SetTargetForItems(this);
511 fUsername
->SetTarget(this);
512 fPassword
->SetTarget(this);
517 GeneralView::MessageReceived(BMessage
*message
)
519 switch(message
->what
) {
520 case kMsgSelectDevice
:
521 if(message
->FindPointer("Addon", reinterpret_cast<void**>(&fDeviceAddon
))
525 if(fDeviceAddon
!= Addon()->DeviceAddon())
526 fDeviceAddon
->LoadSettings(Addon()->Settings(), Addon()->Profile(),
533 case kMsgSelectAuthenticator
:
538 BView::MessageReceived(message
);
544 GeneralView::ReloadDeviceView()
546 // first remove existing device view(s)
547 while (fDeviceBox
->CountChildren() > 1)
548 fDeviceBox
->RemoveChild(fDeviceBox
->ChildAt(1));
553 BView
* deviceView
= fDeviceAddon
->CreateView();
555 BLayoutBuilder::Group
<>(fDeviceBox
, B_VERTICAL
)
563 GeneralView::UpdateControls()
565 BMenu
*menu
= fAuthenticatorField
->Menu();
566 int32 index
= menu
->IndexOf(menu
->FindMarked());
568 fAuthenticatorNone
->SetMarked(true);
571 fUsername
->SetEnabled(false);
572 fPassword
->SetEnabled(false);
573 fSavePassword
->SetEnabled(false);
575 fUsername
->SetEnabled(true);
576 fPassword
->SetEnabled(true);
577 fSavePassword
->SetEnabled(true);
583 GeneralView::AddDevices()
585 AddAddonsToMenu(Addon()->Addons(), fDeviceField
->Menu(), DUN_DEVICE_ADDON_TYPE
,
591 GeneralView::AddAuthenticators()
593 fAuthenticatorDefault
= NULL
;
594 fAuthenticatorNone
= new BMenuItem(kLabelNone
,
595 new BMessage(kMsgSelectAuthenticator
));
596 fAuthenticatorField
->Menu()->AddItem(fAuthenticatorNone
);
597 fAuthenticatorNone
->SetMarked(true);
598 fAuthenticatorField
->Menu()->AddSeparatorItem();
603 Addon()->Addons()->FindMessage(DUN_AUTHENTICATOR_ADDON_TYPE
, index
,
604 &addon
) == B_OK
; index
++) {
605 BMessage
*message
= new BMessage(kMsgSelectAuthenticator
);
606 message
->AddString("KernelModuleName", addon
.FindString("KernelModuleName"));
608 BString name
, technicalName
, friendlyName
;
609 bool hasTechnicalName
610 = (addon
.FindString("TechnicalName", &technicalName
) == B_OK
);
612 = (addon
.FindString("FriendlyName", &friendlyName
) == B_OK
);
613 if(hasTechnicalName
) {
614 name
<< technicalName
;
618 if(hasFriendlyName
) {
619 name
<< friendlyName
;
624 int32 insertAt
= FindNextMenuInsertionIndex(fAuthenticatorField
->Menu(),
626 item
= new BMenuItem(name
.String(), message
);
627 if(hasTechnicalName
&& technicalName
== DEFAULT_AUTHENTICATOR
)
628 fAuthenticatorDefault
= item
;
629 fAuthenticatorField
->Menu()->AddItem(item
, insertAt
);