diff --git a/debian/control b/debian/control index 2878c4d..7138aaa 100644 --- a/debian/control +++ b/debian/control @@ -16,6 +16,7 @@ Build-Depends: cmake, modemmanager-qt-dev, qtbase5-dev, libqt5x11extras5-dev, + libkf5bluezqt-dev, qtdeclarative5-dev, qtquickcontrols2-5-dev, qttools5-dev, diff --git a/src/bluetooth/bluetoothmanager.cpp b/src/bluetooth/bluetoothmanager.cpp index ffcc65e..f9adb9e 100644 --- a/src/bluetooth/bluetoothmanager.cpp +++ b/src/bluetooth/bluetoothmanager.cpp @@ -3,6 +3,7 @@ #include #include +#include BluetoothManager::BluetoothManager(QObject *parent) : QObject(parent) @@ -13,6 +14,8 @@ BluetoothManager::BluetoothManager(QObject *parent) initJob->start(); connect(initJob, &BluezQt::InitManagerJob::result, this, &BluetoothManager::onInitJobResult); + connect(m_agent, &BluetoothAgent::confirmationRequested, this, &BluetoothManager::confirmationRequested); + connect(m_manager, &BluezQt::Manager::bluetoothBlockedChanged, this, [=] (bool blocked) { if (!blocked) { BluezQt::AdapterPtr adaptor = m_manager->adapters().first(); @@ -39,6 +42,37 @@ void BluetoothManager::setName(const QString &name) adaptor->setName(name); } +void BluetoothManager::connectToDevice(const QString address) +{ + BluezQt::AdapterPtr adaptor = m_manager->usableAdapter(); + BluezQt::DevicePtr device = adaptor->deviceForAddress(address); + qDebug() << "hello: " << address << device->name(); + m_device = device; + device->setTrusted(true); + BluezQt::PendingCall *call = m_device->connectToDevice(); +// connect(call, &BluezQt::PendingCall::finished, this, &Bluetooth::connectFinished); +// connect(m_device.data(), &BluezQt::Device::connectedChanged, this, &Bluetooth::connectedStateChanged); +} + +void BluetoothManager::requestParingConnection(const QString address) +{ + BluezQt::AdapterPtr adaptor = m_manager->usableAdapter(); + BluezQt::DevicePtr device = adaptor->deviceForAddress(address); + m_device = device; +// m_address = address; + BluezQt::PendingCall *pairCall = m_device->pair(); +// connect(pairCall, &BluezQt::PendingCall::finished, this, &Bluetooth::pairingFinished); +} + +void BluetoothManager::confirmMatchButton(const bool match) +{ + if (match){ + m_req.accept(); + } else{ + m_req.reject(); + } +} + void BluetoothManager::onInitJobResult(BluezQt::InitManagerJob *job) { if (job->error()) { @@ -68,3 +102,9 @@ void BluetoothManager::operationalChanged(bool operational) BluezQt::Manager::startService(); } } + +void BluetoothManager::confirmationRequested(const QString &passkey, const BluezQt::Request<> &req) +{ + m_req = req; + Q_EMIT showPairDialog(m_device->name(), passkey); +} diff --git a/src/bluetooth/bluetoothmanager.h b/src/bluetooth/bluetoothmanager.h index f2a8e78..2b170c1 100644 --- a/src/bluetooth/bluetoothmanager.h +++ b/src/bluetooth/bluetoothmanager.h @@ -14,15 +14,24 @@ public: ~BluetoothManager(); Q_INVOKABLE void setName(const QString &name); + Q_INVOKABLE void connectToDevice(const QString address); + Q_INVOKABLE void requestParingConnection(const QString address); + Q_INVOKABLE void confirmMatchButton(const bool match); + +signals: + void showPairDialog(const QString name, const QString pin); private slots: void onInitJobResult(BluezQt::InitManagerJob *job); void operationalChanged(bool operational); + void confirmationRequested(const QString &passkey, const BluezQt::Request<> &req); private: BluezQt::Manager *m_manager; BluetoothAgent *m_agent; BluezQt::AdapterPtr m_adapter; + BluezQt::DevicePtr m_device; + BluezQt::Request<> m_req; QString m_name; }; diff --git a/src/qml/Bluetooth/Main.qml b/src/qml/Bluetooth/Main.qml index 87936fe..5c9985d 100644 --- a/src/qml/Bluetooth/Main.qml +++ b/src/qml/Bluetooth/Main.qml @@ -40,7 +40,6 @@ ItemPage { for (var i = 0; i < Bluez.Manager.adapters.length; ++i) { var adapter = Bluez.Manager.adapters[i] - console.log(adapter + ", " + enabled) adapter.powered = enabled } } @@ -56,6 +55,15 @@ ItemPage { BluetoothManager { id: bluetoothMgr + + onShowPairDialog: { + _pairDialog.title = name + _pairDialog.visible = true + } + } + + PairDialog { + id: _pairDialog } // Label { @@ -104,39 +112,76 @@ ItemPage { } ListView { + id: _listView visible: count > 0 + interactive: false + spacing: FishUI.Units.largeSpacing - property var itemHeight: 50 + Layout.fillWidth: true - onCountChanged: { - console.log(count) + Layout.preferredHeight: { + var totalHeight = 0 + for (var i = 0; i < _listView.visibleChildren.length; ++i) { + totalHeight += _listView.visibleChildren[i].height + } + return totalHeight } - Layout.fillWidth: true - Layout.preferredHeight: itemHeight * count + ((count - 1) * spacing) - model: devicesProxyModel //Bluez.Manager.bluetoothOperational ? devicesModel : [] section.property: "Section" section.delegate: Label { + color: FishUI.Theme.disabledTextColor + topPadding: FishUI.Units.largeSpacing + bottomPadding: FishUI.Units.largeSpacing text: section == "Connected" ? qsTr("Connected devices") : qsTr("Available devices") } delegate: Item { - width: ListView.view.itemHeight - height: 50 + width: ListView.view.width + height: _itemLayout.implicitHeight + FishUI.Units.largeSpacing * 1.5 + + Rectangle { + anchors.fill: parent + radius: FishUI.Theme.smallRadius + color: FishUI.Theme.textColor + opacity: mouseArea.pressed ? 0.15 : mouseArea.containsMouse ? 0.1 : 0.0 + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton + onClicked: { + if (model.Connected && model.Paired){ + return + } + + if (model.Paired) { + bluetoothMgr.connectToDevice(model.Address) + } else { + bluetoothMgr.requestParingConnection(model.Address) + } + } + } ColumnLayout { + id: _itemLayout anchors.fill: parent Label { - text: model.Device + text: model.DeviceFullName } } } } } + + Item { + height: FishUI.Units.largeSpacing * 2 + } } } } diff --git a/src/qml/Bluetooth/PairDialog.qml b/src/qml/Bluetooth/PairDialog.qml new file mode 100644 index 0000000..167df23 --- /dev/null +++ b/src/qml/Bluetooth/PairDialog.qml @@ -0,0 +1,61 @@ +import QtQuick 2.4 +import QtQuick.Window 2.12 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 1.3 +import Cutefish.Settings 1.0 +import FishUI 1.0 as FishUI +import "../" + +Window { + id: control + + width: 200 + height: 100 + + minimumWidth: 200 + minimumHeight: 100 + maximumWidth: 200 + maximumHeight: 100 + + modality: Qt.WindowModal + flags: Qt.WindowStaysOnTopHint + visible: false + title: " " + + Rectangle { + anchors.fill: parent + color: FishUI.Theme.secondBackgroundColor + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: FishUI.Units.largeSpacing + + Label { + text: qsTr("Bluetooth Pairing Request") + } + + RowLayout { + spacing: FishUI.Units.largeSpacing + + Button { + text: qsTr("Cancel") + Layout.fillWidth: true + onClicked: { + control.visible = false + bluetoothMgr.confirmMatchButton(false) + } + } + + Button { + text: qsTr("OK") + Layout.fillWidth: true + flat: true + onClicked: { + control.visible = false + bluetoothMgr.confirmMatchButton(true) + } + } + } + } +} diff --git a/src/resources.qrc b/src/resources.qrc index 628b8a3..b3963df 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -119,5 +119,6 @@ images/sidebar/dark/touchpad.svg images/logo.png images/dock_straight.svg + qml/Bluetooth/PairDialog.qml diff --git a/translations/en_US.ts b/translations/en_US.ts index 76fb656..835457a 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -468,17 +468,17 @@ - + Bluetooth Bluetooth - + Connected devices - + Available devices @@ -607,6 +607,24 @@ + + PairDialog + + + Bluetooth Pairing Request + + + + + Cancel + Cancel + + + + OK + + + QObject diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index 8e640a8..79f45ed 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -468,17 +468,17 @@ - + Bluetooth 蓝牙 - + Connected devices 已连接设备 - + Available devices 可用设备 @@ -607,6 +607,24 @@ 指针速度 + + PairDialog + + + Bluetooth Pairing Request + 蓝牙配对请求 + + + + Cancel + 取消 + + + + OK + 确认 + + QObject