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