2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, <axeld@pinc-software.de>
7 * Alexander von Gluck, kallisti5@unixzen.com
8 * John Scipione, jscipione@gmail.com
12 #include "InterfaceView.h"
16 #include <net/if_media.h>
20 #include <ControlLook.h>
21 #include <LayoutBuilder.h>
22 #include <NetworkAddress.h>
23 #include <NetworkDevice.h>
24 #include <StringForSize.h>
25 #include <StringView.h>
26 #include <TextControl.h>
28 #include "MediaTypes.h"
29 #include "WirelessNetworkMenuItem.h"
32 static const uint32 kMsgInterfaceToggle
= 'onof';
33 static const uint32 kMsgInterfaceRenegotiate
= 'redo';
34 static const uint32 kMsgJoinNetwork
= 'join';
37 #undef B_TRANSLATION_CONTEXT
38 #define B_TRANSLATION_CONTEXT "IntefaceView"
41 // #pragma mark - InterfaceView
44 InterfaceView::InterfaceView()
46 BGroupView(B_VERTICAL
),
49 SetFlags(Flags() | B_PULSE_NEEDED
);
51 // TODO: Small graph of throughput?
53 float minimumWidth
= be_control_look
->DefaultItemSpacing() * 16;
55 BStringView
* statusLabel
= new BStringView("status label",
56 B_TRANSLATE("Status:"));
57 statusLabel
->SetAlignment(B_ALIGN_RIGHT
);
58 fStatusField
= new BStringView("status field", "");
59 fStatusField
->SetExplicitMinSize(BSize(minimumWidth
, B_SIZE_UNSET
));
60 BStringView
* macAddressLabel
= new BStringView("mac address label",
61 B_TRANSLATE("MAC address:"));
62 macAddressLabel
->SetAlignment(B_ALIGN_RIGHT
);
63 fMacAddressField
= new BStringView("mac address field", "");
64 fMacAddressField
->SetExplicitMinSize(BSize(minimumWidth
, B_SIZE_UNSET
));
65 BStringView
* linkSpeedLabel
= new BStringView("link speed label",
66 B_TRANSLATE("Link speed:"));
67 linkSpeedLabel
->SetAlignment(B_ALIGN_RIGHT
);
68 fLinkSpeedField
= new BStringView("link speed field", "");
69 fLinkSpeedField
->SetExplicitMinSize(BSize(minimumWidth
, B_SIZE_UNSET
));
71 // TODO: These metrics may be better in a BScrollView?
72 BStringView
* linkTxLabel
= new BStringView("tx label",
73 B_TRANSLATE("Sent:"));
74 linkTxLabel
->SetAlignment(B_ALIGN_RIGHT
);
75 fLinkTxField
= new BStringView("tx field", "");
76 fLinkTxField
->SetExplicitMinSize(BSize(minimumWidth
, B_SIZE_UNSET
));
77 BStringView
* linkRxLabel
= new BStringView("rx label",
78 B_TRANSLATE("Received:"));
79 linkRxLabel
->SetAlignment(B_ALIGN_RIGHT
);
80 fLinkRxField
= new BStringView("rx field", "");
81 fLinkRxField
->SetExplicitMinSize(BSize(minimumWidth
, B_SIZE_UNSET
));
83 fNetworkMenuField
= new BMenuField(B_TRANSLATE("Network:"), new BMenu(
84 B_TRANSLATE("Choose automatically")));
85 fNetworkMenuField
->SetAlignment(B_ALIGN_RIGHT
);
86 fNetworkMenuField
->Menu()->SetLabelFromMarked(true);
88 // Construct the BButtons
89 fToggleButton
= new BButton("onoff", B_TRANSLATE("Disable"),
90 new BMessage(kMsgInterfaceToggle
));
92 fRenegotiateButton
= new BButton("heal", B_TRANSLATE("Renegotiate"),
93 new BMessage(kMsgInterfaceRenegotiate
));
94 fRenegotiateButton
->SetEnabled(false);
96 BLayoutBuilder::Group
<>(this)
98 .Add(statusLabel
, 0, 0)
99 .Add(fStatusField
, 1, 0)
100 .Add(fNetworkMenuField
->CreateLabelLayoutItem(), 0, 1)
101 .Add(fNetworkMenuField
->CreateMenuBarLayoutItem(), 1, 1)
102 .Add(macAddressLabel
, 0, 2)
103 .Add(fMacAddressField
, 1, 2)
104 .Add(linkSpeedLabel
, 0, 3)
105 .Add(fLinkSpeedField
, 1, 3)
106 .Add(linkTxLabel
, 0, 4)
107 .Add(fLinkTxField
, 1, 4)
108 .Add(linkRxLabel
, 0, 5)
109 .Add(fLinkRxField
, 1, 5)
112 .AddGroup(B_HORIZONTAL
)
115 .Add(fRenegotiateButton
)
120 InterfaceView::~InterfaceView()
126 InterfaceView::SetTo(const char* name
)
128 fInterface
.SetTo(name
);
133 InterfaceView::AttachedToWindow()
136 // Populate the fields
138 fToggleButton
->SetTarget(this);
139 fRenegotiateButton
->SetTarget(this);
144 InterfaceView::MessageReceived(BMessage
* message
)
146 switch (message
->what
) {
147 case kMsgJoinNetwork
:
150 BNetworkAddress address
;
151 if (message
->FindString("name", &name
) == B_OK
152 && message
->FindFlat("address", &address
) == B_OK
) {
153 BNetworkDevice
device(fInterface
.Name());
154 status_t status
= device
.JoinNetwork(address
);
155 if (status
!= B_OK
) {
156 // This does not really matter, as it's stored this way,
163 case kMsgInterfaceToggle
:
165 // Disable/enable interface
166 uint32 flags
= fInterface
.Flags();
167 if ((flags
& IFF_UP
) != 0)
172 if (fInterface
.SetFlags(flags
) == B_OK
)
177 case kMsgInterfaceRenegotiate
:
179 // TODO: renegotiate addresses
184 BView::MessageReceived(message
);
190 InterfaceView::Pulse()
192 // Update the wireless network menu every 5 seconds
193 _Update((fPulseCount
++ % 5) == 0);
197 /*! Populate fields with current settings.
200 InterfaceView::_Update(bool updateWirelessNetworks
)
202 BNetworkDevice
device(fInterface
.Name());
203 bool isWireless
= device
.IsWireless();
204 bool disabled
= (fInterface
.Flags() & IFF_UP
) == 0;
206 if (fInterface
.HasLink()) {
209 BString network
= "---";
210 network
.Prepend(" (");
211 network
.Prepend(B_TRANSLATE("connected"));
213 fStatusField
->SetText(network
.String());
215 fStatusField
->SetText(B_TRANSLATE("connected"));
218 fStatusField
->SetText(B_TRANSLATE("disconnected"));
220 BNetworkAddress hardwareAddress
;
221 if (device
.GetHardwareAddress(hardwareAddress
) == B_OK
)
222 fMacAddressField
->SetText(hardwareAddress
.ToString());
224 fMacAddressField
->SetText("-");
226 int media
= fInterface
.Media();
227 if ((media
& IFM_ACTIVE
) != 0)
228 fLinkSpeedField
->SetText(media_type_to_string(media
));
230 fLinkSpeedField
->SetText("-");
234 if (fInterface
.GetStats(stats
) == B_OK
) {
237 string_for_size(stats
.send
.bytes
, buffer
, sizeof(buffer
));
238 fLinkTxField
->SetText(buffer
);
240 string_for_size(stats
.receive
.bytes
, buffer
, sizeof(buffer
));
241 fLinkRxField
->SetText(buffer
);
244 // TODO: move the wireless info to a separate tab. We should have a
245 // BListView of available networks, rather than a menu, to make them more
246 // readable and easier to browse and select.
247 if (fNetworkMenuField
->IsHidden(fNetworkMenuField
) && isWireless
)
248 fNetworkMenuField
->Show();
249 else if (!fNetworkMenuField
->IsHidden(fNetworkMenuField
) && !isWireless
)
250 fNetworkMenuField
->Hide();
252 if (isWireless
&& updateWirelessNetworks
) {
253 // Rebuild network menu
254 BMenu
* menu
= fNetworkMenuField
->Menu();
255 menu
->RemoveItems(0, menu
->CountItems(), true);
257 std::set
<BNetworkAddress
> associated
;
258 BNetworkAddress address
;
260 while (device
.GetNextAssociatedNetwork(cookie
, address
) == B_OK
)
261 associated
.insert(address
);
263 wireless_network network
;
266 while (device
.GetNextNetwork(cookie
, network
) == B_OK
) {
267 BMessage
* message
= new BMessage(kMsgJoinNetwork
);
269 message
->AddString("device", fInterface
.Name());
270 message
->AddString("name", network
.name
);
271 message
->AddFlat("address", &network
.address
);
273 BMenuItem
* item
= new WirelessNetworkMenuItem(network
.name
,
274 network
.signal_strength
,
275 network
.authentication_mode
, message
);
276 if (associated
.find(network
.address
) != associated
.end())
277 item
->SetMarked(true);
283 BMenuItem
* item
= new BMenuItem(
284 B_TRANSLATE("<no wireless networks found>"), NULL
);
285 item
->SetEnabled(false);
288 BMenuItem
* item
= new BMenuItem(
289 B_TRANSLATE("Choose automatically"), NULL
);
290 if (menu
->FindMarked() == NULL
)
291 item
->SetMarked(true);
292 menu
->AddItem(item
, 0);
293 menu
->AddItem(new BSeparatorItem(), 1);
295 menu
->SetTargetForItems(this);
298 //fRenegotiateButton->SetEnabled(!disabled);
299 fToggleButton
->SetLabel(disabled
? "Enable" : "Disable");