diff --git a/src/tests/kits/net/DialUpPreflet/DialUpAddon.h b/src/tests/kits/net/DialUpPreflet/DialUpAddon.h index 21a206784c..9db79d36a2 100644 --- a/src/tests/kits/net/DialUpPreflet/DialUpAddon.h +++ b/src/tests/kits/net/DialUpPreflet/DialUpAddon.h @@ -28,7 +28,7 @@ class DialUpAddon { DialUpAddon(BMessage *addons) : fAddons(addons) {} virtual ~DialUpAddon() {} - const BMessage *Addons() const + BMessage *Addons() const { return fAddons; } virtual const char *FriendlyName() const @@ -47,6 +47,8 @@ class DialUpAddon { virtual bool LoadSettings(BMessage *settings, BMessage *profile, bool isNew) { return false; } + virtual bool HasTemporaryProfile() const + { return false; } virtual void IsModified(bool& settings, bool& profile) const { settings = profile = false; } virtual bool SaveSettings(BMessage *settings, BMessage *profile, diff --git a/src/tests/kits/net/DialUpPreflet/DialUpView.cpp b/src/tests/kits/net/DialUpPreflet/DialUpView.cpp index 889e31fb53..115c8338fb 100644 --- a/src/tests/kits/net/DialUpPreflet/DialUpView.cpp +++ b/src/tests/kits/net/DialUpPreflet/DialUpView.cpp @@ -10,7 +10,9 @@ #include "MessageDriverSettingsUtils.h" +// built-in add-ons #include "GeneralAddon.h" +#include "PPPoEAddon.h" #include @@ -107,12 +109,6 @@ DialUpView::DialUpView(BRect frame) tabViewRect.bottom -= fTabView->TabHeight(); fAddons.AddRect("TabViewRect", tabViewRect); -// BRect noInterfacesRect(rect); -// noInterfacesRect.top = rect.top + rect.Width() / 2; -// noInterfacesRect.bottom = noInterfacesRect.top + 15; -// fNoInterfacesStringView = new BStringView(noInterfacesRect, "NoInterfacesView", -// TEXT_NO_INTERFACE_SELECTED); - rect.top = rect.bottom + 15; rect.bottom = rect.top + 15; rect.right = rect.left + 200; @@ -162,10 +158,8 @@ DialUpView::AttachedToWindow() fInterfaceMenu->SetTargetForItems(this); fConnectButton->SetTarget(this); - if(fListener.InitCheck() != B_OK) { + if(fListener.InitCheck() != B_OK) (new BAlert(ERROR_TITLE, ERROR_NO_PPP_STACK, TEXT_OK))->Go(); -// be_app->PostMessage(B_QUIT_REQUESTED); - } } @@ -178,12 +172,15 @@ DialUpView::MessageReceived(BMessage *message) break; case MSG_CREATE_NEW: { + // TODO: open dialog asking for name AddInterface("New interface", true); if(fCurrentItem) fCurrentItem->SetMarked(true); } break; case MSG_DELETE_CURRENT: { + // TODO: remove file from disk + fInterfaceMenu->RemoveItem(fCurrentItem); delete fCurrentItem; fCurrentItem = NULL; @@ -278,7 +275,6 @@ DialUpView::SaveSettings(BMessage& settings, BMessage& profile, bool saveModifie if(!fCurrentItem) return false; - // create tabs for all registered and valid "Tab" add-ons DialUpAddon *addon; TemplateList addons; for(int32 index = 0; @@ -604,6 +600,10 @@ DialUpView::LoadAddons() GeneralAddon *generalAddon = new GeneralAddon(&fAddons); fAddons.AddPointer("Tab", generalAddon); fAddons.AddPointer("DeleteMe", generalAddon); + // "PPPoE" device + PPPoEAddon *pppoeAddon = new PPPoEAddon(&fAddons); + fAddons.AddPointer("Device", pppoeAddon); + fAddons.AddPointer("DeleteMe", pppoeAddon); // "PAP" authenticator BMessage addon; addon.AddString("KernelModuleName", "pap"); @@ -627,7 +627,10 @@ DialUpView::AddInterface(const char *name, bool isNew = false) BMenuItem *item = new BMenuItem(name, new BMessage(MSG_SELECT_INTERFACE)); item->SetTarget(this); - fInterfaceMenu->AddItem(item, CountInterfaces()); + int32 index = FindNextMenuInsertionIndex(fInterfaceMenu, name); + if(index > CountInterfaces()) + index = CountInterfaces(); + fInterfaceMenu->AddItem(item, index); if(CountInterfaces() == 1) fInterfaceMenu->SetLabelFromMarked(true); SelectInterface(CountInterfaces() - 1, isNew); @@ -653,8 +656,6 @@ DialUpView::SelectInterface(int32 index, bool isNew = false) } else { if(!fCurrentItem) { fTabView->Show(); -// fTabView->MoveBy(-Bounds().Width(), 0); -// fNoInterfacesStringView->MoveBy(Bounds().Width(), 0); fConnectButton->SetEnabled(true); } @@ -673,13 +674,8 @@ DialUpView::SelectInterface(int32 index, bool isNew = false) // tell modules to unload all settings fTabView->Hide(); -// fTabView->MoveBy(Bounds().Width(), 0); -// fNoInterfacesStringView->MoveBy(-Bounds().Width(), 0); fConnectButton->SetEnabled(false); - } else if(isNew && !LoadSettings(true)) { - (new BAlert(ERROR_TITLE, ERROR_LOADING_FAILED, TEXT_OK))->Go(); - LoadSettings(true); - } else if(!LoadSettings(false)) { + } else if(!isNew && !LoadSettings(false)) { (new BAlert(ERROR_TITLE, ERROR_LOADING_FAILED, TEXT_OK))->Go(); LoadSettings(true); } @@ -691,3 +687,18 @@ DialUpView::CountInterfaces() const { return fInterfaceMenu->CountItems() - 3; } + + +int32 +DialUpView::FindNextMenuInsertionIndex(BMenu *menu, const BString& name, + int32 index = 0) +{ + BMenuItem *item; + for(; index < menu->CountItems(); index++) { + item = menu->ItemAt(index); + if(item && name.ICompare(item->Label()) <= 0) + return index; + } + + return index; +} diff --git a/src/tests/kits/net/DialUpPreflet/DialUpView.h b/src/tests/kits/net/DialUpPreflet/DialUpView.h index d3f478beb4..1d650c6a96 100644 --- a/src/tests/kits/net/DialUpPreflet/DialUpView.h +++ b/src/tests/kits/net/DialUpPreflet/DialUpView.h @@ -45,6 +45,8 @@ class DialUpView : public BView { void AddInterface(const char *name, bool isNew = false); void SelectInterface(int32 index, bool isNew = false); int32 CountInterfaces() const; + int32 FindNextMenuInsertionIndex(BMenu *menu, const BString& name, + int32 index = 0); private: PPPInterfaceListener fListener; @@ -62,7 +64,6 @@ class DialUpView : public BView { BPopUpMenu *fInterfaceMenu; BMenuField *fMenuField; BTabView *fTabView; -// BStringView *fNoInterfacesStringView; }; diff --git a/src/tests/kits/net/DialUpPreflet/GeneralAddon.cpp b/src/tests/kits/net/DialUpPreflet/GeneralAddon.cpp index 4af0f179d9..56834c2f42 100644 --- a/src/tests/kits/net/DialUpPreflet/GeneralAddon.cpp +++ b/src/tests/kits/net/DialUpPreflet/GeneralAddon.cpp @@ -32,11 +32,9 @@ GeneralAddon::GeneralAddon(BMessage *addons) fHasPassword(false), fAuthenticatorsCount(0), fSettings(NULL), - fProfile(NULL) + fProfile(NULL), + fGeneralView(NULL) { - BRect rect; - addons->FindRect("TabViewRect", &rect); - fGeneralView = new GeneralView(this, rect); } @@ -50,7 +48,7 @@ GeneralAddon::FindDevice(const BString& moduleName) const { DialUpAddon *addon; for(int32 index = 0; Addons()->FindPointer("Device", index, - reinterpret_cast(addon)); index++) + reinterpret_cast(&addon)) == B_OK; index++) if(addon && moduleName == addon->KernelModuleName()) return addon; @@ -68,6 +66,11 @@ GeneralAddon::LoadSettings(BMessage *settings, BMessage *profile, bool isNew) fAuthenticatorsCount = 0; fSettings = settings; fProfile = profile; + + if(fGeneralView) + fGeneralView->Reload(); + // reset all views (empty settings) + if(!settings || !profile || isNew) return true; @@ -77,6 +80,10 @@ GeneralAddon::LoadSettings(BMessage *settings, BMessage *profile, bool isNew) if(!LoadAuthenticationSettings(settings, profile)) return false; + if(fGeneralView) + fGeneralView->Reload(); + // reload new settings + return true; } @@ -90,7 +97,7 @@ GeneralAddon::LoadDeviceSettings(BMessage *settings, BMessage *profile) return false; // TODO: tell user that device specification is missing - if(!device.FindString("Values", &fDeviceName)) + if(device.FindString("Values", &fDeviceName) != B_OK) return false; // TODO: tell user that device specification is missing @@ -161,6 +168,13 @@ GeneralAddon::LoadAuthenticationSettings(BMessage *settings, BMessage *profile) } +bool +GeneralAddon::HasTemporaryProfile() const +{ + return !fGeneralView->DoesSavePassword(); +} + + void GeneralAddon::IsModified(bool& settings, bool& profile) const { @@ -216,7 +230,7 @@ GeneralAddon::IsAuthenticationModified(bool& settings, bool& profile) const || authenticator != fGeneralView->AuthenticatorName()); } - profile = (fUsername != fGeneralView->Username() + profile = (settings || fUsername != fGeneralView->Username() || (fPassword != fGeneralView->Password() && fHasPassword) || fHasPassword != fGeneralView->DoesSavePassword()); } @@ -229,10 +243,14 @@ GeneralAddon::SaveSettings(BMessage *settings, BMessage *profile, bool saveTempo return false; // TODO: tell user that a device is needed (if we fail because of this) + if(!fDeviceAddon || !fDeviceAddon->SaveSettings(settings, profile, saveTemporary)) + return false; + if(fGeneralView->AuthenticatorName()) { BMessage authenticator; authenticator.AddString("Name", PPP_AUTHENTICATOR_KEY); authenticator.AddString("Values", fGeneralView->AuthenticatorName()); + settings->AddMessage("Parameters", &authenticator); BMessage username; username.AddString("Name", "User"); @@ -246,22 +264,21 @@ GeneralAddon::SaveSettings(BMessage *settings, BMessage *profile, bool saveTempo password.AddString("Values", fGeneralView->Password()); authenticator.AddMessage("Parameters", &password); } + + profile->AddMessage("Parameters", &authenticator); } - DialUpAddon *addon = FindDevice(fGeneralView->DeviceName()); - if(!addon) - return false; - - return addon->SaveSettings(settings, profile, saveTemporary); + return true; } bool GeneralAddon::GetPreferredSize(float *width, float *height) const { - BRect rect(0, 0, 200, 300); - // set default values - Addons()->FindRect("TabViewRect", &rect); + BRect rect; + if(Addons()->FindRect("TabViewRect", &rect) != B_OK) + rect.Set(0, 0, 200, 300); + // set default values if(width) *width = rect.Width(); @@ -275,10 +292,11 @@ GeneralAddon::GetPreferredSize(float *width, float *height) const BView* GeneralAddon::CreateView(BPoint leftTop) { - BRect rect; - if(Addons()->FindRect("TabViewRect", &rect) != B_OK); - rect.Set(0, 0, 200, 300); - // set default values + if(!fGeneralView) { + BRect rect; + Addons()->FindRect("TabViewRect", &rect); + fGeneralView = new GeneralView(this, rect); + } fGeneralView->MoveTo(leftTop); fGeneralView->Reload(); @@ -326,13 +344,14 @@ GeneralAddon::MarkAuthenticatorAsValid(const BString& moduleName) GeneralView::GeneralView(GeneralAddon *addon, BRect frame) - : BView(frame, "General", B_FOLLOW_NONE, 0), + : BView(frame, "GeneralView", B_FOLLOW_NONE, 0), fAddon(addon) { BRect rect = Bounds(); rect.InsetBy(5, 5); rect.bottom = 100; fDeviceBox = new BBox(rect, "Device"); + Addon()->Addons()->AddFloat("DeviceViewWidth", fDeviceBox->Bounds().Width() - 10); rect.top = rect.bottom + 10; rect.bottom = rect.top + 25 // space for topmost control @@ -340,17 +359,16 @@ GeneralView::GeneralView(GeneralAddon *addon, BRect frame) + 3 * 5; // space beween controls and bottom of box fAuthenticationBox = new BBox(rect, "Authentication"); - fDeviceField = new BMenuField(BRect(5, 0, 250, 25), "Device", + fDeviceField = new BMenuField(BRect(5, 0, 250, 20), "Device", "Device:", new BPopUpMenu("No Devices Found!")); - fDeviceField->SetDivider(fDeviceField->StringWidth(fDeviceField->Label()) + 10); + fDeviceField->SetDivider(StringWidth(fDeviceField->Label()) + 10); fDeviceField->Menu()->SetRadioMode(true); AddDevices(); fDeviceBox->SetLabel(fDeviceField); - fAuthenticatorField = new BMenuField(BRect(5, 0, 250, 25), "Authenticator", + fAuthenticatorField = new BMenuField(BRect(5, 0, 250, 20), "Authenticator", "Authenticator:", new BPopUpMenu("No Authenticators Found!")); - fAuthenticatorField->SetDivider(fAuthenticatorField->StringWidth( - fAuthenticatorField->Label()) + 10); + fAuthenticatorField->SetDivider(StringWidth(fAuthenticatorField->Label()) + 10); fAuthenticatorField->Menu()->SetRadioMode(true); AddAuthenticators(); fAuthenticationBox->SetLabel(fAuthenticatorField); @@ -364,6 +382,15 @@ GeneralView::GeneralView(GeneralAddon *addon, BRect frame) rect.bottom = rect.top + 20; fPassword = new BTextControl(rect, "password", "Password: ", NULL, NULL); fPassword->TextView()->HideTyping(true); + float usernameWidth = StringWidth(fUsername->Label()) + 5; + float passwordWidth = StringWidth(fPassword->Label()) + 5; + if(usernameWidth > passwordWidth) + passwordWidth = usernameWidth; + else + usernameWidth = passwordWidth; + fUsername->SetDivider(usernameWidth); + fPassword->SetDivider(passwordWidth); + rect.top = rect.bottom + 5; rect.bottom = rect.top + 20; fSavePassword = new BCheckBox(rect, "SavePassword", "Save Password", NULL); @@ -379,18 +406,12 @@ GeneralView::GeneralView(GeneralAddon *addon, BRect frame) GeneralView::~GeneralView() { - // TODO: delete device add-on } void GeneralView::Reload() { - // TODO: reload settings: - // - select device and authenticator - // - add device view (and move authenticator view to fit) - // - set username, password, and checkbox - fDeviceAddon = NULL; BMenuItem *item; @@ -402,7 +423,7 @@ GeneralView::Reload() break; } - if(fDeviceAddon == Addon()->DeviceAddon()) { + if(fDeviceAddon && fDeviceAddon == Addon()->DeviceAddon()) { item->SetMarked(true); ReloadDeviceView(); } else { @@ -417,8 +438,9 @@ GeneralView::Reload() BMessage authentication; if(Addon()->Settings()->FindMessage("Authentication", &authentication) == B_OK) authentication.FindString("Authenticators", &authenticator); - for(int32 index = 0; index < fDeviceField->Menu()->CountItems(); index++) { - item = fDeviceField->Menu()->ItemAt(index); + BMenu *menu = fAuthenticatorField->Menu(); + for(int32 index = 0; index < menu->CountItems(); index++) { + item = menu->ItemAt(index); if(item && item->Message() && item->Message()->FindString("KernelModuleName", &kernelModule) == B_OK && kernelModule == authenticator) { @@ -432,6 +454,8 @@ GeneralView::Reload() fUsername->SetText(Addon()->Username()); fPassword->SetText(Addon()->Password()); fSavePassword->SetValue(Addon()->HasPassword()); + + ReloadDeviceView(); } @@ -512,14 +536,16 @@ void GeneralView::ReloadDeviceView() { // first remove existing device view(s) - while(fDeviceBox->CountChildren() > 0) - fDeviceBox->RemoveChild(fDeviceBox->ChildAt(0)); + while(fDeviceBox->CountChildren() > 1) + fDeviceBox->RemoveChild(fDeviceBox->ChildAt(1)); + + if(!fDeviceAddon) + return; BRect rect(fDeviceBox->Bounds()); - rect.top = 25; float width, height; if(!fDeviceAddon->GetPreferredSize(&width, &height)) { - width = 50; + width = rect.Width(); height = 50; } @@ -527,10 +553,16 @@ GeneralView::ReloadDeviceView() width = rect.Width(); if(height < 10) height = 10; + // set minimum height + else if(height > 200) + height = 200; + // set maximum height rect.InsetBy((rect.Width() - width) / 2, 0); + // center horizontally + rect.top = 25; rect.bottom = rect.top + height; - float deltaY = rect.Height() - fDeviceBox->Bounds().Height(); + float deltaY = height + 30 - fDeviceBox->Bounds().Height(); fDeviceBox->ResizeBy(0, deltaY); fAuthenticationBox->MoveBy(0, deltaY); @@ -560,7 +592,7 @@ GeneralView::AddAuthenticators() Addon()->Addons()->FindMessage("Authenticator", index, &addon) == B_OK; index++) { BMessage *message = new BMessage(MSG_SELECT_AUTHENTICATOR); - message->AddString("Authenticator", addon.FindString("KernelModuleName")); + message->AddString("KernelModuleName", addon.FindString("KernelModuleName")); BString name, technicalName, friendlyName; bool hasTechnicalName @@ -578,7 +610,7 @@ GeneralView::AddAuthenticators() name << ")"; } - int32 insertAt = FindNextAddonInsertionIndex(fAuthenticatorField->Menu(), + int32 insertAt = FindNextMenuInsertionIndex(fAuthenticatorField->Menu(), name, 2); fAuthenticatorField->Menu()->AddItem(new BMenuItem(name.String(), message), insertAt); @@ -610,14 +642,14 @@ GeneralView::AddAddonsToMenu(BMenu *menu, const char *type, uint32 what) name << ")"; } - int32 insertAt = FindNextAddonInsertionIndex(menu, name); + int32 insertAt = FindNextMenuInsertionIndex(menu, name); menu->AddItem(new BMenuItem(name.String(), message), insertAt); } } int32 -GeneralView::FindNextAddonInsertionIndex(BMenu *menu, const BString& name, +GeneralView::FindNextMenuInsertionIndex(BMenu *menu, const BString& name, int32 index = 0) { BMenuItem *item; diff --git a/src/tests/kits/net/DialUpPreflet/GeneralAddon.h b/src/tests/kits/net/DialUpPreflet/GeneralAddon.h index 2390eff0b2..e6b81d49f6 100644 --- a/src/tests/kits/net/DialUpPreflet/GeneralAddon.h +++ b/src/tests/kits/net/DialUpPreflet/GeneralAddon.h @@ -56,6 +56,7 @@ class GeneralAddon : public DialUpAddon { bool LoadDeviceSettings(BMessage *settings, BMessage *profile); bool LoadAuthenticationSettings(BMessage *settings, BMessage *profile); + virtual bool HasTemporaryProfile() const; virtual void IsModified(bool& settings, bool& profile) const; void IsDeviceModified(bool& settings, bool& profile) const; void IsAuthenticationModified(bool& settings, bool& profile) const; @@ -109,7 +110,7 @@ class GeneralView : public BView { void AddDevices(); void AddAuthenticators(); void AddAddonsToMenu(BMenu *menu, const char *type, uint32 what); - int32 FindNextAddonInsertionIndex(BMenu *menu, const BString& name, + int32 FindNextMenuInsertionIndex(BMenu *menu, const BString& name, int32 index = 0); private: diff --git a/src/tests/kits/net/DialUpPreflet/Jamfile b/src/tests/kits/net/DialUpPreflet/Jamfile index 5433ae2eee..e2da2c968b 100644 --- a/src/tests/kits/net/DialUpPreflet/Jamfile +++ b/src/tests/kits/net/DialUpPreflet/Jamfile @@ -4,6 +4,9 @@ UsePrivateHeaders net ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libppp headers ] ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ; +# additonal headers for built-in add-ons: +UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp pppoe ] ; # PPPoE + SimpleTest DialUpPreflet : DialUpApplication.cpp DialUpView.cpp @@ -13,6 +16,7 @@ SimpleTest DialUpPreflet : # built-in add-ons GeneralAddon.cpp + PPPoEAddon.cpp ; -LinkSharedOSLibs DialUpPreflet : be libppp.a ; +LinkSharedOSLibs DialUpPreflet : libppp.a be ; diff --git a/src/tests/kits/net/DialUpPreflet/MessageDriverSettingsUtils.cpp b/src/tests/kits/net/DialUpPreflet/MessageDriverSettingsUtils.cpp index a0ecebc4ff..5df4b85218 100644 --- a/src/tests/kits/net/DialUpPreflet/MessageDriverSettingsUtils.cpp +++ b/src/tests/kits/net/DialUpPreflet/MessageDriverSettingsUtils.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include @@ -61,6 +60,8 @@ ReadMessageDriverSettings(const char *name, BMessage& message) return false; void *handle = load_driver_settings(name); + if(!handle) + return false; const driver_settings *settings = get_driver_settings(handle); if(!settings) { unload_driver_settings(handle); @@ -79,6 +80,17 @@ ReadMessageDriverSettings(const char *name, BMessage& message) } +static +void +EscapeWord(BString& word) +{ + word.ReplaceAll("\\", "\\\\"); + word.ReplaceAll("#", "\\#"); + word.ReplaceAll("\"", "\\\""); + word.ReplaceAll("\'", "\\\'"); +} + + static bool WriteParameter(BFile& file, const BMessage& parameter, int32 level) @@ -87,13 +99,29 @@ WriteParameter(BFile& file, const BMessage& parameter, int32 level) if(parameter.FindString("Name", &name) != B_OK || !name) return false; - BString line; + BString line, word(name); + EscapeWord(word); + bool needsEscaping = word.FindFirst(' ') >= 0; line.SetTo('\t', level); - line << name << ' '; + if(needsEscaping) + line << '\"'; + line << word; + if(needsEscaping) + line << '\"'; + line << ' '; for(int32 index = 0; parameter.FindString("Values", index, &name) == B_OK; index++) - if(name) - line << name << ' '; + if(name) { + word = name; + EscapeWord(word); + needsEscaping = word.FindFirst(' ') >= 0; + if(needsEscaping) + line << '\"'; + line << word; + if(needsEscaping) + line << '\"'; + line << ' '; + } type_code type; int32 parameterCount; @@ -112,7 +140,7 @@ WriteParameter(BFile& file, const BMessage& parameter, int32 level) WriteParameter(file, subParameter, level + 1); line.SetTo('\t', level); - line << '\n'; + line << "}\n"; file.Write(line.String(), line.Length()); } @@ -126,12 +154,16 @@ WriteMessageDriverSettings(BFile& file, const BMessage& message) if(file.InitCheck() != B_OK || !file.IsWritable()) return false; + file.SetSize(0); file.Seek(0, SEEK_SET); BMessage parameter; for(int32 index = 0; message.FindMessage("Parameters", index, ¶meter) == B_OK; - index++) + index++) { + if(index > 0) + file.Write("\n", 1); WriteParameter(file, parameter, 0); + } return true; } diff --git a/src/tests/kits/net/DialUpPreflet/TODO b/src/tests/kits/net/DialUpPreflet/TODO index 4f20e6c77f..97f23631d3 100644 --- a/src/tests/kits/net/DialUpPreflet/TODO +++ b/src/tests/kits/net/DialUpPreflet/TODO @@ -11,6 +11,7 @@ Short-term TODOs: - write PAP authenticator add-on - write PPPoE device add-on - move DEVNOTES into a doxygen file and document the rest of the API +- remove static window positions Long-term TODOs: - allow selecting multiple authenticators