diff --git a/debian/control b/debian/control
index 7be2f5d..607167e 100644
--- a/debian/control
+++ b/debian/control
@@ -31,8 +31,6 @@ Depends: qml6-module-qtquick-controls,
qml6-module-qtquick-dialogs,
qml6-module-qtquick-particles,
qml6-module-qt5compat-graphicaleffects,
- qml6-module-org-kde-bluezqt,
- bluedevil,
network-manager,
fishui,
libcutefish,
diff --git a/src/qml/Bluetooth/Main.qml b/src/qml/Bluetooth/Main.qml
index 0f23c3c..490a93f 100644
--- a/src/qml/Bluetooth/Main.qml
+++ b/src/qml/Bluetooth/Main.qml
@@ -17,10 +17,9 @@
* along with this program. If not, see .
*/
-import QtQuick 2.4
-import QtQuick.Controls 2.4
-import QtQuick.Layouts 1.3
-import Cutefish.Settings 1.0
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
import FishUI 1.0 as FishUI
import Cutefish.Bluetooth 1.0 as Bluetooth
import "../"
@@ -28,51 +27,43 @@ import "../"
ItemPage {
id: control
headerTitle: qsTr("Bluetooth")
+ readonly property bool bluetoothEnabled: Bluetooth.Manager.enabled
- property bool bluetoothDisConnected: Bluetooth.Manager.bluetoothBlocked
-
- onBluetoothDisConnectedChanged: {
- bluetoothSwitch.checked = !bluetoothDisConnected
- }
-
- function setBluetoothEnabled(enabled) {
- Bluetooth.Manager.bluetoothBlocked = !enabled
-
- for (var i = 0; i < Bluetooth.Manager.adapters.length; ++i) {
- var adapter = Bluetooth.Manager.adapters[i]
- adapter.powered = enabled
- }
+ function updateActivity() {
+ Bluetooth.Manager.agentEnabled = visible
+ Bluetooth.Manager.discoveryRequested = visible && Bluetooth.Manager.enabled
}
- Bluetooth.DevicesProxyModel {
- id: devicesProxyModel
- sourceModel: devicesModel
+ onVisibleChanged: updateActivity()
+ onBluetoothEnabledChanged: {
+ Bluetooth.Manager.discoveryRequested = visible && bluetoothEnabled
}
-
- Bluetooth.DevicesModel {
- id: devicesModel
+ Component.onCompleted: updateActivity()
+ Component.onDestruction: {
+ Bluetooth.Manager.discoveryRequested = false
+ Bluetooth.Manager.agentEnabled = false
}
- Bluetooth.BluetoothManager {
- id: bluetoothMgr
-
- onShowPairDialog: {
- _pairDialog.title = name
- _pairDialog.pin = pin
- _pairDialog.visible = true
+ Bluetooth.DevicesModel { id: devicesModel }
+ PairDialog { }
+
+ Dialog {
+ id: forgetDialog
+ property var device: null
+ title: qsTr("Forget this device?")
+ anchors.centerIn: parent
+ modal: true
+ standardButtons: Dialog.Cancel | Dialog.Ok
+ Label {
+ text: forgetDialog.device ? forgetDialog.device.name : ""
+ textFormat: Text.PlainText
}
-
- onPairFailed: {
- rootWindow.showPassiveNotification(qsTr("Pairing unsuccessful"), 3000)
- }
-
- onConnectFailed: {
- rootWindow.showPassiveNotification(qsTr("Connecting Unsuccessful"), 3000)
+ onAccepted: {
+ if (device)
+ device.forget()
+ device = null
}
- }
-
- PairDialog {
- id: _pairDialog
+ onRejected: device = null
}
Scrollable {
@@ -81,188 +72,200 @@ ItemPage {
ColumnLayout {
id: layout
- anchors.fill: parent
- anchors.bottomMargin: FishUI.Units.largeSpacing
+ width: parent.contentWidth
+ spacing: FishUI.Units.largeSpacing
RoundedItem {
- id: mainItem
- spacing: FishUI.Units.largeSpacing
-
RowLayout {
Label {
text: qsTr("Bluetooth")
- color: FishUI.Theme.disabledTextColor
- }
-
- Item {
Layout.fillWidth: true
}
-
Switch {
- id: bluetoothSwitch
- Layout.fillHeight: true
- rightPadding: 0
- checked: !Bluetooth.Manager.bluetoothBlocked
- onCheckedChanged: setBluetoothEnabled(checked)
+ checked: Bluetooth.Manager.enabled
+ enabled: Bluetooth.Manager.operational && Bluetooth.Manager.adapters.length > 0
+ onClicked: Bluetooth.Manager.enabled = checked
}
}
-
- ListView {
- id: _listView
- visible: count > 0
- interactive: false
- spacing: 0
-
+ Label {
Layout.fillWidth: true
-
- Layout.preferredHeight: {
- var totalHeight = 0
- for (var i = 0; i < _listView.visibleChildren.length; ++i) {
- totalHeight += _listView.visibleChildren[i].height
+ wrapMode: Text.Wrap
+ visible: !Bluetooth.Manager.operational || !Bluetooth.Manager.adapters.length
+ || Bluetooth.Manager.hardwareBlocked || !Bluetooth.Manager.enabled
+ text: !Bluetooth.Manager.operational ? qsTr("Bluetooth service is unavailable")
+ : Bluetooth.Manager.hardwareBlocked ? qsTr("Bluetooth is blocked by a hardware switch")
+ : !Bluetooth.Manager.adapters.length ? qsTr("No Bluetooth adapters found")
+ : qsTr("Bluetooth is disabled")
+ }
+ RowLayout {
+ visible: Bluetooth.Manager.enabled
+ Label {
+ Layout.fillWidth: true
+ text: Bluetooth.Manager.scanning ? qsTr("Searching for devices…") : qsTr("Devices")
+ }
+ BusyIndicator {
+ running: Bluetooth.Manager.scanning
+ implicitWidth: 28
+ implicitHeight: 28
+ }
+ Button {
+ text: Bluetooth.Manager.discoveryRequested ? qsTr("Stop searching") : qsTr("Search")
+ onClicked: {
+ Bluetooth.Manager.clearError()
+ Bluetooth.Manager.discoveryRequested = !Bluetooth.Manager.discoveryRequested
}
- return totalHeight
}
+ }
+ }
- model: Bluetooth.Manager.bluetoothOperational ? devicesProxyModel : []
+ RoundedItem {
+ visible: Bluetooth.Manager.errorText.length > 0
+ Label {
+ Layout.fillWidth: true
+ wrapMode: Text.Wrap
+ textFormat: Text.PlainText
+ text: Bluetooth.Manager.errorText
+ }
+ Button {
+ text: qsTr("Dismiss")
+ onClicked: Bluetooth.Manager.clearError()
+ }
+ }
- section.property: "Section"
- section.criteria: ViewSection.FullString
- section.delegate: Label {
- color: FishUI.Theme.disabledTextColor
- topPadding: FishUI.Units.largeSpacing
- bottomPadding: FishUI.Units.largeSpacing
- text: section == "My devices" ? qsTr("My devices")
- : qsTr("Other devices")
+ Repeater {
+ model: Bluetooth.Manager.adapters
+ delegate: RoundedItem {
+ required property var modelData
+ Label {
+ Layout.fillWidth: true
+ text: modelData.name + " · " + modelData.address
+ textFormat: Text.PlainText
+ elide: Text.ElideRight
}
+ RowLayout {
+ Layout.fillWidth: true
+ TextField {
+ id: adapterName
+ Layout.fillWidth: true
+ placeholderText: modelData.name
+ maximumLength: 248
+ }
+ Button {
+ text: qsTr("Rename")
+ enabled: adapterName.text.length > 0
+ onClicked: {
+ modelData.name = adapterName.text
+ adapterName.clear()
+ }
+ }
+ }
+ RowLayout {
+ Switch {
+ text: qsTr("Powered")
+ checked: modelData.powered
+ onClicked: modelData.powered = checked
+ }
+ Switch {
+ text: qsTr("Visible to other devices")
+ enabled: modelData.powered
+ checked: modelData.discoverable
+ onClicked: modelData.discoverable = checked
+ }
+ }
+ Switch {
+ text: qsTr("Allow incoming pairing")
+ enabled: modelData.powered
+ checked: modelData.pairable
+ onClicked: modelData.pairable = checked
+ }
+ }
+ }
- delegate: Item {
- width: ListView.view.width
- height: _itemLayout.implicitHeight + FishUI.Units.largeSpacing
-
- property bool paired: model.Connected && model.Paired
+ Label {
+ visible: Bluetooth.Manager.enabled && devicesModel.count === 0
+ text: qsTr("No devices found. Make your device discoverable and search again.")
+ wrapMode: Text.Wrap
+ Layout.fillWidth: true
+ }
+ Repeater {
+ model: devicesModel
+ delegate: RoundedItem {
+ required property var device
+ visible: Bluetooth.Manager.enabled
+ RowLayout {
ColumnLayout {
- id: _itemLayout
- anchors.fill: parent
- anchors.leftMargin: 0
- anchors.rightMargin: 0
- anchors.topMargin: FishUI.Units.smallSpacing
- anchors.bottomMargin: FishUI.Units.smallSpacing
- spacing: 0
-
- Item {
+ Layout.fillWidth: true
+ Label {
Layout.fillWidth: true
- height: _contentLayout.implicitHeight + FishUI.Units.largeSpacing
-
- 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){
- additionalSettings.toggle()
- return
- }
-
- if (model.Paired) {
- bluetoothMgr.connectToDevice(model.Address)
- } else {
- bluetoothMgr.requestParingConnection(model.Address)
- }
- }
- }
-
- RowLayout {
- id: _contentLayout
- anchors.fill: parent
- anchors.rightMargin: FishUI.Units.smallSpacing
-
- Image {
- width: 16
- height: 16
- sourceSize: Qt.size(16, 16)
- source: FishUI.Theme.darkMode ? "qrc:/images/sidebar/dark/bluetooth.svg"
- : "qrc:/images/sidebar/light/bluetooth.svg"
- Layout.alignment: Qt.AlignVCenter
- }
-
- Label {
- text: model.DeviceFullName
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignVCenter
- }
-
- Label {
- visible: model.Paired
- text: model.Connected ? qsTr("Connected") : qsTr("Not Connected")
- }
- }
+ text: device.name
+ textFormat: Text.PlainText
+ elide: Text.ElideRight
}
-
- Hideable {
- id: additionalSettings
- spacing: 0
-
- ColumnLayout {
- Item {
- height: FishUI.Units.largeSpacing
- }
-
- RowLayout {
- spacing: FishUI.Units.largeSpacing
- Layout.leftMargin: FishUI.Units.smallSpacing
-
- Button {
- text: qsTr("Connect")
- visible: !model.Connected
- onClicked: {
- if (model.Paired) {
- bluetoothMgr.connectToDevice(model.Address)
- } else {
- bluetoothMgr.requestParingConnection(model.Address)
- }
- }
- }
-
- Button {
- text: qsTr("Disconnect")
- visible: model.Connected
- onClicked: {
- bluetoothMgr.deviceDisconnect(model.Address)
- additionalSettings.hide()
- }
- }
-
- Button {
- text: qsTr("Forget This Device")
- flat: true
- onClicked: {
- bluetoothMgr.deviceRemoved(model.Address)
- additionalSettings.hide()
- }
- }
- }
- }
-
- HorizontalDivider {}
+ Label {
+ text: device.address + " · " + device.adapterPath.split("/").pop()
+ color: FishUI.Theme.disabledTextColor
+ }
+ Label {
+ text: device.connected ? qsTr("Connected")
+ : device.paired ? qsTr("Paired") : qsTr("Not paired")
}
}
+ Label {
+ visible: device.batteryPercentage >= 0
+ text: qsTr("%1% battery").arg(device.batteryPercentage)
+ }
+ BusyIndicator {
+ running: device.busy
+ visible: running
+ implicitWidth: 28
+ implicitHeight: 28
+ }
+ }
+ RowLayout {
+ Button {
+ text: device.connected ? qsTr("Disconnect")
+ : device.paired ? qsTr("Connect") : qsTr("Pair")
+ enabled: !device.busy && (device.paired || Bluetooth.Manager.agentReady)
+ onClicked: {
+ if (device.connected)
+ device.disconnectFromDevice()
+ else if (device.paired)
+ device.connectToDevice()
+ else
+ device.pair()
+ }
+ }
+ Button {
+ visible: device.busy && !device.paired
+ text: qsTr("Cancel pairing")
+ onClicked: device.cancelPairing()
+ }
+ Button {
+ visible: device.paired
+ enabled: !device.busy
+ text: qsTr("Forget")
+ onClicked: {
+ forgetDialog.device = device
+ forgetDialog.open()
+ }
+ }
+ CheckBox {
+ visible: device.paired
+ text: qsTr("Trusted")
+ checked: device.trusted
+ enabled: !device.busy
+ onClicked: device.trusted = checked
+ }
+ CheckBox {
+ text: qsTr("Blocked")
+ checked: device.blocked
+ enabled: !device.busy
+ onClicked: device.blocked = checked
+ }
}
}
}
-
- Item {
- height: FishUI.Units.largeSpacing * 2
- }
}
}
}
diff --git a/src/qml/Bluetooth/PairDialog.qml b/src/qml/Bluetooth/PairDialog.qml
index 16cefc4..2333949 100644
--- a/src/qml/Bluetooth/PairDialog.qml
+++ b/src/qml/Bluetooth/PairDialog.qml
@@ -1,103 +1,93 @@
-import QtQuick 2.12
-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 "../"
-
-FishUI.Window {
- id: control
-
- windowRadius: 16
- windowButtonsTopMargin: 8
- windowButtonsRightMargin: 8
- minimizeButtonVisible: false
- header.height: 44
- contentTopMargin: 0
-
- width: contentWidth
- height: contentHeight
-
- property int contentWidth: 360
- property int contentHeight: mainLayout.implicitHeight + 32
-
- minimumWidth: contentWidth
- minimumHeight: contentHeight
- maximumWidth: contentWidth
- maximumHeight: contentHeight
-
- modality: Qt.WindowModal
- flags: Qt.Dialog | Qt.FramelessWindowHint
- visible: false
- title: " "
-
- property var pin: ""
-
- background.color: FishUI.Theme.secondBackgroundColor
-
- DragHandler {
- target: null
- acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
- grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
- onActiveChanged: if (active) { control.helper.startSystemMove(control) }
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import Cutefish.Bluetooth 1.0 as Bluetooth
+
+Dialog {
+ id: dialog
+ anchors.centerIn: parent
+ width: Math.min(parent.width - 32, 420)
+ modal: true
+ closePolicy: Popup.NoAutoClose
+ title: qsTr("Bluetooth pairing")
+
+ readonly property string kind: Bluetooth.Manager.pairingKind
+ readonly property bool inputRequired: kind === "RequestPinCode" || kind === "RequestPasskey"
+ readonly property bool displayOnly: kind === "DisplayPinCode" || kind === "DisplayPasskey"
+
+ Connections {
+ target: Bluetooth.Manager
+ function onPairingChanged() {
+ if (Bluetooth.Manager.pairingKind.length) {
+ if (!dialog.opened) {
+ codeInput.clear()
+ dialog.open()
+ if (dialog.inputRequired)
+ codeInput.forceActiveFocus()
+ }
+ } else {
+ dialog.close()
+ }
+ }
}
- ColumnLayout {
- id: mainLayout
- anchors.fill: parent
- anchors.margins: 16
+ contentItem: ColumnLayout {
spacing: 16
-
Label {
Layout.fillWidth: true
- Layout.rightMargin: 32
- text: "Bluetooth Pairing Request"
+ text: Bluetooth.Manager.pairingDevice
textFormat: Text.PlainText
- font.pixelSize: 14
- font.weight: Font.DemiBold
- color: FishUI.Theme.textColor
wrapMode: Text.Wrap
}
-
Label {
Layout.fillWidth: true
- text: control.title.trim()
- textFormat: Text.PlainText
- font.pixelSize: 14
- color: FishUI.Theme.disabledTextColor
+ text: dialog.kind === "RequestConfirmation" ? qsTr("Does this code match the code on your device?")
+ : dialog.kind === "RequestPinCode" ? qsTr("Enter the PIN for your device.")
+ : dialog.kind === "RequestPasskey" ? qsTr("Enter the passkey shown on your device.")
+ : dialog.displayOnly ? qsTr("Enter this code on your device, then press Enter.")
+ : dialog.kind === "AuthorizeService" ? qsTr("Allow this device to use the following Bluetooth service?")
+ : qsTr("Allow this device to pair?")
wrapMode: Text.Wrap
- visible: text.length > 0
}
-
Label {
- text: control.pin
+ Layout.fillWidth: true
+ visible: Bluetooth.Manager.pairingCode.length > 0
+ text: Bluetooth.Manager.pairingCode
textFormat: Text.PlainText
- visible: control.pin !== ""
- font.pixelSize: 24
- font.weight: Font.DemiBold
- Layout.alignment: Qt.AlignHCenter
+ wrapMode: Text.WrapAnywhere
+ font.pixelSize: dialog.kind === "AuthorizeService" ? 14 : 28
+ horizontalAlignment: Text.AlignHCenter
+ }
+ Label {
+ visible: dialog.kind === "DisplayPasskey"
+ text: qsTr("%1 digits entered").arg(Bluetooth.Manager.pairingEntered)
+ }
+ TextField {
+ id: codeInput
+ Layout.fillWidth: true
+ visible: dialog.inputRequired
+ maximumLength: dialog.kind === "RequestPasskey" ? 6 : 16
+ inputMethodHints: dialog.kind === "RequestPasskey" ? Qt.ImhDigitsOnly : Qt.ImhNone
+ onAccepted: Bluetooth.Manager.respondPairing(true, text)
+ }
+ Label {
+ Layout.fillWidth: true
+ visible: Bluetooth.Manager.errorText.length > 0
+ text: Bluetooth.Manager.errorText
+ textFormat: Text.PlainText
+ wrapMode: Text.Wrap
}
-
RowLayout {
- spacing: 8
Layout.alignment: Qt.AlignRight
-
- FishUI.ConfirmDialogButton {
+ Button {
text: qsTr("Cancel")
- onClicked: {
- control.visible = false
- bluetoothMgr.confirmMatchButton(false)
- }
+ onClicked: Bluetooth.Manager.cancelPairing()
}
-
- FishUI.ConfirmDialogButton {
- text: qsTr("OK")
- primary: true
- onClicked: {
- control.visible = false
- bluetoothMgr.confirmMatchButton(true)
- }
+ Button {
+ visible: !dialog.displayOnly
+ text: dialog.kind === "RequestConfirmation" ? qsTr("Confirm") : qsTr("Accept")
+ enabled: !dialog.inputRequired || codeInput.text.length > 0
+ onClicked: Bluetooth.Manager.respondPairing(true, codeInput.text)
}
}
}
diff --git a/src/qml/BluetoothPage.qml b/src/qml/BluetoothPage.qml
index b4269ff..0930151 100644
--- a/src/qml/BluetoothPage.qml
+++ b/src/qml/BluetoothPage.qml
@@ -17,84 +17,7 @@
* along with this program. If not, see .
*/
-import QtQuick 2.4
-import QtQuick.Controls 2.4
-import QtQuick.Layouts 1.3
-import Cutefish.Settings 1.0
-import FishUI 1.0 as FishUI
-import org.kde.bluezqt 1.0 as BluezQt
-import org.kde.plasma.private.bluetooth 1.0
+import QtQuick
+import "Bluetooth" as BluetoothPage
-ItemPage {
- headerTitle: qsTr("Bluetooth")
-
- function setBluetoothEnabled(enabled) {
- BluezQt.Manager.bluetoothBlocked = !enabled
-
- for (var i = 0; i < BluezQt.Manager.adapters.length; ++i) {
- var adapter = BluezQt.Manager.adapters[i];
- adapter.powered = enabled;
- }
- }
-
-// Label {
-// id: noBluetoothMessage
-// anchors.centerIn: parent
-// visible: BluezQt.Manager.rfkill.state === BluezQt.Rfkill.Unknown
-// text: qsTr("No Bluetooth adapters found")
-// }
-
- Label {
- anchors.centerIn: parent
- text: qsTr("Bluetooth is disabled")
- visible: BluezQt.Manager.operational && !BluezQt.Manager.bluetoothOperational // && !noBluetoothMessage.visible
- }
-
- Scrollable {
- anchors.fill: parent
- contentHeight: layout.implicitHeight
-
- ColumnLayout {
- id: layout
- anchors.fill: parent
- anchors.bottomMargin: FishUI.Units.largeSpacing
-
- Switch {
- id: bluetoothSwitch
- height: 50
- onCheckedChanged: setBluetoothEnabled(checked)
- Component.onCompleted: bluetoothSwitch.checked = BluezQt.Manager.operational
- }
-
- ListView {
- Layout.fillWidth: true
- Layout.fillHeight: true
-
- DevicesProxyModel {
- id: devicesModel
- sourceModel: BluezQt.DevicesModel { }
- }
-
- model: BluezQt.Manager.bluetoothOperational ? devicesModel : []
-
- delegate: Item {
- width: ListView.view.width
- height: 50
-
- Rectangle {
- anchors.fill: parent
- color: "red"
- }
-
- ColumnLayout {
- anchors.fill: parent
-
- Label {
- text: model.name
- }
- }
- }
- }
- }
- }
-}
+BluetoothPage.Main { }
diff --git a/src/qml/SideBar.qml b/src/qml/SideBar.qml
index e557c83..cdc35e6 100644
--- a/src/qml/SideBar.qml
+++ b/src/qml/SideBar.qml
@@ -23,8 +23,10 @@ import QtQuick.Layouts 1.3
import FishUI 1.0 as FishUI
import Cutefish.Settings 1.0
import Cutefish.Network 1.0 as NM
+import Cutefish.Bluetooth 1.0 as Bluetooth
Item {
+ id: sideBar
implicitWidth: 230
property int itemRadiusV: 8
@@ -32,6 +34,67 @@ Item {
property alias view: listView
property alias model: listModel
property alias currentIndex: listView.currentIndex
+ property bool updatingModel: false
+ signal currentPageRemoved()
+ signal bluetoothItemAdded()
+
+ Component.onCompleted: syncBluetoothItem()
+
+ Connections {
+ target: Bluetooth.Manager
+ function onAvailableChanged() {
+ Qt.callLater(sideBar.syncBluetoothItem)
+ }
+ }
+
+ function syncBluetoothItem() {
+ var bluetoothIndex = -1
+ for (var i = 0; i < listModel.count; ++i) {
+ if (listModel.get(i).name === "bluetooth") {
+ bluetoothIndex = i
+ break
+ }
+ }
+ if (Bluetooth.Manager.available === (bluetoothIndex >= 0))
+ return
+
+ var selectedPage = listView.currentIndex >= 0
+ ? listModel.get(listView.currentIndex).page : ""
+ var selectedRemoved = bluetoothIndex >= 0 && listView.currentIndex === bluetoothIndex
+ updatingModel = true
+ if (Bluetooth.Manager.available) {
+ var insertIndex = 0
+ while (insertIndex < listModel.count
+ && (listModel.get(insertIndex).name === "wlan"
+ || listModel.get(insertIndex).name === "ethernet"))
+ ++insertIndex
+ listModel.insert(insertIndex, {
+ title: qsTr("Bluetooth"),
+ name: "bluetooth",
+ page: "qrc:/qml/Bluetooth/Main.qml",
+ iconSource: "bluetooth.svg",
+ iconColor: "#0067FF",
+ category: qsTr("Network and connection")
+ })
+ } else {
+ listModel.remove(bluetoothIndex)
+ }
+ if (selectedRemoved) {
+ listView.currentIndex = 0
+ } else {
+ for (var j = 0; j < listModel.count; ++j) {
+ if (listModel.get(j).page === selectedPage) {
+ listView.currentIndex = j
+ break
+ }
+ }
+ }
+ updatingModel = false
+ if (selectedRemoved)
+ currentPageRemoved()
+ else if (Bluetooth.Manager.available)
+ bluetoothItemAdded()
+ }
Rectangle {
anchors.fill: parent
@@ -77,15 +140,6 @@ Item {
// category: qsTr("Network and connection")
// }
- ListElement {
- title: qsTr("Bluetooth")
- name: "bluetooth"
- page: "qrc:/qml/Bluetooth/Main.qml"
- iconSource: "bluetooth.svg"
- iconColor: "#0067FF"
- category: qsTr("Network and connection")
- }
-
// ListElement {
// title: qsTr("VPN")
// name: "vpn"
diff --git a/src/qml/main.qml b/src/qml/main.qml
index bbe912e..a12c371 100644
--- a/src/qml/main.qml
+++ b/src/qml/main.qml
@@ -34,6 +34,7 @@ FishUI.Window {
minimumHeight: 600
property alias stackView: _stackView
+ property string pendingPageName: ""
background.color: FishUI.Theme.backgroundColor
background.opacity: blurEnabled && blurAvailable ? (FishUI.Theme.darkMode ? 0.7 : 0.5) : 1
@@ -58,7 +59,13 @@ FishUI.Window {
: Math.round(implicitWidth * pixelRatio) / pixelRatio
onCurrentIndexChanged: {
- switchPageFromIndex(currentIndex)
+ if (!sideBar.updatingModel)
+ switchPageFromIndex(currentIndex)
+ }
+ onCurrentPageRemoved: switchPageFromIndex(currentIndex)
+ onBluetoothItemAdded: {
+ if (rootWindow.pendingPageName === "bluetooth")
+ rootWindow.switchPageFromName("bluetooth")
}
}
@@ -77,11 +84,15 @@ FishUI.Window {
}
function switchPageFromIndex(index) {
+ if (index < 0 || index >= sideBar.model.count)
+ return
+ pendingPageName = ""
_stackView.pop()
_stackView.push(Qt.resolvedUrl(sideBar.model.get(index).page))
}
function switchPageFromName(pageName) {
+ pendingPageName = pageName === "bluetooth" ? pageName : ""
for (var i = 0; i < sideBar.model.count; ++i) {
if (pageName === sideBar.model.get(i).name) {
switchPageFromIndex(i)