2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Alexander von Gluck, kallisti5@unixzen.com
7 * John Scipione, jscipione@gmail.com
11 #include "InterfaceAddressView.h"
17 #include <ControlLook.h>
18 #include <LayoutBuilder.h>
20 #include <MenuField.h>
21 #include <PopUpMenu.h>
24 #include <StringView.h>
25 #include <TextControl.h>
27 #include "IPAddressControl.h"
30 #undef B_TRANSLATION_CONTEXT
31 #define B_TRANSLATION_CONTEXT "IntefaceAddressView"
34 const uint32 kModeAuto
= 'iato';
35 const uint32 kModeStatic
= 'istc';
36 const uint32 kModeDisabled
= 'ioff';
37 const uint32 kMsgApply
= 'aply';
40 // #pragma mark - InterfaceAddressView
43 InterfaceAddressView::InterfaceAddressView(int family
,
44 const char* interface
, BNetworkSettings
& settings
)
46 BGroupView(B_VERTICAL
),
48 fInterface(interface
),
51 SetLayout(new BGroupLayout(B_VERTICAL
));
53 // Create our controls
54 fModePopUpMenu
= new BPopUpMenu("modes");
56 if (fFamily
== AF_INET
) {
57 fModePopUpMenu
->AddItem(new BMenuItem(B_TRANSLATE("DHCP"),
58 new BMessage(kModeAuto
)));
61 if (fFamily
== AF_INET6
) {
62 // Automatic can be DHCPv6 or Router Advertisements
63 fModePopUpMenu
->AddItem(new BMenuItem(B_TRANSLATE("Automatic"),
64 new BMessage(kModeAuto
)));
67 fModePopUpMenu
->AddItem(new BMenuItem(B_TRANSLATE("Static"),
68 new BMessage(kModeStatic
)));
69 fModePopUpMenu
->AddSeparatorItem();
70 fModePopUpMenu
->AddItem(new BMenuItem(B_TRANSLATE("Disabled"),
71 new BMessage(kModeDisabled
)));
73 fModeField
= new BMenuField(B_TRANSLATE("Mode:"), fModePopUpMenu
);
74 fModeField
->SetToolTip(
75 B_TRANSLATE("The method for obtaining an IP address"));
77 float minimumWidth
= be_control_look
->DefaultItemSpacing() * 15;
79 fAddressField
= new IPAddressControl(fFamily
, B_TRANSLATE("IP Address:"),
81 fAddressField
->SetToolTip(B_TRANSLATE("Your IP address"));
82 fAddressField
->TextView()->SetExplicitMinSize(
83 BSize(minimumWidth
, B_SIZE_UNSET
));
84 fAddressField
->SetAllowEmpty(false);
85 fNetmaskField
= new IPAddressControl(fFamily
, B_TRANSLATE("Netmask:"),
87 fNetmaskField
->SetToolTip(B_TRANSLATE(
88 "The netmask defines your local network"));
89 fNetmaskField
->TextView()->SetExplicitMinSize(
90 BSize(minimumWidth
, B_SIZE_UNSET
));
91 fGatewayField
= new IPAddressControl(fFamily
, B_TRANSLATE("Gateway:"),
93 fGatewayField
->SetToolTip(B_TRANSLATE("Your gateway to the internet"));
94 fGatewayField
->TextView()->SetExplicitMinSize(
95 BSize(minimumWidth
, B_SIZE_UNSET
));
97 fApplyButton
= new BButton("apply", B_TRANSLATE("Apply"),
98 new BMessage(kMsgApply
));
100 fSettings
.GetInterface(interface
, fOriginalSettings
);
103 BLayoutBuilder::Group
<>(this)
105 .AddMenuField(fModeField
, 0, 0, B_ALIGN_RIGHT
)
106 .AddTextControl(fAddressField
, 0, 1, B_ALIGN_RIGHT
)
107 .AddTextControl(fNetmaskField
, 0, 2, B_ALIGN_RIGHT
)
108 .AddTextControl(fGatewayField
, 0, 3, B_ALIGN_RIGHT
)
110 .AddGroup(B_HORIZONTAL
)
118 InterfaceAddressView::~InterfaceAddressView()
123 // #pragma mark - InterfaceAddressView virtual methods
127 InterfaceAddressView::AttachedToWindow()
129 fModePopUpMenu
->SetTargetForItems(this);
130 fApplyButton
->SetTarget(this);
135 InterfaceAddressView::MessageReceived(BMessage
* message
)
137 switch (message
->what
) {
141 if (message
->what
== fLastMode
)
144 _SetModeField(message
->what
);
145 if (message
->what
!= kModeStatic
)
154 BView::MessageReceived(message
);
159 // #pragma mark - InterfaceAddressView public methods
163 InterfaceAddressView::Revert()
165 return fSettings
.AddInterface(fOriginalSettings
);
170 InterfaceAddressView::IsRevertable() const
173 fSettings
.GetInterface(fInterface
.Name(), settings
);
175 return !settings
.HasSameData(fOriginalSettings
);
180 InterfaceAddressView::ConfigurationUpdated(const BMessage
& message
)
182 const char* interface
= message
.GetString("interface", NULL
);
183 if (interface
== NULL
|| strcmp(interface
, fInterface
.Name()) != 0)
190 // #pragma mark - InterfaceAddressView private methods
194 InterfaceAddressView::_EnableFields(bool enable
)
196 fAddressField
->SetEnabled(enable
);
197 fNetmaskField
->SetEnabled(enable
);
198 fGatewayField
->SetEnabled(enable
);
199 fApplyButton
->SetEnabled(enable
);
203 /*! Updates the UI to match the current interface configuration.
205 The interface settings may be consulted to determine if the
206 automatic configuration has been specified, if there was no
210 InterfaceAddressView::_UpdateFields()
212 BMessage interfaceSettings
;
213 fSettings
.GetInterface(fInterface
.Name(), interfaceSettings
);
215 bool autoConfigure
= interfaceSettings
.IsEmpty();
216 if (!autoConfigure
) {
217 BNetworkInterfaceSettings
settings(interfaceSettings
);
218 autoConfigure
= settings
.IsAutoConfigure(fFamily
);
221 BNetworkInterfaceAddress address
;
222 status_t status
= B_ERROR
;
224 int32 index
= fInterface
.FindFirstAddress(fFamily
);
226 status
= fInterface
.GetAddressAt(index
, address
);
227 if (!autoConfigure
&& (index
< 0 || status
!= B_OK
228 || address
.Address().IsEmpty())) {
229 _SetModeField(kModeDisabled
);
234 _SetModeField(kModeAuto
);
236 _SetModeField(kModeStatic
);
238 fAddressField
->SetText(address
.Address().ToString());
239 fNetmaskField
->SetText(address
.Mask().ToString());
241 BNetworkAddress gateway
;
242 if (fInterface
.GetDefaultGateway(fFamily
, gateway
) == B_OK
)
243 fGatewayField
->SetText(gateway
.ToString());
245 fGatewayField
->SetText(NULL
);
250 InterfaceAddressView::_SetModeField(uint32 mode
)
252 BMenuItem
* item
= fModePopUpMenu
->FindItem(mode
);
254 item
->SetMarked(true);
256 _EnableFields(mode
== kModeStatic
);
258 if (mode
== kModeDisabled
) {
259 fAddressField
->SetText(NULL
);
260 fNetmaskField
->SetText(NULL
);
261 fGatewayField
->SetText(NULL
);
262 } else if (mode
== kModeStatic
)
263 fAddressField
->MakeFocus(true);
269 /*! Updates the current settings from the controls. */
271 InterfaceAddressView::_UpdateSettings()
274 fSettings
.GetInterface(fInterface
.Name(), interface
);
275 BNetworkInterfaceSettings
settings(interface
);
277 settings
.SetName(fInterface
.Name());
279 // Remove previous address for family
281 int32 index
= settings
.FindFirstAddress(fFamily
);
283 index
= settings
.FindFirstAddress(AF_UNSPEC
);
284 if (index
>= 0 && index
< settings
.CountAddresses()) {
285 BNetworkInterfaceAddressSettings
& address
= settings
.AddressAt(index
);
286 _ConfigureAddress(address
);
288 BNetworkInterfaceAddressSettings address
;
289 _ConfigureAddress(address
);
290 settings
.AddAddress(address
);
293 interface
.MakeEmpty();
295 // TODO: better error reporting!
296 status_t status
= settings
.GetMessage(interface
);
298 fSettings
.AddInterface(interface
);
300 fprintf(stderr
, "Could not add interface: %s\n", strerror(status
));
305 InterfaceAddressView::_Mode() const
307 uint32 mode
= kModeAuto
;
308 BMenuItem
* item
= fModePopUpMenu
->FindMarked();
310 mode
= item
->Message()->what
;
317 InterfaceAddressView::_ConfigureAddress(
318 BNetworkInterfaceAddressSettings
& settings
)
320 uint32 mode
= _Mode();
322 settings
.SetFamily(fFamily
);
323 settings
.SetAutoConfigure(mode
== kModeAuto
);
325 settings
.Address().Unset();
326 settings
.Mask().Unset();
327 settings
.Peer().Unset();
328 settings
.Broadcast().Unset();
329 settings
.Gateway().Unset();
331 if (mode
== kModeStatic
) {
332 _SetAddress(settings
.Address(), fAddressField
->Text());
333 _SetAddress(settings
.Mask(), fNetmaskField
->Text());
334 _SetAddress(settings
.Gateway(), fGatewayField
->Text());
340 InterfaceAddressView::_SetAddress(BNetworkAddress
& address
, const char* text
)
342 BString
string(text
);
344 if (string
.IsEmpty())
347 address
.SetTo(string
.String(), static_cast<uint16
>(0),
348 B_NO_ADDRESS_RESOLUTION
);