#include <stdio.h>
#include <Alert.h>
#include <Catalog.h>
#include <Messenger.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
#include <Path.h>
#include <LayoutBuilder.h>
#include <SpaceLayoutItem.h>
#include <PincodeWindow.h>
#include <bluetooth/RemoteDevice.h>
#include "BluetoothWindow.h"
#include "defs.h"
#include "InquiryPanel.h"
#include "RemoteDevicesView.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Remote devices"
static const uint32 kMsgAddDevices = 'ddDv';
static const uint32 kMsgRemoveDevice = 'rmDv';
static const uint32 kMsgPairDevice = 'trDv';
static const uint32 kMsgDisconnectDevice = 'dsDv';
static const uint32 kMsgConnComplete = 'cmDv';
static const uint32 kMsgCancelConn = 'cnDv';
class DeviceListView : public BListView
{
public:
DeviceListView(const char* name, list_view_type type)
:
BListView(name, type)
{
}
void
SelectionChanged()
{
RemoteDevicesView* remoteDevicesView = static_cast<RemoteDevicesView*>(Parent()->Parent());
remoteDevicesView->DeviceSelected();
}
};
RemoteDevicesView::RemoteDevicesView(const char* name, uint32 flags)
: BView(name, flags)
{
addButton = new BButton("add", B_TRANSLATE("Add" B_UTF8_ELLIPSIS),
new BMessage(kMsgAddDevices));
removeButton = new BButton("remove", B_TRANSLATE("Remove"),
new BMessage(kMsgRemoveDevice));
pairButton = new BButton("pair", B_TRANSLATE("Pair" B_UTF8_ELLIPSIS),
new BMessage(kMsgPairDevice));
pairButton->SetEnabled(false);
disconnectButton = new BButton("disconnect", B_TRANSLATE("Disconnect"),
new BMessage(kMsgDisconnectDevice));
disconnectButton->SetEnabled(false);
cancelButton = new BButton("cancel", B_TRANSLATE("Cancel"),
new BMessage(kMsgCancelConn));
cancelButton->SetEnabled(false);
fDeviceList = new DeviceListView("DeviceList", B_SINGLE_SELECTION_LIST);
fScrollView = new BScrollView("ScrollView", fDeviceList, 0, false, true);
BLayoutBuilder::Group<>(this, B_HORIZONTAL, 10)
.SetInsets(5)
.Add(fScrollView)
.AddGroup(B_VERTICAL)
.SetInsets(0, 15, 0, 15)
.Add(addButton)
.Add(removeButton)
.AddGlue()
.Add(pairButton)
.Add(disconnectButton)
.Add(cancelButton)
.AddGlue()
.End()
.End();
}
RemoteDevicesView::~RemoteDevicesView(void)
{
}
void
RemoteDevicesView::AttachedToWindow(void)
{
fDeviceList->SetTarget(this);
addButton->SetTarget(this);
removeButton->SetTarget(this);
pairButton->SetTarget(this);
disconnectButton->SetTarget(this);
cancelButton->SetTarget(this);
LoadRemoteDevices();
LoadSettings();
fDeviceList->Select(0);
fConnectingDeviceItem = NULL;
}
void
RemoteDevicesView::AddRemoteDevice(BMessage* device)
{
RemoteDevice* rd = RemoteDevice::ParseRemoteDevice(ActiveLocalDevice, device);
DeviceListItem* deviceItem = new DeviceListItem(rd);
deviceItem->SetConnectionState(rd->GetConnectionState());
BMessage message(kMsgAddToRemoteList);
message.AddPointer("device", deviceItem);
MessageReceived(&message);
}
void
RemoteDevicesView::LoadRemoteDevices()
{
BObjectList<RemoteDevice> rdList = RemoteDevice::GetRemoteDevices(ActiveLocalDevice);
if (rdList.IsEmpty())
return;
BMessage device;
for (int32 i = 0; i < rdList.CountItems(); i++) {
RemoteDevice* remote = rdList.ItemAt(i);
DeviceListItem* deviceItem = new DeviceListItem(remote);
deviceItem->SetConnectionState(remote->GetConnectionState());
BMessage message(kMsgAddToRemoteList);
message.AddPointer("device", deviceItem);
MessageReceived(&message);
}
}
void
RemoteDevicesView::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgAddDevices:
{
InquiryPanel* inquiryPanel= new InquiryPanel(
BRect(100, 100, 450, 450), ActiveLocalDevice);
inquiryPanel->Show();
break;
}
case kMsgRemoveDevice:
{
RemoteDevice* remote = NULL;
DeviceListItem* device = static_cast<DeviceListItem*>(fDeviceList
->ItemAt(fDeviceList->CurrentSelection(0)));
if (device != NULL)
remote = dynamic_cast<RemoteDevice*>(device->Device());
fDeviceList->RemoveItem(fDeviceList->CurrentSelection(0));
if (remote == NULL)
break;
remote->Disconnect(true);
break;
}
case kMsgAddToRemoteList:
{
DeviceListItem* device = NULL;
message->FindPointer("device", (void**)&device);
bool isDuplicate = false;
for (int32 i = 0; i < fDeviceList->CountItems(); i++) {
DeviceListItem* existingDevice
= static_cast<DeviceListItem*>(fDeviceList->ItemAt(i));
if (DeviceListItem::Compare(&existingDevice, &device)) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
fDeviceList->AddItem((BListItem*)device);
fDeviceList->Invalidate();
} else {
delete device;
}
break;
}
case kMsgPairDevice:
{
DeviceListItem* device = static_cast<DeviceListItem*>(fDeviceList
->ItemAt(fDeviceList->CurrentSelection(0)));
if (device == NULL)
break;
RemoteDevice* remote = dynamic_cast<RemoteDevice*>(device->Device());
if (remote == NULL)
break;
fConnectingDeviceItem = device;
fConnectingDeviceItem->SetConnectionState(RemoteDevice::CONNECTING);
DeviceSelected();
remote->Connect();
break;
}
case BT_MSG_CONN_COMPLETED:
{
uint8 status;
bdaddr_t* bdaddr;
ssize_t size;
message->FindUInt8("status", &status);
if (fConnectingDeviceItem == NULL &&
message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size) == B_OK) {
for (int32 i = 0; i < fDeviceList->CountItems(); i++) {
DeviceListItem* item = static_cast<DeviceListItem*>(fDeviceList->ItemAt(i));
if (bdaddrUtils::Compare(item->Device()->GetBluetoothAddress(), *bdaddr))
fConnectingDeviceItem = item;
}
}
if (fConnectingDeviceItem == NULL)
break;
if (status == BT_OK)
fConnectingDeviceItem->SetConnectionState(RemoteDevice::CONNECTED);
else
fConnectingDeviceItem->SetConnectionState(RemoteDevice::DISCONNECTED);
DeviceSelected();
fConnectingDeviceItem = NULL;
break;
}
case kMsgDisconnectDevice:
{
DeviceListItem* device = static_cast<DeviceListItem*>(fDeviceList
->ItemAt(fDeviceList->CurrentSelection(0)));
if (device == NULL)
break;
RemoteDevice* remote = dynamic_cast<RemoteDevice*>(device->Device());
if (remote == NULL)
break;
fConnectingDeviceItem = device;
remote->Disconnect(false);
break;
}
case BT_MSG_CONN_FAILED:
case BT_MSG_DISCONN_COMPLETED:
{
bdaddr_t* bdaddr;
ssize_t size;
if (fConnectingDeviceItem == NULL &&
message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size) == B_OK) {
for (int32 i = 0; i < fDeviceList->CountItems(); i++) {
DeviceListItem* item = static_cast<DeviceListItem*>(fDeviceList->ItemAt(i));
if (bdaddrUtils::Compare(item->Device()->GetBluetoothAddress(), *bdaddr))
fConnectingDeviceItem = item;
}
}
if (fConnectingDeviceItem == NULL)
break;
fConnectingDeviceItem->SetConnectionState(RemoteDevice::DISCONNECTED);
fConnectingDeviceItem = NULL;
DeviceSelected();
break;
}
case kMsgCancelConn:
{
fConnectingDeviceItem->Device()->CancelConnection();
break;
}
default:
BView::MessageReceived(message);
break;
}
}
void
RemoteDevicesView::DeviceSelected()
{
DeviceListItem* device = static_cast<DeviceListItem*>(fDeviceList
->ItemAt(fDeviceList->CurrentSelection(0)));
if (device == NULL)
return;
switch (device->GetConnectionState()) {
case RemoteDevice::CONNECTING:
pairButton->SetEnabled(false);
disconnectButton->SetEnabled(false);
cancelButton->SetEnabled(true);
break;
case RemoteDevice::CONNECTED:
pairButton->SetEnabled(false);
disconnectButton->SetEnabled(true);
cancelButton->SetEnabled(false);
break;
case RemoteDevice::DISCONNECTED:
pairButton->SetEnabled(true);
disconnectButton->SetEnabled(false);
cancelButton->SetEnabled(false);
break;
}
}
void
RemoteDevicesView::LoadSettings(void)
{
}
bool
RemoteDevicesView::IsDefaultable(void)
{
return true;
}