/* * Copyright 2008-2009, Oliver Ruiz Dorantes * Copyright 2012-2013, Tri-Edge AI, * Copyright 2021, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Fredrik Modéen */ #include "BluetoothSettingsView.h" #include "defs.h" #include "BluetoothSettings.h" #include "BluetoothWindow.h" #include "ExtendedLocalDeviceView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "Settings view" static const char* kAllLabel = B_TRANSLATE_MARK("From all devices"); static const char* kTrustedLabel = B_TRANSLATE_MARK("Only from trusted devices"); static const char* kAlwaysLabel = B_TRANSLATE_MARK("Always ask"); static const char* kDesktopLabel = B_TRANSLATE_MARK("Desktop"); static const char* kServerLabel = B_TRANSLATE_MARK("Server"); static const char* kLaptopLabel = B_TRANSLATE_MARK("Laptop"); static const char* kHandheldLabel = B_TRANSLATE_MARK("Handheld"); static const char* kPhoneLabel = B_TRANSLATE_MARK("Smart phone"); // #pragma mark - BluetoothSettingsView::BluetoothSettingsView(const char* name) : BView(name, 0), fLocalDevicesMenu(NULL) { fSettings.LoadSettings(); fPolicyMenu = new BOptionPopUp("policy", B_TRANSLATE("Incoming connections policy:"), new BMessage(kMsgSetConnectionPolicy)); fPolicyMenu->AddOption(B_TRANSLATE_NOCOLLECT(kAllLabel), 1); fPolicyMenu->AddOption(B_TRANSLATE_NOCOLLECT(kTrustedLabel), 2); fPolicyMenu->AddOption(B_TRANSLATE_NOCOLLECT(kAlwaysLabel), 3); fPolicyMenu->SetValue(fSettings.Policy()); BString label(B_TRANSLATE("Default inquiry time:")); label << " " << fSettings.InquiryTime(); fInquiryTimeControl = new BSlider("time", label.String() , new BMessage(kMsgSetInquiryTime), 15, 61, B_HORIZONTAL); fInquiryTimeControl->SetLimitLabels(B_TRANSLATE("15 secs"), B_TRANSLATE("61 secs")); fInquiryTimeControl->SetHashMarks(B_HASH_MARKS_BOTTOM); fInquiryTimeControl->SetHashMarkCount(20); fInquiryTimeControl->SetEnabled(true); fInquiryTimeControl->SetValue(fSettings.InquiryTime()); fExtDeviceView = new ExtendedLocalDeviceView(NULL); // localdevices menu _BuildLocalDevicesMenu(); fLocalDevicesMenuField = new BMenuField("devices", B_TRANSLATE("Local devices found on system:"), fLocalDevicesMenu); if (ActiveLocalDevice != NULL) { fExtDeviceView->SetLocalDevice(ActiveLocalDevice); fExtDeviceView->SetEnabled(true); DeviceClass rememberedClass = ActiveLocalDevice->GetDeviceClass(); if (!rememberedClass.IsUnknownDeviceClass()) fSettings.SetLocalDeviceClass(rememberedClass); } fClassMenu = new BOptionPopUp("DeviceClass", B_TRANSLATE("Identify host as:"), new BMessage(kMsgSetDeviceClass)); fClassMenu->AddOption(B_TRANSLATE_NOCOLLECT(kDesktopLabel), 1); fClassMenu->AddOption(B_TRANSLATE_NOCOLLECT(kServerLabel), 2); fClassMenu->AddOption(B_TRANSLATE_NOCOLLECT(kLaptopLabel), 3); fClassMenu->AddOption(B_TRANSLATE_NOCOLLECT(kHandheldLabel), 4); fClassMenu->AddOption(B_TRANSLATE_NOCOLLECT(kPhoneLabel), 5); fClassMenu->SetValue(_GetClassForMenu()); BLayoutBuilder::Grid<>(this, 0) .SetInsets(10) .Add(fClassMenu, 0, 0) .Add(fPolicyMenu, 0, 1) .Add(fInquiryTimeControl, 0, 2, 2) .Add(fLocalDevicesMenuField->CreateLabelLayoutItem(), 0, 5) .Add(fLocalDevicesMenuField->CreateMenuBarLayoutItem(), 1, 5) .Add(fExtDeviceView, 0, 6, 2) .End(); } BluetoothSettingsView::~BluetoothSettingsView() { fSettings.SaveSettings(); } void BluetoothSettingsView::AttachedToWindow() { if (Parent() != NULL) SetViewColor(Parent()->ViewColor()); else SetViewUIColor(B_PANEL_BACKGROUND_COLOR); fLocalDevicesMenu->SetTargetForItems(this); fInquiryTimeControl->SetTarget(this); } void BluetoothSettingsView::MessageReceived(BMessage* message) { //message->PrintToStream(); switch (message->what) { case kMsgLocalSwitched: { LocalDevice* lDevice; if (message->FindPointer("LocalDevice", (void**)&lDevice) == B_OK) { _MarkLocalDevice(lDevice); } break; } case kMsgSetConnectionPolicy: { int32 policy; if (message->FindInt32("be:value", (int32*)&policy) == B_OK) { fSettings.SetPolicy(policy); } break; } case kMsgSetInquiryTime: { fSettings.SetInquiryTime(fInquiryTimeControl->Value()); BString label(B_TRANSLATE("Default inquiry time:")); label << " " << fInquiryTimeControl->Value(); fInquiryTimeControl->SetLabel(label.String()); break; } case kMsgSetDeviceClass: { int32 deviceClass; if (message->FindInt32("be:value", (int32*)&deviceClass) == B_OK) { if (deviceClass == 5) _SetDeviceClass(2, 3, 0x72); else _SetDeviceClass(1, deviceClass, 0x72); } break; } case kMsgRefresh: { _BuildLocalDevicesMenu(); fLocalDevicesMenu->SetTargetForItems(this); break; } default: BView::MessageReceived(message); break; } } bool BluetoothSettingsView::_SetDeviceClass(uint8 major, uint8 minor, uint16 service) { bool haveRun = true; fSettings.SetLocalDeviceClass(DeviceClass(major, minor, service)); if (ActiveLocalDevice != NULL) ActiveLocalDevice->SetDeviceClass(fSettings.LocalDeviceClass()); else haveRun = false; return haveRun; } void BluetoothSettingsView::_BuildLocalDevicesMenu() { LocalDevice* lDevice; if (!fLocalDevicesMenu) fLocalDevicesMenu = new BPopUpMenu(B_TRANSLATE("Pick device" B_UTF8_ELLIPSIS)); while (fLocalDevicesMenu->CountItems() > 0) { BMenuItem* item = fLocalDevicesMenu->RemoveItem((int32)0); if (item != NULL) { delete item; } } ActiveLocalDevice = NULL; for (uint32 i = 0; i < LocalDevice::GetLocalDeviceCount(); i++) { lDevice = LocalDevice::GetLocalDevice(); if (lDevice != NULL) { BMessage* message = new BMessage(kMsgLocalSwitched); message->AddPointer("LocalDevice", lDevice); BMenuItem* item = new BMenuItem( (lDevice->GetFriendlyName().String()), message); if (bdaddrUtils::Compare(lDevice->GetBluetoothAddress(), fSettings.PickedDevice())) { item->SetMarked(true); ActiveLocalDevice = lDevice; } fLocalDevicesMenu->AddItem(item); } } } void BluetoothSettingsView::_MarkLocalDevice(LocalDevice* lDevice) { // TODO: Device integrity should be rechecked. fExtDeviceView->SetLocalDevice(lDevice); fExtDeviceView->SetEnabled(true); ActiveLocalDevice = lDevice; fSettings.SetPickedDevice(lDevice->GetBluetoothAddress()); } int BluetoothSettingsView::_GetClassForMenu() { int deviceClass = fSettings.LocalDeviceClass().MajorDeviceClass()+ fSettings.LocalDeviceClass().MinorDeviceClass(); // As of now we only support MajorDeviceClass = 1 and MinorDeviceClass 1-4 // and MajorDeviceClass = 2 and MinorDeviceClass 3. if (fSettings.LocalDeviceClass().MajorDeviceClass() == 1 && (fSettings.LocalDeviceClass().MinorDeviceClass() > 0 && fSettings.LocalDeviceClass().MinorDeviceClass() < 5)) deviceClass -= 1; return deviceClass; }