diff --git a/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h b/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h index 8cebdf7bc5..f05259b8bf 100644 --- a/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h +++ b/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h @@ -41,8 +41,9 @@ public: const BNetworkProfile* Profile() const; - virtual status_t Save() = 0; + virtual status_t Apply() = 0; virtual status_t Revert() = 0; + virtual bool IsRevertable() = 0; private: const BNetworkProfile* diff --git a/src/preferences/network/InterfaceListItem.cpp b/src/preferences/network/InterfaceListItem.cpp index ce04aabb3c..64e6c02bae 100644 --- a/src/preferences/network/InterfaceListItem.cpp +++ b/src/preferences/network/InterfaceListItem.cpp @@ -28,7 +28,7 @@ #undef B_TRANSLATION_CONTEXT -#define B_TRANSLATION_CONTEXT "InterfacesListView" +#define B_TRANSLATION_CONTEXT "InterfaceListItem" InterfaceListItem::InterfaceListItem(const char* name) @@ -74,57 +74,38 @@ InterfaceListItem::DrawItem(BView* owner, BRect /*bounds*/, bool complete) list->FillRect(bounds); } - BString interfaceState; - BBitmap* stateIcon(NULL); - // TODO: only update periodically - bool disabled = (fInterface.Flags() & IFF_UP) == 0; + _UpdateState(); - if (disabled) { - interfaceState = "disabled"; - stateIcon = fIconOffline; - } else if (!fInterface.HasLink()) { - interfaceState = "no link"; - stateIcon = fIconOffline; - // TODO! -// } else if ((fSettings->IPAddr(AF_INET).IsEmpty() -// && fSettings->IPAddr(AF_INET6).IsEmpty()) -// && (fSettings->AutoConfigure(AF_INET) -// || fSettings->AutoConfigure(AF_INET6))) { -// interfaceState = "connecting" B_UTF8_ELLIPSIS; -// stateIcon = fIconPending; - } else { - interfaceState = "connected"; - stateIcon = fIconOnline; - } + BBitmap* stateIcon = _StateIcon(); + const char* stateText = _StateText(); // Set the initial bounds of item contents - BPoint iconPt = bounds.LeftTop(); - BPoint namePt = bounds.LeftTop(); - BPoint line2Pt = bounds.LeftTop(); - BPoint line3Pt = bounds.LeftTop(); - BPoint statePt = bounds.RightTop(); + BPoint iconPoint = bounds.LeftTop(); + BPoint namePoint = bounds.LeftTop(); + BPoint line2Point = bounds.LeftTop(); + BPoint line3Point = bounds.LeftTop(); + BPoint statePoint = bounds.RightTop(); - iconPt += BPoint(4, 4); - statePt += BPoint(0, fFirstlineOffset); - namePt += BPoint(ICON_SIZE + 12, fFirstlineOffset); - line2Pt += BPoint(ICON_SIZE + 12, fSecondlineOffset); - line3Pt += BPoint(ICON_SIZE + 12, fThirdlineOffset); + iconPoint += BPoint(4, 4); + statePoint += BPoint(0, fFirstlineOffset); + namePoint += BPoint(ICON_SIZE + 12, fFirstlineOffset); + line2Point += BPoint(ICON_SIZE + 12, fSecondlineOffset); + line3Point += BPoint(ICON_SIZE + 12, fThirdlineOffset); - statePt -= BPoint( - be_plain_font->StringWidth(interfaceState.String()) + 4.0f, 0); + statePoint -= BPoint(be_plain_font->StringWidth(stateText) + 4.0f, 0); - if (disabled) { + if (fDisabled) { list->SetDrawingMode(B_OP_ALPHA); list->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); list->SetHighColor(0, 0, 0, 32); } else list->SetDrawingMode(B_OP_OVER); - list->DrawBitmapAsync(fIcon, iconPt); - list->DrawBitmapAsync(stateIcon, iconPt); + list->DrawBitmapAsync(fIcon, iconPoint); + list->DrawBitmapAsync(stateIcon, iconPoint); - if (disabled) { + if (fDisabled) { rgb_color textColor; if (IsSelected()) textColor = ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR); @@ -144,12 +125,9 @@ InterfaceListItem::DrawItem(BView* owner, BRect /*bounds*/, bool complete) list->SetFont(be_bold_font); - BString name = Name(); - name.RemoveFirst("/dev/net/"); - - list->DrawString(name, namePt); + list->DrawString(fDeviceName, namePoint); list->SetFont(be_plain_font); - list->DrawString(interfaceState, statePt); + list->DrawString(stateText, statePoint); // TODO! /* if (!disabled) { @@ -160,7 +138,7 @@ InterfaceListItem::DrawItem(BView* owner, BRect /*bounds*/, bool complete) else ipv4Str << " " << BString(fSettings->IP(AF_INET)); - list->DrawString(ipv4Str, line2Pt); + list->DrawString(ipv4Str, line2Point); } // Render IPv6 Address (if present) @@ -168,7 +146,7 @@ InterfaceListItem::DrawItem(BView* owner, BRect /*bounds*/, bool complete) BString ipv6Str(B_TRANSLATE_COMMENT("IPv6:", "IPv6 address label")); ipv6Str << " " << BString(fSettings->IP(AF_INET6)); - list->DrawString(ipv6Str, line3Pt); + list->DrawString(ipv6Str, line3Point); } */ owner->PopState(); @@ -189,6 +167,11 @@ InterfaceListItem::Update(BView* owner, const BFont* font) fSecondlineOffset = fFirstlineOffset + lineHeight; fThirdlineOffset = fFirstlineOffset + (lineHeight * 2); + _UpdateState(); + + SetWidth(fIcon->Bounds().Width() + 24 + + be_bold_font->StringWidth(fDeviceName.String()) + + owner->StringWidth(_StateText())); SetHeight(std::max(3 * lineHeight + 4, fIcon->Bounds().Height() + 8)); // either to the text height or icon height, whichever is taller } @@ -279,3 +262,65 @@ InterfaceListItem::_PopulateBitmaps(const char* mediaType) BIconUtils::GetVectorIcon(onlineHVIF, iconSize, fIconOnline); } } + + +void +InterfaceListItem::_UpdateState() +{ + fDeviceName = Name(); + fDeviceName.RemoveFirst("/dev/net/"); + + fDisabled = (fInterface.Flags() & IFF_UP) == 0; + fHasLink = fInterface.HasLink(); + fConnecting = (fInterface.Flags() & IFF_CONFIGURING) != 0; + + int32 count = fInterface.CountAddresses(); + size_t addressIndex = 0; + for (int32 index = 0; index < count; index++) { + if (addressIndex >= sizeof(fAddress) / sizeof(fAddress[0])) + break; + + BNetworkInterfaceAddress address; + if (fInterface.GetAddressAt(index, address) == B_OK) + fAddress[addressIndex++] = address.Address().ToString(); + } +} + + +BBitmap* +InterfaceListItem::_StateIcon() const +{ + if (fDisabled) + return fIconOffline; + if (!fHasLink) + return fIconOffline; + // TODO! +// } else if ((fSettings->IPAddr(AF_INET).IsEmpty() +// && fSettings->IPAddr(AF_INET6).IsEmpty()) +// && (fSettings->AutoConfigure(AF_INET) +// || fSettings->AutoConfigure(AF_INET6))) { +// interfaceState = "connecting" B_UTF8_ELLIPSIS; +// stateIcon = fIconPending; + + return fIconOnline; +} + + +const char* +InterfaceListItem::_StateText() const +{ + if (fDisabled) + return B_TRANSLATE("disabled"); + if (!fInterface.HasLink()) + return B_TRANSLATE("no link"); + + // TODO! +// } else if ((fSettings->IPAddr(AF_INET).IsEmpty() +// && fSettings->IPAddr(AF_INET6).IsEmpty()) +// && (fSettings->AutoConfigure(AF_INET) +// || fSettings->AutoConfigure(AF_INET6))) { +// interfaceState = "connecting" B_UTF8_ELLIPSIS; +// stateIcon = fIconPending; + + return B_TRANSLATE("connected"); +} diff --git a/src/preferences/network/InterfaceListItem.h b/src/preferences/network/InterfaceListItem.h index 84d42864d6..e989411e89 100644 --- a/src/preferences/network/InterfaceListItem.h +++ b/src/preferences/network/InterfaceListItem.h @@ -33,7 +33,11 @@ public: private: void _Init(); void _PopulateBitmaps(const char* mediaType); + void _UpdateState(); + BBitmap* _StateIcon() const; + const char* _StateText() const; +private: BBitmap* fIcon; BBitmap* fIconOffline; BBitmap* fIconPending; @@ -45,6 +49,12 @@ private: float fFirstlineOffset; float fSecondlineOffset; float fThirdlineOffset; + + BString fDeviceName; + bool fDisabled; + bool fHasLink; + bool fConnecting; + BString fAddress[2]; }; diff --git a/src/preferences/network/InterfacesAddOn/InterfaceHardwareView.cpp b/src/preferences/network/InterfaceView.cpp similarity index 54% rename from src/preferences/network/InterfacesAddOn/InterfaceHardwareView.cpp rename to src/preferences/network/InterfaceView.cpp index d393860f6a..14da86459a 100644 --- a/src/preferences/network/InterfacesAddOn/InterfaceHardwareView.cpp +++ b/src/preferences/network/InterfaceView.cpp @@ -1,80 +1,81 @@ /* - * Copyright 2004-2013 Haiku, Inc. All rights reserved. + * Copyright 2004-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: + * Axel Dörfler, * Alexander von Gluck, kallisti5@unixzen.com * John Scipione, jscipione@gmail.com */ -#include "InterfaceHardwareView.h" - #include "InterfaceView.h" -#include "NetworkSettings.h" -#include "WirelessNetworkMenuItem.h" + +#include + +#include #include #include #include #include -#include -#include #include -#include -#include +#include #include #include #include -#include -#include +#include "MediaTypes.h" +#include "WirelessNetworkMenuItem.h" + + +static const uint32 kMsgInterfaceToggle = 'onof'; +static const uint32 kMsgInterfaceRenegotiate = 'redo'; +static const uint32 kMsgJoinNetwork = 'join'; #undef B_TRANSLATION_CONTEXT -#define B_TRANSLATION_CONTEXT "IntefaceHardwareView" +#define B_TRANSLATION_CONTEXT "IntefaceView" -// #pragma mark - InterfaceHardwareView +// #pragma mark - InterfaceView -InterfaceHardwareView::InterfaceHardwareView(NetworkSettings* settings) +InterfaceView::InterfaceView() : - BGroupView(B_VERTICAL), - fSettings(settings) + BGroupView(B_VERTICAL) { - SetLayout(new BGroupLayout(B_VERTICAL)); - SetFlags(Flags() | B_PULSE_NEEDED); - // TODO : Small graph of throughput? + // TODO: Small graph of throughput? float minimumWidth = be_control_look->DefaultItemSpacing() * 16; - BStringView* status = new BStringView("status label", B_TRANSLATE("Status:")); - status->SetAlignment(B_ALIGN_RIGHT); + BStringView* statusLabel = new BStringView("status label", + B_TRANSLATE("Status:")); + statusLabel->SetAlignment(B_ALIGN_RIGHT); fStatusField = new BStringView("status field", ""); fStatusField->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); - BStringView* macAddress = new BStringView("mac address label", + BStringView* macAddressLabel = new BStringView("mac address label", B_TRANSLATE("MAC address:")); - macAddress->SetAlignment(B_ALIGN_RIGHT); + macAddressLabel->SetAlignment(B_ALIGN_RIGHT); fMacAddressField = new BStringView("mac address field", ""); fMacAddressField->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); - BStringView* linkSpeed = new BStringView("link speed label", + BStringView* linkSpeedLabel = new BStringView("link speed label", B_TRANSLATE("Link speed:")); - linkSpeed->SetAlignment(B_ALIGN_RIGHT); + linkSpeedLabel->SetAlignment(B_ALIGN_RIGHT); fLinkSpeedField = new BStringView("link speed field", ""); fLinkSpeedField->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); // TODO: These metrics may be better in a BScrollView? - BStringView* linkTx = new BStringView("tx label", + BStringView* linkTxLabel = new BStringView("tx label", B_TRANSLATE("Sent:")); - linkTx->SetAlignment(B_ALIGN_RIGHT); + linkTxLabel->SetAlignment(B_ALIGN_RIGHT); fLinkTxField = new BStringView("tx field", ""); fLinkTxField ->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); - BStringView* linkRx = new BStringView("rx label", + BStringView* linkRxLabel = new BStringView("rx label", B_TRANSLATE("Received:")); - linkRx->SetAlignment(B_ALIGN_RIGHT); + linkRxLabel->SetAlignment(B_ALIGN_RIGHT); fLinkRxField = new BStringView("rx field", ""); fLinkRxField ->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); @@ -93,43 +94,44 @@ InterfaceHardwareView::InterfaceHardwareView(NetworkSettings* settings) BLayoutBuilder::Group<>(this) .AddGrid() - .Add(status, 0, 0) + .Add(statusLabel, 0, 0) .Add(fStatusField, 1, 0) .Add(fNetworkMenuField->CreateLabelLayoutItem(), 0, 1) .Add(fNetworkMenuField->CreateMenuBarLayoutItem(), 1, 1) - .Add(macAddress, 0, 2) + .Add(macAddressLabel, 0, 2) .Add(fMacAddressField, 1, 2) - .Add(linkSpeed, 0, 3) + .Add(linkSpeedLabel, 0, 3) .Add(fLinkSpeedField, 1, 3) - .Add(linkTx, 0, 4) + .Add(linkTxLabel, 0, 4) .Add(fLinkTxField, 1, 4) - .Add(linkRx, 0, 5) + .Add(linkRxLabel, 0, 5) .Add(fLinkRxField, 1, 5) .End() .AddGlue() .AddGroup(B_HORIZONTAL) - .Add(fOnOff) .AddGlue() + .Add(fOnOff) .Add(fRenegotiate) - .End() - .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING); + .End(); } -InterfaceHardwareView::~InterfaceHardwareView() +InterfaceView::~InterfaceView() { - } -// #pragma mark - InterfaceHardwareView virtual methods - - void -InterfaceHardwareView::AttachedToWindow() +InterfaceView::SetTo(const char* name) { - Update(); + fInterface.SetTo(name); +} + + +void +InterfaceView::AttachedToWindow() +{ + _Update(); // Populate the fields fOnOff->SetTarget(this); @@ -138,25 +140,35 @@ InterfaceHardwareView::AttachedToWindow() void -InterfaceHardwareView::MessageReceived(BMessage* message) +InterfaceView::MessageReceived(BMessage* message) { switch (message->what) { - case kMsgNetwork: + case kMsgJoinNetwork: { - fSettings->SetWirelessNetwork(message->FindString("name")); + const char* name; + BNetworkAddress address; + if (message->FindString("name", &name) == B_OK + && message->FindFlat("address", &address) == B_OK) { + BNetworkDevice device(fInterface.Name()); + status_t status = device.JoinNetwork(address); + if (status != B_OK) { + // This does not really matter, as it's stored this way, + // anyway. + } + // TODO: store value + } break; } case kMsgInterfaceToggle: { - fSettings->SetDisabled(!fSettings->IsDisabled()); - Update(); - Window()->FindView("interfaces")->Invalidate(); + // TODO: disable/enable interface + _Update(); break; } case kMsgInterfaceRenegotiate: { - fSettings->RenegotiateAddresses(); + // TODO: renegotiate addresses break; } @@ -167,31 +179,25 @@ InterfaceHardwareView::MessageReceived(BMessage* message) void -InterfaceHardwareView::Pulse() +InterfaceView::Pulse() { - // TODO maybe not everything needs to be updated here. - Update(); -} - - -// #pragma mark - InterfaceHardwareView public methods - - -status_t -InterfaceHardwareView::Revert() -{ - Update(); - return B_OK; + // Update the wireless network menu every 5 seconds + _Update((fPulseCount++ % 5) == 0); } status_t -InterfaceHardwareView::Update() +InterfaceView::_Update(bool updateWirelessNetworks) { + BNetworkDevice device(fInterface.Name()); + bool isWireless = device.IsWireless(); + bool disabled = (fInterface.Flags() & IFF_UP) == 0; + // Populate fields with current settings - if (fSettings->HasLink()) { - if (fSettings->IsWireless()) { - BString network = fSettings->WirelessNetwork(); + if (fInterface.HasLink()) { + if (isWireless) { + // TODO! + BString network = "---"; network.Prepend(" ("); network.Prepend(B_TRANSLATE("connected")); network.Append(")"); @@ -202,34 +208,39 @@ InterfaceHardwareView::Update() } else fStatusField->SetText(B_TRANSLATE("disconnected")); - fMacAddressField->SetText(fSettings->HardwareAddress()); + BNetworkAddress hardwareAddress; + if (device.GetHardwareAddress(hardwareAddress) == B_OK) + fMacAddressField->SetText(hardwareAddress.ToString()); + else + fMacAddressField->SetText("-"); - // TODO : Find how to get link speed - fLinkSpeedField->SetText("100 Mb/s"); + int media = fInterface.Media(); + if ((media & IFM_ACTIVE) != 0) + fLinkSpeedField->SetText(media_type_to_string(media)); + else + fLinkSpeedField->SetText("-"); // Update Link stats ifreq_stats stats; - char buffer[100]; - fSettings->Stats(&stats); + if (fInterface.GetStats(stats) == B_OK) { + char buffer[100]; - string_for_size(stats.send.bytes, buffer, sizeof(buffer)); - fLinkTxField->SetText(buffer); + string_for_size(stats.send.bytes, buffer, sizeof(buffer)); + fLinkTxField->SetText(buffer); - string_for_size(stats.receive.bytes, buffer, sizeof(buffer)); - fLinkRxField->SetText(buffer); - - // TODO move the wireless info to a separate tab. We should have a - // BListView of available networks, rather than a menu, to make them more - // readable and easier to browse and select. - if (fNetworkMenuField->IsHidden(fNetworkMenuField) - && fSettings->IsWireless()) { - fNetworkMenuField->Show(); - } else if (!fNetworkMenuField->IsHidden(fNetworkMenuField) - && !fSettings->IsWireless()) { - fNetworkMenuField->Hide(); + string_for_size(stats.receive.bytes, buffer, sizeof(buffer)); + fLinkRxField->SetText(buffer); } - if (fSettings->IsWireless()) { + // TODO: move the wireless info to a separate tab. We should have a + // BListView of available networks, rather than a menu, to make them more + // readable and easier to browse and select. + if (fNetworkMenuField->IsHidden(fNetworkMenuField) && isWireless) + fNetworkMenuField->Show(); + else if (!fNetworkMenuField->IsHidden(fNetworkMenuField) && !isWireless) + fNetworkMenuField->Hide(); + + if (isWireless && updateWirelessNetworks) { // Rebuild network menu BMenu* menu = fNetworkMenuField->Menu(); menu->RemoveItems(0, menu->CountItems(), true); @@ -237,17 +248,18 @@ InterfaceHardwareView::Update() std::set associated; BNetworkAddress address; uint32 cookie = 0; - while (fSettings->GetNextAssociatedNetwork(cookie, address) == B_OK) + while (device.GetNextAssociatedNetwork(cookie, address) == B_OK) associated.insert(address); wireless_network network; int32 count = 0; cookie = 0; - while (fSettings->GetNextNetwork(cookie, network) == B_OK) { - BMessage* message = new BMessage(kMsgNetwork); + while (device.GetNextNetwork(cookie, network) == B_OK) { + BMessage* message = new BMessage(kMsgJoinNetwork); - message->AddString("device", fSettings->Name()); + message->AddString("device", fInterface.Name()); message->AddString("name", network.name); + message->AddFlat("address", &network.address); BMenuItem* item = new WirelessNetworkMenuItem(network.name, network.signal_strength, @@ -274,15 +286,8 @@ InterfaceHardwareView::Update() menu->SetTargetForItems(this); } - fRenegotiate->SetEnabled(!fSettings->IsDisabled()); - fOnOff->SetLabel(fSettings->IsDisabled() ? "Enable" : "Disable"); + fRenegotiate->SetEnabled(!disabled); + fOnOff->SetLabel(disabled ? "Enable" : "Disable"); return B_OK; } - - -status_t -InterfaceHardwareView::Save() -{ - return B_OK; -} diff --git a/src/preferences/network/InterfacesAddOn/InterfaceHardwareView.h b/src/preferences/network/InterfaceView.h similarity index 55% rename from src/preferences/network/InterfacesAddOn/InterfaceHardwareView.h rename to src/preferences/network/InterfaceView.h index 36f8a5477f..be495351ed 100644 --- a/src/preferences/network/InterfacesAddOn/InterfaceHardwareView.h +++ b/src/preferences/network/InterfaceView.h @@ -1,48 +1,44 @@ /* - * Copyright 2004-2013 Haiku, Inc. All rights reserved. + * Copyright 2004-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: + * Axel Dörfler, * Alexander von Gluck, kallisti5@unixzen.com * John Scipione, jscipione@gmail.com */ -#ifndef INTERFACE_HARDWARE_VIEW_H -#define INTERFACE_HARDWARE_VIEW_H +#ifndef INTERFACE_VIEW_H +#define INTERFACE_VIEW_H -#include "NetworkSettings.h" - #include - - -static const uint32 kMsgInterfaceToggle = 'onof'; -static const uint32 kMsgInterfaceRenegotiate = 'redo'; +#include class BButton; class BMenuField; class BMessage; -class BRect; class BStringView; -class InterfaceHardwareView : public BGroupView { + +class InterfaceView : public BGroupView { public: - InterfaceHardwareView( - NetworkSettings* settings); - virtual ~InterfaceHardwareView(); + InterfaceView(); + virtual ~InterfaceView(); + + void SetTo(const char* name); virtual void MessageReceived(BMessage* message); virtual void AttachedToWindow(); - void Pulse(); - status_t Revert(); - status_t Save(); + virtual void Pulse(); private: - status_t Update(); - + status_t _Update(bool updateWirelessNetworks = true); void _EnableFields(bool enabled); - NetworkSettings* fSettings; +private: + BNetworkInterface fInterface; + int fPulseCount; BStringView* fStatusField; BStringView* fMacAddressField; diff --git a/src/preferences/network/Jamfile b/src/preferences/network/Jamfile index 0b3ac4e004..055d5b64a0 100644 --- a/src/preferences/network/Jamfile +++ b/src/preferences/network/Jamfile @@ -3,7 +3,8 @@ SubDir HAIKU_TOP src preferences network ; UsePublicHeaders [ FDirName add-ons network_settings ] ; UsePrivateHeaders net shared ; -SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src apps networkstatus ] ; +SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src apps networkstatus ] + [ FDirName $(HAIKU_TOP) src bin network ifconfig ] ; Preference Network : Network.cpp @@ -11,12 +12,16 @@ Preference Network : NetworkProfile.cpp NetworkSettingsAddOn.cpp InterfaceListItem.cpp + InterfaceView.cpp # from NetworkStatus RadioView.cpp WirelessNetworkMenuItem.cpp - : be root bnetapi [ TargetLibstdc++ ] localestub + # from ifconfig + MediaTypes.cpp + + : be bnetapi libshared.a [ TargetLibstdc++ ] localestub : Network.rdef InterfaceIcons.rdef ; diff --git a/src/preferences/network/NetworkWindow.cpp b/src/preferences/network/NetworkWindow.cpp index a1e6417b3a..b47ae03bcf 100644 --- a/src/preferences/network/NetworkWindow.cpp +++ b/src/preferences/network/NetworkWindow.cpp @@ -40,6 +40,7 @@ #endif #include "InterfaceListItem.h" +#include "InterfaceView.h" const char* kNetworkStatusSignature = "application/x-vnd.Haiku-NetworkStatus"; @@ -59,7 +60,7 @@ static const uint32 kMsgItemSelected = 'ItSl'; NetworkWindow::NetworkWindow() : - BWindow(BRect(100, 100, 300, 300), B_TRANSLATE("Network"), B_TITLED_WINDOW, + BWindow(BRect(100, 100, 400, 400), B_TRANSLATE("Network"), B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS) { // Profiles section @@ -98,6 +99,12 @@ NetworkWindow::NetworkWindow() BScrollView* scrollView = new BScrollView("ScrollView", fListView, 0, false, true); + fAddOnShellView = new BView("add-on shell", 0, + new BGroupLayout(B_VERTICAL)); + fAddOnShellView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + fInterfaceView = new InterfaceView(); + // Build the layout BLayoutBuilder::Group<>(this, B_VERTICAL) .SetInsets(B_USE_DEFAULT_SPACING) @@ -110,7 +117,7 @@ NetworkWindow::NetworkWindow() #endif .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .Add(scrollView) - .AddGlue() + .Add(fAddOnShellView) .End() .Add(showReplicantCheckBox) .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) @@ -122,7 +129,11 @@ NetworkWindow::NetworkWindow() _ScanInterfaces(); _ScanAddOns(); - fAddOnView = NULL; + // Set preferred size of the list view from its contents + float width; + float height; + fListView->GetPreferredSize(&width, &height); + fListView->SetExplicitMinSize(BSize(width, std::min(height, 400.f))); CenterOnScreen(); } @@ -162,19 +173,29 @@ NetworkWindow::MessageReceived(BMessage* message) } case kMsgItemSelected: + { + BListItem* listItem = fListView->FullListItemAt( + fListView->FullListCurrentSelection()); + if (listItem == NULL) + break; + + _SelectItem(listItem); break; + } case kMsgRevert: { - for (int index = 0; index < fItems.CountItems(); index++) - fItems.ItemAt(index)->Revert(); + SettingsMap::const_iterator iterator = fSettingsMap.begin(); + for (; iterator != fSettingsMap.end(); iterator++) + iterator->second->Revert(); break; } case kMsgApply: { - for (int index = 0; index < fItems.CountItems(); index++) - fItems.ItemAt(index)->Save(); + SettingsMap::const_iterator iterator = fSettingsMap.begin(); + for (; iterator != fSettingsMap.end(); iterator++) + iterator->second->Apply(); break; } @@ -328,7 +349,7 @@ NetworkWindow::_ScanAddOns() if (item == NULL) break; - fItems.AddItem(item); + fSettingsMap[item->ListItem()] = item; // TODO: sort fListView->AddUnder(interfaceItem, item->ListItem()); } @@ -341,17 +362,29 @@ NetworkWindow::_ScanAddOns() if (item == NULL) break; - fItems.AddItem(item); + fSettingsMap[item->ListItem()] = item; // TODO: sort - fListView->AddUnder(_ItemFor(item->Type()), item->ListItem()); + fListView->AddUnder(_ListItemFor(item->Type()), + item->ListItem()); } } } } +BNetworkSettingsItem* +NetworkWindow::_SettingsItemFor(BListItem* item) +{ + SettingsMap::const_iterator found = fSettingsMap.find(item); + if (found != fSettingsMap.end()) + return found->second; + + return NULL; +} + + BListItem* -NetworkWindow::_ItemFor(BNetworkSettingsType type) +NetworkWindow::_ListItemFor(BNetworkSettingsType type) { switch (type) { case B_NETWORK_SETTINGS_TYPE_SERVICE: @@ -378,6 +411,34 @@ NetworkWindow::_ItemFor(BNetworkSettingsType type) } +void +NetworkWindow::_SelectItem(BListItem* listItem) +{ + if (fAddOnShellView->CountChildren() > 0) + fAddOnShellView->ChildAt(0)->RemoveSelf(); + + BView* nextView = NULL; + + BNetworkSettingsItem* item = _SettingsItemFor(listItem); + if (item != NULL) { + nextView = item->View(); + } else { + InterfaceListItem* item = dynamic_cast( + listItem); + if (item != NULL) { + fInterfaceView->SetTo(item->Name()); + nextView = fInterfaceView; + } + } + + if (nextView != NULL) + fAddOnShellView->AddChild(nextView); + + fAddOnShellView->Invalidate(); + InvalidateLayout(); +} + + void NetworkWindow::_ShowReplicant(bool show) { diff --git a/src/preferences/network/NetworkWindow.h b/src/preferences/network/NetworkWindow.h index 073e500798..0d84de3031 100644 --- a/src/preferences/network/NetworkWindow.h +++ b/src/preferences/network/NetworkWindow.h @@ -20,10 +20,9 @@ using namespace BNetworkKit; - -class BTabView; class BButton; class BMenu; +class InterfaceView; class NetworkWindow : public BWindow { @@ -40,7 +39,10 @@ private: void _BuildProfilesMenu(BMenu* menu, int32 what); void _ScanInterfaces(); void _ScanAddOns(); - BListItem* _ItemFor(BNetworkSettingsType type); + BNetworkSettingsItem* + _SettingsItemFor(BListItem* item); + BListItem* _ListItemFor(BNetworkSettingsType type); + void _SelectItem(BListItem* listItem); bool _IsReplicantInstalled(); void _ShowReplicant(bool show); @@ -49,6 +51,7 @@ private: typedef BObjectList AddOnList; typedef BObjectList ItemList; typedef std::map ItemMap; + typedef std::map SettingsMap; BButton* fRevertButton; BButton* fApplyButton; @@ -61,9 +64,10 @@ private: BListItem* fDialUpItem; BListItem* fOtherItem; - ItemList fItems; + SettingsMap fSettingsMap; - BView* fAddOnView; + InterfaceView* fInterfaceView; + BView* fAddOnShellView; };