* Copyright 2008-2009, Oliver Ruiz Dorantes <oliver.ruiz.dorantes@gmail.com>
* Copyright 2012-2013, Tri-Edge AI, <triedgeai@gmail.com>
* Copyright 2021, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Fredrik Modéen <fredrik_at_modeen.se>
*/
#include "BluetoothSettingsView.h"
#include "defs.h"
#include "BluetoothSettings.h"
#include "BluetoothWindow.h"
#include "ExtendedLocalDeviceView.h"
#include <bluetooth/LocalDevice.h>
#include <Box.h>
#include <Catalog.h>
#include <LayoutBuilder.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <OptionPopUp.h>
#include <Slider.h>
#include <SpaceLayoutItem.h>
#include <String.h>
#include <TextView.h>
#include <stdio.h>
#include <stdlib.h>
#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");
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);
_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)
{
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)
{
fExtDeviceView->SetLocalDevice(lDevice);
fExtDeviceView->SetEnabled(true);
ActiveLocalDevice = lDevice;
fSettings.SetPickedDevice(lDevice->GetBluetoothAddress());
}
int
BluetoothSettingsView::_GetClassForMenu()
{
int deviceClass =
fSettings.LocalDeviceClass().MajorDeviceClass()+
fSettings.LocalDeviceClass().MinorDeviceClass();
if (fSettings.LocalDeviceClass().MajorDeviceClass() == 1
&& (fSettings.LocalDeviceClass().MinorDeviceClass() > 0
&& fSettings.LocalDeviceClass().MinorDeviceClass() < 5))
deviceClass -= 1;
return deviceClass;
}