BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / add-ons / network_settings / dnsclient / DNSSettingsView.cpp
blob131ec34552e93112b97d4e37b24e25874d3ed9ea
1 /*
2 * Copyright 2014-2015 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Adrien Destugues, pulkomandy@pulkomandy.tk
7 */
10 #include "DNSSettingsView.h"
12 #include <arpa/inet.h>
13 #include <netinet/in.h>
14 #include <resolv.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <sys/socket.h>
19 #include <Box.h>
20 #include <Button.h>
21 #include <Catalog.h>
22 #include <ControlLook.h>
23 #include <File.h>
24 #include <FindDirectory.h>
25 #include <LayoutBuilder.h>
26 #include <ListView.h>
27 #include <Path.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)
48 BView("dns", 0),
49 fItem(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),
82 0, 1, 1, 3)
83 .Add(fUpButton, 1, 1)
84 .Add(fDownButton, 1, 2)
85 .Add(fRemoveButton, 1, 3)
86 .SetColumnWeight(0, 10.f);
88 BLayoutBuilder::Group<>(this, B_VERTICAL)
89 .Add(titleView)
90 .Add(serviceGridView)
91 .Add(new BSeparatorView(B_HORIZONTAL))
92 .Add(fDomain)
93 .AddStrut(spacing)
94 .AddGroup(B_HORIZONTAL)
95 .AddGlue()
96 .Add(fApplyButton);
98 _LoadDNSConfiguration();
102 DNSSettingsView::~DNSSettingsView()
107 status_t
108 DNSSettingsView::Revert()
110 int i;
111 for (i = 0; i < fRevertList.CountStrings(); i++) {
112 BStringItem* item = static_cast<BStringItem*>(
113 fServerListView->ItemAt(i));
114 if (item == NULL) {
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);
126 return B_OK;
130 bool
131 DNSSettingsView::IsRevertable() const
133 // TODO
134 return false;
138 void
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);
152 void
153 DNSSettingsView::MessageReceived(BMessage* message)
155 switch (message->what) {
156 case kMsgAddServer:
158 const char* address = fTextControl->Text();
159 fServerListView->AddItem(new BStringItem(address));
160 break;
162 case kMsgDeleteServer:
163 delete fServerListView->RemoveItem(
164 fServerListView->CurrentSelection());
165 break;
167 case kMsgMoveUp:
169 int index = fServerListView->CurrentSelection();
170 if (index > 0)
171 fServerListView->SwapItems(index, index - 1);
172 break;
174 case kMsgMoveDown:
176 int index = fServerListView->CurrentSelection();
177 if (index < fServerListView->CountItems() - 1)
178 fServerListView->SwapItems(index, index + 1);
179 break;
181 case kMsgApply:
182 if (_SaveDNSConfiguration() == B_OK)
183 fItem->NotifySettingsUpdated();
184 break;
186 default:
187 BView::MessageReceived(message);
188 break;
193 status_t
194 DNSSettingsView::_LoadDNSConfiguration()
196 if (res_init() != 0)
197 return B_ERROR;
199 res_state state = __res_get_state();
201 if (state != NULL) {
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);
211 return B_OK;
214 return B_ERROR;
218 status_t
219 DNSSettingsView::_SaveDNSConfiguration()
221 BPath path;
222 status_t status;
223 status = find_directory(B_SYSTEM_SETTINGS_DIRECTORY, &path);
224 if (status != B_OK)
225 return status;
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());