2 * Copyright 2014-2015 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Adrien Destugues, pulkomandy@pulkomandy.tk
10 #include "DNSSettingsView.h"
12 #include <arpa/inet.h>
13 #include <netinet/in.h>
17 #include <sys/socket.h>
22 #include <ControlLook.h>
24 #include <FindDirectory.h>
25 #include <LayoutBuilder.h>
28 #include <SeparatorView.h>
29 #include <ScrollView.h>
30 #include <StringView.h>
32 #include "IPAddressControl.h"
35 static const int32 kMsgAddServer
= 'adds';
36 static const int32 kMsgDeleteServer
= 'dels';
37 static const int32 kMsgMoveUp
= 'mvup';
38 static const int32 kMsgMoveDown
= 'mvdn';
39 static const int32 kMsgApply
= 'aply';
42 #undef B_TRANSLATION_CONTEXT
43 #define B_TRANSLATION_CONTEXT "DNSSettingsView"
46 DNSSettingsView::DNSSettingsView(BNetworkSettingsItem
* item
)
51 BStringView
* titleView
= new BStringView("title",
52 B_TRANSLATE("DNS settings"));
53 titleView
->SetFont(be_bold_font
);
54 titleView
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, B_SIZE_UNSET
));
56 fServerListView
= new BListView("nameservers");
57 const char* serverLabel
= B_TRANSLATE("Server:");
58 fTextControl
= new IPAddressControl(AF_UNSPEC
, serverLabel
, "server");
59 fTextControl
->SetExplicitMinSize(BSize(fTextControl
->StringWidth("5") * 16
60 + fTextControl
->StringWidth(serverLabel
), B_SIZE_UNSET
));
62 fAddButton
= new BButton(B_TRANSLATE("Add"), new BMessage(kMsgAddServer
));
63 fAddButton
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, B_SIZE_UNSET
));
64 fUpButton
= new BButton(B_TRANSLATE("Move up"), new BMessage(kMsgMoveUp
));
65 fUpButton
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, B_SIZE_UNSET
));
66 fDownButton
= new BButton(B_TRANSLATE("Move down"),
67 new BMessage(kMsgMoveDown
));
68 fDownButton
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, B_SIZE_UNSET
));
69 fRemoveButton
= new BButton(B_TRANSLATE("Remove"),
70 new BMessage(kMsgDeleteServer
));
71 fRemoveButton
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, B_SIZE_UNSET
));
72 fDomain
= new BTextControl(B_TRANSLATE("Domain:"), "", NULL
);
73 fApplyButton
= new BButton(B_TRANSLATE("Apply"), new BMessage(kMsgApply
));
75 float spacing
= be_control_look
->DefaultItemSpacing();
77 BGridView
* serviceGridView
= new BGridView();
78 BLayoutBuilder::Grid
<>(serviceGridView
)
79 .Add(fTextControl
, 0, 0)
80 .Add(fAddButton
, 1, 0)
81 .Add(new BScrollView("scroll", fServerListView
, 0, false, true),
84 .Add(fDownButton
, 1, 2)
85 .Add(fRemoveButton
, 1, 3)
86 .SetColumnWeight(0, 10.f
);
88 BLayoutBuilder::Group
<>(this, B_VERTICAL
)
91 .Add(new BSeparatorView(B_HORIZONTAL
))
94 .AddGroup(B_HORIZONTAL
)
98 _LoadDNSConfiguration();
102 DNSSettingsView::~DNSSettingsView()
108 DNSSettingsView::Revert()
111 for (i
= 0; i
< fRevertList
.CountStrings(); i
++) {
112 BStringItem
* item
= static_cast<BStringItem
*>(
113 fServerListView
->ItemAt(i
));
115 item
= new BStringItem("");
116 fServerListView
->AddItem(item
);
119 item
->SetText(fRevertList
.StringAt(i
));
122 // Now remove any extra item
123 for (; i
< fServerListView
->CountItems(); i
++)
124 delete fServerListView
->RemoveItem(i
);
131 DNSSettingsView::IsRevertable() const
139 DNSSettingsView::AttachedToWindow()
141 fAddButton
->SetTarget(this);
142 fRemoveButton
->SetTarget(this);
143 fUpButton
->SetTarget(this);
144 fDownButton
->SetTarget(this);
146 fTextControl
->SetTarget(this);
148 fApplyButton
->SetTarget(this);
153 DNSSettingsView::MessageReceived(BMessage
* message
)
155 switch (message
->what
) {
158 const char* address
= fTextControl
->Text();
159 fServerListView
->AddItem(new BStringItem(address
));
162 case kMsgDeleteServer
:
163 delete fServerListView
->RemoveItem(
164 fServerListView
->CurrentSelection());
169 int index
= fServerListView
->CurrentSelection();
171 fServerListView
->SwapItems(index
, index
- 1);
176 int index
= fServerListView
->CurrentSelection();
177 if (index
< fServerListView
->CountItems() - 1)
178 fServerListView
->SwapItems(index
, index
+ 1);
182 if (_SaveDNSConfiguration() == B_OK
)
183 fItem
->NotifySettingsUpdated();
187 BView::MessageReceived(message
);
194 DNSSettingsView::_LoadDNSConfiguration()
199 res_state state
= __res_get_state();
202 for (int i
= 0; i
< state
->nscount
; i
++) {
203 char* address
= inet_ntoa(state
->nsaddr_list
[i
].sin_addr
);
204 fServerListView
->AddItem(new BStringItem(address
));
205 fRevertList
.Add(address
);
208 fDomain
->SetText(state
->dnsrch
[0]);
210 __res_put_state(state
);
219 DNSSettingsView::_SaveDNSConfiguration()
223 status
= find_directory(B_SYSTEM_SETTINGS_DIRECTORY
, &path
);
227 path
.Append("network/resolv.conf");
229 BFile
file(path
.Path(), B_CREATE_FILE
| B_ERASE_FILE
| B_WRITE_ONLY
);
230 if (file
.InitCheck() != B_OK
) {
231 fprintf(stderr
, "failed to open %s for writing: %s\n", path
.Path(),
232 strerror(file
.InitCheck()));
233 return file
.InitCheck();
236 BString
content("# Generated by Network preferences\n");
238 for (int i
= 0; i
< fServerListView
->CountItems(); i
++) {
239 BString item
= ((BStringItem
*)fServerListView
->ItemAt(i
))->Text();
240 if (item
.Length() > 0)
241 content
<< "nameserver\t" << item
.String() << "\n";
244 if (strlen(fDomain
->Text()) > 0)
245 content
<< "domain\t" << fDomain
->Text() << "\n";
247 return file
.Write(content
.String(), content
.Length());