xref: /haiku/src/preferences/bluetooth/BluetoothSettingsView.cpp (revision f8da8f3477d3c18142e59d17d05a545982faa5a8)
1 /*
2  * Copyright 2008-2009, Oliver Ruiz Dorantes <oliver.ruiz.dorantes@gmail.com>
3  * Copyright 2012-2013, Tri-Edge AI, <triedgeai@gmail.com>
4  *
5  * All rights reserved. Distributed under the terms of the MIT License.
6  */
7 
8 #include "BluetoothSettingsView.h"
9 
10 #include "defs.h"
11 #include "BluetoothSettings.h"
12 #include "BluetoothWindow.h"
13 #include "ExtendedLocalDeviceView.h"
14 
15 #include <bluetooth/LocalDevice.h>
16 
17 #include <Box.h>
18 #include <Catalog.h>
19 #include <GridLayoutBuilder.h>
20 #include <GroupLayoutBuilder.h>
21 #include <MenuField.h>
22 #include <MenuItem.h>
23 #include <PopUpMenu.h>
24 #include <Slider.h>
25 #include <SpaceLayoutItem.h>
26 #include <String.h>
27 #include <TextView.h>
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 
32 #undef B_TRANSLATION_CONTEXT
33 #define B_TRANSLATION_CONTEXT "Settings view"
34 
35 static const int32 kMsgSetConnectionPolicy = 'sCpo';
36 static const int32 kMsgSetDeviceClass = 'sDC0';
37 static const int32 kMsgSetInquiryTime = 'afEa';
38 static const int32 kMsgLocalSwitched = 'lDsW';
39 
40 static const char* kAllLabel = B_TRANSLATE_MARK("From all devices");
41 static const char* kTrustedLabel =
42 	B_TRANSLATE_MARK("Only from trusted devices");
43 static const char* kAlwaysLabel = B_TRANSLATE_MARK("Always ask");
44 
45 static const char* kDesktopLabel = B_TRANSLATE_MARK("Desktop");
46 static const char* kServerLabel = B_TRANSLATE_MARK("Server");
47 static const char* kLaptopLabel = B_TRANSLATE_MARK("Laptop");
48 static const char* kHandheldLabel = B_TRANSLATE_MARK("Handheld");
49 static const char* kPhoneLabel = B_TRANSLATE_MARK("Smart phone");
50 
51 //	#pragma mark -
52 
53 BluetoothSettingsView::BluetoothSettingsView(const char* name)
54 	:
55 	BView(name, 0),
56 	fLocalDevicesMenu(NULL)
57 {
58 	fSettings.Load();
59 
60 	_BuildConnectionPolicy();
61 	fPolicyMenuField = new BMenuField("policy",
62 		B_TRANSLATE("Incoming connections policy:"), fPolicyMenu);
63 
64 	fInquiryTimeControl = new BSlider("time",
65 		B_TRANSLATE("Default inquiry time:"), new BMessage(kMsgSetInquiryTime),
66 		0, 255, B_HORIZONTAL);
67 	fInquiryTimeControl->SetLimitLabels(B_TRANSLATE("15 secs"),
68 		B_TRANSLATE("61 secs"));
69 	fInquiryTimeControl->SetHashMarks(B_HASH_MARKS_BOTTOM);
70 	fInquiryTimeControl->SetHashMarkCount(255 / 15);
71 	fInquiryTimeControl->SetEnabled(true);
72 
73 	fExtDeviceView = new ExtendedLocalDeviceView(BRect(0, 0, 5, 5), NULL);
74 
75 	// localdevices menu
76 	_BuildLocalDevicesMenu();
77 	fLocalDevicesMenuField = new BMenuField("devices",
78 		B_TRANSLATE("Local devices found on system:"),
79 		fLocalDevicesMenu);
80 
81 	SetLayout(new BGroupLayout(B_VERTICAL));
82 
83 	if (ActiveLocalDevice != NULL) {
84 		fExtDeviceView->SetLocalDevice(ActiveLocalDevice);
85 		fExtDeviceView->SetEnabled(true);
86 
87 		DeviceClass rememberedClass = ActiveLocalDevice->GetDeviceClass();
88 
89 		if (!rememberedClass.IsUnknownDeviceClass())
90 			fSettings.Data.LocalDeviceClass = rememberedClass;
91 	}
92 
93 	// hinting menu
94 	_BuildClassMenu();
95 	fClassMenuField = new BMenuField("class", B_TRANSLATE("Identify host as:"),
96 		fClassMenu);
97 
98 	// controls pane
99 	AddChild(BGridLayoutBuilder(10, 10)
100 		.Add(fClassMenuField->CreateLabelLayoutItem(), 0, 0)
101 		.Add(fClassMenuField->CreateMenuBarLayoutItem(), 1, 0)
102 
103 		.Add(fPolicyMenuField->CreateLabelLayoutItem(), 0, 1)
104 		.Add(fPolicyMenuField->CreateMenuBarLayoutItem(), 1, 1)
105 
106 		.Add(BSpaceLayoutItem::CreateGlue(), 0, 2, 2)
107 
108 		.Add(fInquiryTimeControl, 0, 3, 2)
109 		.Add(BSpaceLayoutItem::CreateGlue(), 0, 4, 2)
110 
111 		.Add(fLocalDevicesMenuField->CreateLabelLayoutItem(), 0, 5)
112 		.Add(fLocalDevicesMenuField->CreateMenuBarLayoutItem(), 1, 5)
113 
114 		.Add(fExtDeviceView, 0, 6, 2)
115 		.Add(BSpaceLayoutItem::CreateGlue(), 0, 7, 2)
116 
117 		.SetInsets(10, 10, 10, 10)
118 	);
119 }
120 
121 
122 BluetoothSettingsView::~BluetoothSettingsView()
123 {
124 	fSettings.Save();
125 }
126 
127 
128 void
129 BluetoothSettingsView::AttachedToWindow()
130 {
131 	if (Parent() != NULL)
132 		SetViewColor(Parent()->ViewColor());
133 	else
134 		SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
135 
136 	fPolicyMenu->SetTargetForItems(this);
137 	fClassMenu->SetTargetForItems(this);
138 	fLocalDevicesMenu->SetTargetForItems(this);
139 	fInquiryTimeControl->SetTarget(this);
140 }
141 
142 
143 void
144 BluetoothSettingsView::MessageReceived(BMessage* message)
145 {
146 	switch (message->what) {
147 		case kMsgLocalSwitched:
148 		{
149 			LocalDevice* lDevice;
150 
151 			if (message->FindPointer("LocalDevice",
152 				(void**)&lDevice) == B_OK) {
153 
154 				_MarkLocalDevice(lDevice);
155 			}
156 
157 			break;
158 		}
159 		// TODO: To be fixed. :)
160 
161 		/*
162 		case kMsgSetConnectionPolicy:
163 		{
164 			//uint8 Policy;
165 			//if (message->FindInt8("Policy", (int8*)&Policy) == B_OK)
166 			break;
167 		}
168 
169 		case kMsgSetInquiryTime:
170 		{
171 			break;
172 		}
173 		*/
174 		case kMsgSetDeviceClass:
175 		{
176 			uint8 deviceClass;
177 
178 			if (message->FindInt8("DeviceClass",
179 				(int8*)&deviceClass) == B_OK) {
180 
181 				if (deviceClass == 5)
182 					_SetDeviceClass(2, 3, 0x72);
183 				else
184 					_SetDeviceClass(1, deviceClass, 0x72);
185 			}
186 
187 			break;
188 		}
189 		case kMsgRefresh:
190 		{
191 			_BuildLocalDevicesMenu();
192 			fLocalDevicesMenu->SetTargetForItems(this);
193 
194 			break;
195 		}
196 		default:
197 			BView::MessageReceived(message);
198 	}
199 }
200 
201 
202 bool
203 BluetoothSettingsView::_SetDeviceClass(uint8 major, uint8 minor,
204 	uint16 service)
205 {
206 	bool haveRun = true;
207 
208 	fSettings.Data.LocalDeviceClass.SetRecord(major, minor, service);
209 
210 	if (ActiveLocalDevice != NULL)
211 		ActiveLocalDevice->SetDeviceClass(fSettings.Data.LocalDeviceClass);
212 	else
213 		haveRun = false;
214 
215 	return haveRun;
216 }
217 
218 
219 void
220 BluetoothSettingsView::_BuildConnectionPolicy()
221 {
222 	BMessage* message = NULL;
223 	BMenuItem* item = NULL;
224 
225 	fPolicyMenu = new BPopUpMenu(B_TRANSLATE("Policy..."));
226 
227 	message = new BMessage(kMsgSetConnectionPolicy);
228 	message->AddInt8("Policy", 1);
229 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kAllLabel), message);
230 	fPolicyMenu->AddItem(item);
231 
232 	message = new BMessage(kMsgSetConnectionPolicy);
233 	message->AddInt8("Policy", 2);
234 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kTrustedLabel), message);
235 	fPolicyMenu->AddItem(item);
236 
237 	message = new BMessage(kMsgSetConnectionPolicy);
238 	message->AddInt8("Policy", 3);
239 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kAlwaysLabel), NULL);
240 	fPolicyMenu->AddItem(item);
241 }
242 
243 void
244 BluetoothSettingsView::_BuildClassMenu()
245 {
246 	BMessage* message = NULL;
247 	BMenuItem* item = NULL;
248 
249 	fClassMenu = new BPopUpMenu(B_TRANSLATE("Identify us as..."));
250 
251 	message = new BMessage(kMsgSetDeviceClass);
252 	message->AddInt8("DeviceClass", 1);
253 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kDesktopLabel), message);
254 	fClassMenu->AddItem(item);
255 
256 	if (fSettings.Data.LocalDeviceClass.MajorDeviceClass() == 1 &&
257 		fSettings.Data.LocalDeviceClass.MinorDeviceClass() == 1)
258 			item->SetMarked(true);
259 
260 	message = new BMessage(kMsgSetDeviceClass);
261 	message->AddInt8("DeviceClass", 2);
262 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kServerLabel), message);
263 	fClassMenu->AddItem(item);
264 
265 	if (fSettings.Data.LocalDeviceClass.MajorDeviceClass() == 1 &&
266 		fSettings.Data.LocalDeviceClass.MinorDeviceClass() == 2)
267 			item->SetMarked(true);
268 
269 	message = new BMessage(kMsgSetDeviceClass);
270 	message->AddInt8("DeviceClass", 3);
271 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kLaptopLabel), message);
272 	fClassMenu->AddItem(item);
273 
274 	if (fSettings.Data.LocalDeviceClass.MajorDeviceClass() == 1 &&
275 		fSettings.Data.LocalDeviceClass.MinorDeviceClass() == 3)
276 			item->SetMarked(true);
277 
278 	message = new BMessage(kMsgSetDeviceClass);
279 	message->AddInt8("DeviceClass", 4);
280 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kHandheldLabel), message);
281 	fClassMenu->AddItem(item);
282 
283 	if (fSettings.Data.LocalDeviceClass.MajorDeviceClass() == 1 &&
284 		fSettings.Data.LocalDeviceClass.MinorDeviceClass() == 4)
285 			item->SetMarked(true);
286 
287 	message = new BMessage(kMsgSetDeviceClass);
288 	message->AddInt8("DeviceClass", 5);
289 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kPhoneLabel), message);
290 	fClassMenu->AddItem(item);
291 
292 	if (fSettings.Data.LocalDeviceClass.MajorDeviceClass() == 2 &&
293 		fSettings.Data.LocalDeviceClass.MinorDeviceClass() == 3)
294 			item->SetMarked(true);
295 }
296 
297 
298 void
299 BluetoothSettingsView::_BuildLocalDevicesMenu()
300 {
301 	LocalDevice* lDevice;
302 
303 	if (!fLocalDevicesMenu)
304 		fLocalDevicesMenu = new BPopUpMenu(B_TRANSLATE("Pick device..."));
305 
306 	while (fLocalDevicesMenu->CountItems() > 0) {
307 		BMenuItem* item = fLocalDevicesMenu->RemoveItem(0L);
308 
309 		if (item != NULL) {
310 			delete item;
311 		}
312 	}
313 
314 	ActiveLocalDevice = NULL;
315 
316 	for (uint32 i = 0; i < LocalDevice::GetLocalDeviceCount(); i++) {
317 		lDevice = LocalDevice::GetLocalDevice();
318 
319 		if (lDevice != NULL) {
320 			BMessage* message = new BMessage(kMsgLocalSwitched);
321 			message->AddPointer("LocalDevice", lDevice);
322 
323 			BMenuItem* item = new BMenuItem(
324 				(lDevice->GetFriendlyName().String()), message);
325 
326 			if (bdaddrUtils::Compare(lDevice->GetBluetoothAddress(),
327 				fSettings.Data.PickedDevice)) {
328 
329 				item->SetMarked(true);
330 				ActiveLocalDevice = lDevice;
331 			}
332 
333 			fLocalDevicesMenu->AddItem(item);
334 		}
335 	}
336 }
337 
338 void
339 BluetoothSettingsView::_MarkLocalDevice(LocalDevice* lDevice)
340 {
341 	// TODO: Device integrity should be rechecked.
342 
343 	fExtDeviceView->SetLocalDevice(lDevice);
344 	fExtDeviceView->SetEnabled(true);
345 	ActiveLocalDevice = lDevice;
346 	fSettings.Data.PickedDevice = lDevice->GetBluetoothAddress();
347 }
348