diff --git a/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h b/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h index 3bd9d42778..89371a6ca2 100644 --- a/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h +++ b/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h @@ -10,9 +10,13 @@ #include #include #include +#include #include +class BNetworkAddress; + + namespace BNetworkKit { @@ -31,7 +35,14 @@ class BNetworkProfile; class BNetworkSettings; -class BNetworkSettingsItem { +class BNetworkConfigurationListener { +public: + virtual void ConfigurationUpdated( + const BMessage& message) = 0; +}; + + +class BNetworkSettingsItem : public BNetworkConfigurationListener { public: BNetworkSettingsItem(); virtual ~BNetworkSettingsItem(); @@ -73,6 +84,36 @@ private: }; +class BNetworkInterfaceListItem : public BListItem, + public BNetworkConfigurationListener { +public: + BNetworkInterfaceListItem(int family, + const char* interface, const char* label, + BNetworkSettings& settings); + ~BNetworkInterfaceListItem(); + + virtual void DrawItem(BView* owner, + BRect bounds, bool complete); + virtual void Update(BView* owner, const BFont* font); + + virtual void ConfigurationUpdated(const BMessage& message); + +private: + BFont _AddressFont(); + void _UpdateState(); + +private: + BNetworkSettings& fSettings; + int fFamily; + const char* fInterface; + const char* fLabel; + BString fAddress; + bool fDisabled; + float fLineOffset; + float fSpacing; +}; + + class BNetworkSettingsAddOn { public: BNetworkSettingsAddOn(image_id image, diff --git a/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp b/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp index f4856ac424..9d263b7391 100644 --- a/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp +++ b/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp @@ -49,7 +49,8 @@ public: private: BNetworkSettings& fSettings; - BStringItem* fItem; + BNetworkInterfaceListItem* + fItem; InterfaceAddressView* fView; }; @@ -63,7 +64,8 @@ IPv4InterfaceItem::IPv4InterfaceItem(const char* interface, : BNetworkSettingsInterfaceItem(interface), fSettings(settings), - fItem(new BStringItem(B_TRANSLATE("IPv4"))), + fItem(new BNetworkInterfaceListItem(AF_INET, Interface(), + B_TRANSLATE("IPv4"), settings)), fView(NULL) { } diff --git a/src/add-ons/network_settings/ipv6/IPv6InterfaceAddOn.cpp b/src/add-ons/network_settings/ipv6/IPv6InterfaceAddOn.cpp index db56aa6b94..3eb440c2ce 100644 --- a/src/add-ons/network_settings/ipv6/IPv6InterfaceAddOn.cpp +++ b/src/add-ons/network_settings/ipv6/IPv6InterfaceAddOn.cpp @@ -49,7 +49,8 @@ public: private: BNetworkSettings& fSettings; - BStringItem* fItem; + BNetworkInterfaceListItem* + fItem; InterfaceAddressView* fView; }; @@ -63,7 +64,8 @@ IPv6InterfaceItem::IPv6InterfaceItem(const char* interface, : BNetworkSettingsInterfaceItem(interface), fSettings(settings), - fItem(new BStringItem(B_TRANSLATE("IPv6"))), + fItem(new BNetworkInterfaceListItem(AF_INET6, Interface(), + B_TRANSLATE("IPv6"), settings)), fView(NULL) { } diff --git a/src/preferences/network/InterfaceListItem.cpp b/src/preferences/network/InterfaceListItem.cpp index f295576c74..502fb30d6f 100644 --- a/src/preferences/network/InterfaceListItem.cpp +++ b/src/preferences/network/InterfaceListItem.cpp @@ -24,7 +24,7 @@ #include -#define ICON_SIZE 37 +#define ICON_SIZE 32 #undef B_TRANSLATION_CONTEXT @@ -53,43 +53,39 @@ InterfaceListItem::~InterfaceListItem() void InterfaceListItem::DrawItem(BView* owner, BRect bounds, bool complete) { - BOutlineListView* list = dynamic_cast(owner); - if (list == NULL) - return; - owner->PushState(); - rgb_color lowColor = list->LowColor(); + rgb_color lowColor = owner->LowColor(); if (IsSelected() || complete) { if (IsSelected()) { - list->SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR)); - list->SetLowColor(list->HighColor()); + owner->SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR)); + owner->SetLowColor(owner->HighColor()); } else - list->SetHighColor(lowColor); + owner->SetHighColor(lowColor); - list->FillRect(bounds); + owner->FillRect(bounds); } BBitmap* stateIcon = _StateIcon(); const char* stateText = _StateText(); // Set the initial bounds of item contents - BPoint iconPoint = bounds.LeftTop() + BPoint(4, 4); + BPoint iconPoint = bounds.LeftTop() + BPoint(4, 2); BPoint statePoint = bounds.RightTop() + BPoint(0, fFirstLineOffset) - BPoint(be_plain_font->StringWidth(stateText) + 4.0f, 0); BPoint namePoint = bounds.LeftTop() + BPoint(ICON_SIZE + 12, fFirstLineOffset); if (fDisabled) { - list->SetDrawingMode(B_OP_ALPHA); - list->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); - list->SetHighColor(0, 0, 0, 32); + owner->SetDrawingMode(B_OP_ALPHA); + owner->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); + owner->SetHighColor(0, 0, 0, 32); } else - list->SetDrawingMode(B_OP_OVER); + owner->SetDrawingMode(B_OP_OVER); - list->DrawBitmapAsync(fIcon, iconPoint); - list->DrawBitmapAsync(stateIcon, iconPoint); + owner->DrawBitmapAsync(fIcon, iconPoint); + owner->DrawBitmapAsync(stateIcon, iconPoint); if (fDisabled) { rgb_color textColor; @@ -99,30 +95,25 @@ InterfaceListItem::DrawItem(BView* owner, BRect bounds, bool complete) textColor = ui_color(B_LIST_ITEM_TEXT_COLOR); if (textColor.red + textColor.green + textColor.blue > 128 * 3) - list->SetHighColor(tint_color(textColor, B_DARKEN_1_TINT)); + owner->SetHighColor(tint_color(textColor, B_DARKEN_1_TINT)); else - list->SetHighColor(tint_color(textColor, B_LIGHTEN_1_TINT)); + owner->SetHighColor(tint_color(textColor, B_LIGHTEN_1_TINT)); } else { if (IsSelected()) - list->SetHighColor(ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR)); + owner->SetHighColor(ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR)); else - list->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR)); + owner->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR)); } - list->SetFont(be_bold_font); + owner->SetFont(be_bold_font); - list->DrawString(fDeviceName, namePoint); - list->SetFont(be_plain_font); - list->DrawString(stateText, statePoint); + owner->DrawString(fDeviceName, namePoint); + owner->SetFont(be_plain_font); + owner->DrawString(stateText, statePoint); BPoint linePoint = bounds.LeftTop() + BPoint(ICON_SIZE + 12, fFirstLineOffset + fLineOffset); - - for (size_t line = 0; line < sizeof(fAddress) / sizeof(fAddress[0]); - line++) { - list->DrawString(fAddress[line], linePoint); - linePoint.y += fLineOffset; - } + owner->DrawString(fSubtitle, linePoint); owner->PopState(); } @@ -146,7 +137,7 @@ InterfaceListItem::Update(BView* owner, const BFont* font) SetWidth(fIcon->Bounds().Width() + 44 + be_bold_font->StringWidth(fDeviceName.String()) + owner->StringWidth(_StateText())); - SetHeight(std::max(3 * lineHeight + 4, fIcon->Bounds().Height() + 8)); + SetHeight(std::max(2 * lineHeight + 4, fIcon->Bounds().Height() + 4)); // either to the text height or icon height, whichever is taller } @@ -255,23 +246,13 @@ InterfaceListItem::_UpdateState() fHasLink = fInterface.HasLink(); fConnecting = (fInterface.Flags() & IFF_CONFIGURING) != 0; - int32 count = fInterface.CountAddresses(); - int lastFamily = -1; - 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) { - if (address.Address().IsEmpty() - || lastFamily == address.Address().Family()) - continue; - - fAddress[addressIndex++] = address.Address().ToString(); - lastFamily = address.Address().Family(); - } - } + BNetworkDevice device(Name()); + if (device.IsWireless()) + fSubtitle = B_TRANSLATE("Wireless device"); + else if (device.IsEthernet()) + fSubtitle = B_TRANSLATE("Ethernet device"); + else + fSubtitle = ""; } diff --git a/src/preferences/network/InterfaceListItem.h b/src/preferences/network/InterfaceListItem.h index 6141a37d40..2725793729 100644 --- a/src/preferences/network/InterfaceListItem.h +++ b/src/preferences/network/InterfaceListItem.h @@ -14,12 +14,14 @@ #include #include +#include class BBitmap; -class InterfaceListItem : public BListItem { +class InterfaceListItem : public BListItem, + public BNetworkKit::BNetworkConfigurationListener { public: InterfaceListItem(const char* name); ~InterfaceListItem(); @@ -30,7 +32,7 @@ public: inline const char* Name() { return fInterface.Name(); } - void ConfigurationUpdated(const BMessage& message); + virtual void ConfigurationUpdated(const BMessage& message); private: void _Init(); @@ -55,7 +57,7 @@ private: bool fDisabled; bool fHasLink; bool fConnecting; - BString fAddress[2]; + BString fSubtitle; }; diff --git a/src/preferences/network/NetworkSettingsAddOn.cpp b/src/preferences/network/NetworkSettingsAddOn.cpp index b1ee4a6511..7b54fb4ef4 100644 --- a/src/preferences/network/NetworkSettingsAddOn.cpp +++ b/src/preferences/network/NetworkSettingsAddOn.cpp @@ -9,6 +9,11 @@ #include #include +#include +#include +#include +#include + using namespace BNetworkKit; @@ -85,6 +90,137 @@ BNetworkSettingsInterfaceItem::Interface() const // #pragma mark - +BNetworkInterfaceListItem::BNetworkInterfaceListItem(int family, + const char* interface, const char* label, BNetworkSettings& settings) + : + fSettings(settings), + fFamily(family), + fInterface(interface), + fLabel(label) +{ +} + + +BNetworkInterfaceListItem::~BNetworkInterfaceListItem() +{ +} + + +void +BNetworkInterfaceListItem::DrawItem(BView* owner, BRect bounds, bool complete) +{ + owner->PushState(); + + if (IsSelected() || complete) { + if (IsSelected()) { + owner->SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR)); + owner->SetLowColor(owner->HighColor()); + } else + owner->SetHighColor(owner->LowColor()); + + owner->FillRect(bounds); + } + + // Set the initial bounds of item contents + BPoint labelLocation = bounds.LeftTop() + BPoint(fSpacing, fLineOffset); + + if (fDisabled) { + rgb_color textColor; + if (IsSelected()) + textColor = ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR); + else + textColor = ui_color(B_LIST_ITEM_TEXT_COLOR); + + if (textColor.red + textColor.green + textColor.blue > 128 * 3) + owner->SetHighColor(tint_color(textColor, B_DARKEN_1_TINT)); + else + owner->SetHighColor(tint_color(textColor, B_LIGHTEN_1_TINT)); + } else { + if (IsSelected()) + owner->SetHighColor(ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR)); + else + owner->SetHighColor(ui_color(B_LIST_ITEM_TEXT_COLOR)); + } + + owner->SetFont(be_plain_font); + owner->DrawString(fLabel, labelLocation); + + if (!fAddress.IsEmpty()) { + BFont font = _AddressFont(); + owner->MovePenBy(fSpacing, 0); + owner->SetFont(&font); + owner->DrawString(fAddress); + } + + owner->PopState(); +} + + +void +BNetworkInterfaceListItem::Update(BView* owner, const BFont* font) +{ + _UpdateState(); + + fSpacing = be_control_look->DefaultLabelSpacing(); + + BListItem::Update(owner, font); + font_height height; + font->GetHeight(&height); + + float lineHeight = ceilf(height.ascent) + ceilf(height.descent) + + ceilf(height.leading); + fLineOffset = 2 + ceilf(height.ascent + height.leading / 2); + + SetWidth(owner->StringWidth(fLabel) + 2 * fSpacing + + _AddressFont().StringWidth(fAddress.String())); + SetHeight(lineHeight + 4); +} + + +void +BNetworkInterfaceListItem::ConfigurationUpdated(const BMessage& message) +{ + _UpdateState(); +} + + +BFont +BNetworkInterfaceListItem::_AddressFont() +{ + BFont font; + font.SetFace(B_ITALIC_FACE); + font.SetSize(font.Size() * 0.9f); + return font; +} + + +void +BNetworkInterfaceListItem::_UpdateState() +{ + BNetworkInterfaceAddress address; + BNetworkInterface interface(fInterface); + + bool autoConfigure = fSettings.Interface(fInterface).IsAutoConfigure( + fFamily); + + fAddress = ""; + fDisabled = !autoConfigure; + + int32 index = interface.FindFirstAddress(fFamily); + if (index < 0) + return; + + interface.GetAddressAt(index, address); + + fDisabled = address.Address().IsEmpty() && !autoConfigure; + if (!address.Address().IsEmpty()) + fAddress << "(" << address.Address().ToString() << ")"; +} + + +// #pragma mark - + + BNetworkSettingsAddOn::BNetworkSettingsAddOn(image_id image, BNetworkSettings& settings) : diff --git a/src/preferences/network/NetworkWindow.cpp b/src/preferences/network/NetworkWindow.cpp index ada463a54a..03654eca3f 100644 --- a/src/preferences/network/NetworkWindow.cpp +++ b/src/preferences/network/NetworkWindow.cpp @@ -349,11 +349,10 @@ NetworkWindow::_ScanAddOns() fAddOns.AddItem(addOn); // Per interface items - InterfaceItemMap::const_iterator iterator - = fInterfaceItemMap.begin(); + ItemMap::const_iterator iterator = fInterfaceItemMap.begin(); for (; iterator != fInterfaceItemMap.end(); iterator++) { const BString& interface = iterator->first; - InterfaceListItem* interfaceItem = iterator->second; + BListItem* interfaceItem = iterator->second; uint32 cookie = 0; while (true) { @@ -463,9 +462,13 @@ NetworkWindow::_BroadcastSettingsUpdate(uint32 type) void NetworkWindow::_BroadcastConfigurationUpdate(const BMessage& message) { - InterfaceItemMap::const_iterator itemIterator = fInterfaceItemMap.begin(); - for (; itemIterator != fInterfaceItemMap.end(); itemIterator++) - itemIterator->second->ConfigurationUpdated(message); + for (int32 index = 0; index < fListView->FullListCountItems(); index++) { + BNetworkConfigurationListener* listener + = dynamic_cast( + fListView->FullListItemAt(index)); + if (listener != NULL) + listener->ConfigurationUpdated(message); + } SettingsMap::const_iterator iterator = fSettingsMap.begin(); for (; iterator != fSettingsMap.end(); iterator++) diff --git a/src/preferences/network/NetworkWindow.h b/src/preferences/network/NetworkWindow.h index b08b0d5e18..5b55745eb8 100644 --- a/src/preferences/network/NetworkWindow.h +++ b/src/preferences/network/NetworkWindow.h @@ -55,14 +55,14 @@ private: private: typedef BObjectList AddOnList; typedef BObjectList ItemList; - typedef std::map InterfaceItemMap; + typedef std::map ItemMap; typedef std::map SettingsMap; BNetworkSettings fSettings; AddOnList fAddOns; BOutlineListView* fListView; - InterfaceItemMap fInterfaceItemMap; + ItemMap fInterfaceItemMap; BListItem* fServicesItem; BListItem* fDialUpItem; BListItem* fOtherItem;