Improve Bluetooth and remove bluezqt

pull/55/head
reionwong 4 years ago
parent 27ea85b763
commit 641c378464

@ -17,7 +17,6 @@ find_package(X11 REQUIRED)
find_package(Freetype REQUIRED)
find_package(PkgConfig REQUIRED)
find_package(Libcrypt REQUIRED)
find_package(KF5BluezQt REQUIRED)
# find_package(QApt REQUIRED)
find_package(KF5NetworkManagerQt REQUIRED)
@ -54,8 +53,6 @@ set(SRCS
src/datetime/timezonemap.cpp
src/datetime/timedated_interface.cpp
src/touchpad.cpp
src/bluetooth/bluetoothmanager.cpp
src/bluetooth/bluetoothagent.cpp
src/vpn/vpn.cpp
src/vpn/nm-l2tp-service.h
src/vpn/nm-openvpn-service.h
@ -89,7 +86,6 @@ target_link_libraries(${PROJECT_NAME}
KF5::NetworkManagerQt
KF5::ModemManagerQt
KF5::BluezQt
PkgConfig::FontConfig
${FREETYPE_LIBRARIES}

1
debian/control vendored

@ -16,7 +16,6 @@ Build-Depends: cmake,
modemmanager-qt-dev,
qtbase5-dev,
libqt5x11extras5-dev,
libkf5bluezqt-dev,
qtdeclarative5-dev,
qtquickcontrols2-5-dev,
qttools5-dev,

@ -26,8 +26,6 @@
#include "datetime/time.h"
#include "datetime/timezonemap.h"
#include "bluetooth/bluetoothmanager.h"
static QObject *passwordSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine);
@ -80,7 +78,6 @@ Application::Application(int &argc, char **argv)
qmlRegisterType<Time>(uri, 1, 0, "Time");
qmlRegisterType<TimeZoneMap>(uri, 1, 0, "TimeZoneMap");
qmlRegisterType<Touchpad>(uri, 1, 0, "Touchpad");
qmlRegisterType<BluetoothManager>(uri, 1, 0, "BluetoothManager");
qmlRegisterType<NetworkProxy>(uri, 1, 0, "NetworkProxy");
qmlRegisterSingletonType<Password>(uri, 1, 0, "Password", passwordSingleton);

@ -1,179 +0,0 @@
/*
* SPDX-FileCopyrightText: 2010 Alex Fiestas <alex@eyeos.org>
* SPDX-FileCopyrightText: 2010 UFO Coders <info@ufocoders.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "bluetoothagent.h"
#include <QDBusObjectPath>
#include <QFile>
#include <QStandardPaths>
#include <QXmlStreamReader>
#include <BluezQt/Device>
#include <QDebug>
#include <QThread>
#include <QThreadStorage>
#include <unistd.h>
static int cRandom()
{
static QThreadStorage<bool> initialized_threads;
if (!initialized_threads.localData()) {
unsigned int seed;
initialized_threads.setLocalData(true);
QFile urandom(QStringLiteral("/dev/urandom"));
bool opened = urandom.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
if (!opened || urandom.read(reinterpret_cast<char *>(&seed), sizeof(seed)) != sizeof(seed)) {
// silence warnings about use of deprecated qsrand()/qrand()
// Porting to QRandomGenerator::global() instead might result in no new seed set for the generator behind qrand()
// which then might affect other places indirectly relying on this.
// So just keeping the old calls here, as this method is also deprecated and will disappear together with qsrand/qrand.
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wdeprecated-declarations")
QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations")
// No /dev/urandom... try something else.
qsrand(getpid());
seed = qrand() ^ time(nullptr) ^ reinterpret_cast<quintptr>(QThread::currentThread());
}
qsrand(seed);
}
return qrand();
QT_WARNING_POP
}
BluetoothAgent::BluetoothAgent(QObject *parent)
: BluezQt::Agent(parent)
, m_fromDatabase(false)
{
}
QString BluetoothAgent::pin()
{
return m_pin;
}
void BluetoothAgent::setPin(const QString &pin)
{
m_pin = pin;
m_fromDatabase = false;
}
bool BluetoothAgent::isFromDatabase()
{
return m_fromDatabase;
}
QString BluetoothAgent::getPin(BluezQt::DevicePtr device)
{
m_fromDatabase = false;
m_pin = QString::number(cRandom());
m_pin = m_pin.left(6);
const QString &xmlPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("pin-code-database.xml"));
QFile file(xmlPath);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Can't open the pin-code-database.xml";
return m_pin;
}
QXmlStreamReader xml(&file);
QString deviceType = BluezQt::Device::typeToString(device->type());
if (deviceType == QLatin1String("audiovideo")) {
deviceType = QStringLiteral("audio");
}
while (!xml.atEnd()) {
xml.readNext();
if (xml.name() != QLatin1String("device")) {
continue;
}
QXmlStreamAttributes attr = xml.attributes();
if (attr.count() == 0) {
continue;
}
if (attr.hasAttribute(QLatin1String("type")) && attr.value(QLatin1String("type")) != QLatin1String("any")) {
if (deviceType != attr.value(QLatin1String("type")).toString()) {
continue;
}
}
if (attr.hasAttribute(QLatin1String("oui"))) {
if (!device->address().startsWith(attr.value(QLatin1String("oui")).toString())) {
continue;
}
}
if (attr.hasAttribute(QLatin1String("name"))) {
if (device->name() != attr.value(QLatin1String("name")).toString()) {
continue;
}
}
m_pin = attr.value(QLatin1String("pin")).toString();
m_fromDatabase = true;
if (m_pin.startsWith(QLatin1String("max:"))) {
m_fromDatabase = false;
int num = m_pin.rightRef(m_pin.length() - 4).toInt();
m_pin = QString::number(cRandom()).left(num);
}
qDebug() << "PIN: " << m_pin;
return m_pin;
}
return m_pin;
}
QDBusObjectPath BluetoothAgent::objectPath() const
{
return QDBusObjectPath(QStringLiteral("/agent"));
}
void BluetoothAgent::requestPinCode(BluezQt::DevicePtr device, const BluezQt::Request<QString> &req)
{
qDebug() << "AGENT-RequestPinCode" << device->ubi();
Q_EMIT pinRequested(m_pin);
req.accept(m_pin);
}
void BluetoothAgent::displayPinCode(BluezQt::DevicePtr device, const QString &pinCode)
{
qDebug() << "AGENT-DisplayPinCode" << device->ubi() << pinCode;
Q_EMIT pinRequested(pinCode);
}
void BluetoothAgent::requestPasskey(BluezQt::DevicePtr device, const BluezQt::Request<quint32> &req)
{
qDebug() << "AGENT-RequestPasskey" << device->ubi();
Q_EMIT pinRequested(m_pin);
req.accept(m_pin.toUInt());
}
void BluetoothAgent::displayPasskey(BluezQt::DevicePtr device, const QString &passkey, const QString &entered)
{
Q_UNUSED(entered);
qDebug() << "AGENT-DisplayPasskey" << device->ubi() << passkey;
Q_EMIT pinRequested(passkey);
}
void BluetoothAgent::requestConfirmation(BluezQt::DevicePtr device, const QString &passkey, const BluezQt::Request<> &req)
{
qDebug() << "AGENT-RequestConfirmation " << device->ubi() << passkey;
Q_EMIT confirmationRequested(passkey, req);
}

@ -1,43 +0,0 @@
/*
* SPDX-FileCopyrightText: 2010 Alex Fiestas <alex@eyeos.org>
* SPDX-FileCopyrightText: 2010 UFO Coders <info@ufocoders.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef BLUETOOTHAGENT_H
#define BLUETOOTHAGENT_H
#include <BluezQt/Agent>
class BluetoothAgent : public BluezQt::Agent
{
Q_OBJECT
public:
explicit BluetoothAgent(QObject *parent = nullptr);
QString pin();
void setPin(const QString &pin);
bool isFromDatabase();
QString getPin(BluezQt::DevicePtr device);
QDBusObjectPath objectPath() const override;
void requestPinCode(BluezQt::DevicePtr device, const BluezQt::Request<QString> &req) override;
void displayPinCode(BluezQt::DevicePtr device, const QString &pinCode) override;
void requestPasskey(BluezQt::DevicePtr device, const BluezQt::Request<quint32> &req) override;
void displayPasskey(BluezQt::DevicePtr device, const QString &passkey, const QString &entered) override;
void requestConfirmation(BluezQt::DevicePtr device, const QString &passkey, const BluezQt::Request<> &req) override;
Q_SIGNALS:
void pinRequested(const QString &pin);
void confirmationRequested(const QString &passkey, const BluezQt::Request<> &req);
private:
bool m_fromDatabase;
QString m_pin;
};
#endif // BluetoothAgent_H

@ -1,140 +0,0 @@
#include "bluetoothmanager.h"
#include <QDebug>
#include <BluezQt/InitManagerJob>
#include <BluezQt/Adapter>
#include <BluezQt/Device>
#include <BluezQt/MediaPlayer>
BluetoothManager::BluetoothManager(QObject *parent)
: QObject(parent)
, m_agent(new BluetoothAgent(this))
{
m_manager = new BluezQt::Manager(this);
BluezQt::InitManagerJob *initJob = m_manager->init();
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();
if (adaptor) {
if (!adaptor->isDiscoverable()) {
adaptor->setDiscoverable(true);
}
}
}
});
}
BluetoothManager::~BluetoothManager()
{
m_manager->unregisterAgent(m_agent);
delete m_agent;
delete m_manager;
}
void BluetoothManager::setName(const QString &name)
{
BluezQt::AdapterPtr adaptor = m_manager->usableAdapter();
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::deviceDisconnect(const QString address)
{
stopMediaPlayer(address);
BluezQt::AdapterPtr adaptor = m_manager->usableAdapter();
BluezQt::DevicePtr device = adaptor->deviceForAddress(address);
BluezQt::PendingCall *pairCall = device->disconnectFromDevice();
// connect(pairCall, &BluezQt::PendingCall::finished, this, &Bluetooth::disconnectFromDeviceFinished);
}
void BluetoothManager::deviceRemoved(const QString address)
{
stopMediaPlayer(address);
BluezQt::AdapterPtr adaptor = m_manager->usableAdapter();
BluezQt::DevicePtr device = adaptor->deviceForAddress(address);
BluezQt::PendingCall *removeCall = adaptor->removeDevice(device);
// connect(removeCall, &BluezQt::PendingCall::finished, this, &Bluetooth::removeDeviceFinished);
}
void BluetoothManager::stopMediaPlayer(const QString address)
{
BluezQt::AdapterPtr adaptor = m_manager->usableAdapter();
BluezQt::DevicePtr device = adaptor->deviceForAddress(address);
BluezQt::MediaPlayerPtr mediaPlayer = device->mediaPlayer();
if (mediaPlayer){
mediaPlayer->stop();
}
}
void BluetoothManager::onInitJobResult(BluezQt::InitManagerJob *job)
{
if (job->error()) {
qDebug() << "Init Bluetooth error";
return;
}
// Make sure to register agent when bluetoothd starts
operationalChanged(m_manager->isOperational());
connect(m_manager, &BluezQt::Manager::operationalChanged, this, &BluetoothManager::operationalChanged);
m_adapter = m_manager->usableAdapter();
if (m_adapter) {
setName("CutefishOS");
if (!m_adapter->isDiscoverable())
m_adapter->startDiscovery();
}
}
void BluetoothManager::operationalChanged(bool operational)
{
if (operational) {
m_manager->registerAgent(m_agent);
} else {
// Attempt to start bluetoothd
BluezQt::Manager::startService();
}
}
void BluetoothManager::confirmationRequested(const QString &passkey, const BluezQt::Request<> &req)
{
m_req = req;
Q_EMIT showPairDialog(m_device->name(), passkey);
}

@ -1,41 +0,0 @@
#ifndef BLUETOOTHMANAGER_H
#define BLUETOOTHMANAGER_H
#include <QObject>
#include <BluezQt/Manager>
#include "bluetoothagent.h"
class BluetoothManager : public QObject
{
Q_OBJECT
public:
explicit BluetoothManager(QObject *parent = nullptr);
~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);
Q_INVOKABLE void deviceDisconnect(const QString address);
Q_INVOKABLE void deviceRemoved(const QString address);
Q_INVOKABLE void stopMediaPlayer(const QString address);
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;
};
#endif // BLUETOOTHMANAGER_H

@ -53,13 +53,22 @@ ItemPage {
id: devicesModel
}
BluetoothManager {
Bluez.BluetoothManager {
id: bluetoothMgr
onShowPairDialog: {
_pairDialog.title = name
_pairDialog.pin = pin
_pairDialog.visible = true
}
onPairFailed: {
rootWindow.showPassiveNotification(qsTr("Pairing unsuccessful"), 3000)
}
onConnectFailed: {
rootWindow.showPassiveNotification(qsTr("Connecting Unsuccessful"), 3000)
}
}
PairDialog {
@ -114,15 +123,16 @@ ItemPage {
return totalHeight
}
model: devicesProxyModel //Bluez.Manager.bluetoothOperational ? devicesModel : []
model: Bluez.Manager.bluetoothOperational ? devicesProxyModel : []
section.property: "Section"
section.criteria: ViewSection.FullString
section.delegate: Label {
color: FishUI.Theme.disabledTextColor
topPadding: FishUI.Units.largeSpacing
bottomPadding: FishUI.Units.largeSpacing
text: section == "Connected" ? qsTr("Connected devices")
: qsTr("Available devices")
text: section == "My devices" ? qsTr("My devices")
: qsTr("Other devices")
}
delegate: Item {
@ -131,12 +141,6 @@ ItemPage {
property bool paired: model.Connected && model.Paired
onPairedChanged: {
if (!paired) {
additionalSettings.hide()
}
}
ColumnLayout {
id: _itemLayout
anchors.fill: parent
@ -164,7 +168,7 @@ ItemPage {
acceptedButtons: Qt.LeftButton
onClicked: {
if (model.Connected && model.Paired){
if (model.Connected || model.Paired){
additionalSettings.toggle()
return
}
@ -180,6 +184,7 @@ ItemPage {
RowLayout {
id: _contentLayout
anchors.fill: parent
anchors.rightMargin: FishUI.Units.smallSpacing
Image {
width: 16
@ -195,6 +200,11 @@ ItemPage {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
}
Label {
visible: model.Paired
text: model.Connected ? qsTr("Connected") : qsTr("Not Connected")
}
}
}
@ -211,8 +221,21 @@ ItemPage {
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()
@ -229,6 +252,8 @@ ItemPage {
}
}
}
HorizontalDivider {}
}
}
}

@ -1,4 +1,4 @@
import QtQuick 2.4
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
@ -6,33 +6,60 @@ import Cutefish.Settings 1.0
import FishUI 1.0 as FishUI
import "../"
Window {
FishUI.Window {
id: control
width: 200
height: 100
width: contentWidth
height: contentHeight
minimumWidth: 200
minimumHeight: 100
maximumWidth: 200
maximumHeight: 100
property int contentWidth: mainLayout.implicitWidth + FishUI.Units.largeSpacing * 2 + control.header.height
property int contentHeight: mainLayout.implicitHeight + FishUI.Units.largeSpacing * 2 + control.header.height
minimumWidth: contentWidth
minimumHeight: contentHeight
maximumWidth: contentWidth
maximumHeight: contentHeight
modality: Qt.WindowModal
flags: Qt.WindowStaysOnTopHint
flags: Qt.Dialog | Qt.FramelessWindowHint
visible: false
title: " "
Rectangle {
anchors.fill: parent
color: FishUI.Theme.secondBackgroundColor
property var pin: ""
background.color: FishUI.Theme.secondBackgroundColor
headerItem: Item {
Label {
anchors.fill: parent
anchors.leftMargin: FishUI.Units.largeSpacing
text: control.title
}
}
DragHandler {
target: null
acceptedDevices: PointerDevice.GenericPointer
grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
onActiveChanged: if (active) { control.helper.startSystemMove(control) }
}
ColumnLayout {
id: mainLayout
anchors.fill: parent
anchors.margins: FishUI.Units.largeSpacing
Label {
text: qsTr("Bluetooth Pairing Request")
Layout.alignment: Qt.AlignHCenter
}
Label {
text: "<b>%1</b>".arg(control.pin)
visible: control.pin !== ""
font.pointSize: 16
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: FishUI.Units.largeSpacing
}
RowLayout {

@ -468,27 +468,52 @@
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="30"/>
<location filename="../src/qml/Bluetooth/Main.qml" line="84"/>
<location filename="../src/qml/Bluetooth/Main.qml" line="93"/>
<source>Bluetooth</source>
<translation type="unfinished">Bluetooth</translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="124"/>
<source>Connected devices</source>
<location filename="../src/qml/Bluetooth/Main.qml" line="66"/>
<source>Pairing unsuccessful</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="125"/>
<source>Available devices</source>
<location filename="../src/qml/Bluetooth/Main.qml" line="70"/>
<source>Connecting Unsuccessful</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="215"/>
<location filename="../src/qml/Bluetooth/Main.qml" line="134"/>
<source>My devices</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="135"/>
<source>Other devices</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="206"/>
<source>Connected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="206"/>
<source>Not Connected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="225"/>
<source>Connect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="237"/>
<source>Disconnect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="223"/>
<location filename="../src/qml/Bluetooth/Main.qml" line="246"/>
<source>Forget This Device</source>
<translation type="unfinished"></translation>
</message>
@ -628,54 +653,54 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="65"/>
<location filename="../src/qml/Proxy/Main.qml" line="69"/>
<source>No Proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="70"/>
<location filename="../src/qml/Proxy/Main.qml" line="78"/>
<source>Detect proxy configuration automatically</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="75"/>
<location filename="../src/qml/Proxy/Main.qml" line="87"/>
<source>Use proxy auto configuration URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="80"/>
<location filename="../src/qml/Proxy/Main.qml" line="96"/>
<source>Use manually specified proxy configuration</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="100"/>
<location filename="../src/qml/Proxy/Main.qml" line="124"/>
<source>Select file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="114"/>
<location filename="../src/qml/Proxy/Main.qml" line="138"/>
<source>HTTP Proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="124"/>
<location filename="../src/qml/Proxy/Main.qml" line="165"/>
<location filename="../src/qml/Proxy/Main.qml" line="186"/>
<location filename="../src/qml/Proxy/Main.qml" line="153"/>
<location filename="../src/qml/Proxy/Main.qml" line="207"/>
<location filename="../src/qml/Proxy/Main.qml" line="241"/>
<source>Port</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="139"/>
<location filename="../src/qml/Proxy/Main.qml" line="174"/>
<source>Also use this proxy for FTP</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="154"/>
<location filename="../src/qml/Proxy/Main.qml" line="190"/>
<source>FTP Proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="177"/>
<location filename="../src/qml/Proxy/Main.qml" line="225"/>
<source>SOCKS Proxy</source>
<translation type="unfinished"></translation>
</message>
@ -683,17 +708,17 @@
<context>
<name>PairDialog</name>
<message>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="35"/>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="52"/>
<source>Bluetooth Pairing Request</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="42"/>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="69"/>
<source>Cancel</source>
<translation type="unfinished">Cancel</translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="51"/>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="78"/>
<source>OK</source>
<translation type="unfinished"></translation>
</message>

@ -468,27 +468,52 @@
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="30"/>
<location filename="../src/qml/Bluetooth/Main.qml" line="84"/>
<location filename="../src/qml/Bluetooth/Main.qml" line="93"/>
<source>Bluetooth</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="124"/>
<source>Connected devices</source>
<translation></translation>
<location filename="../src/qml/Bluetooth/Main.qml" line="66"/>
<source>Pairing unsuccessful</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="125"/>
<source>Available devices</source>
<translation></translation>
<location filename="../src/qml/Bluetooth/Main.qml" line="70"/>
<source>Connecting Unsuccessful</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="215"/>
<location filename="../src/qml/Bluetooth/Main.qml" line="134"/>
<source>My devices</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="135"/>
<source>Other devices</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="206"/>
<source>Connected</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="206"/>
<source>Not Connected</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="225"/>
<source>Connect</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="237"/>
<source>Disconnect</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/Main.qml" line="223"/>
<location filename="../src/qml/Bluetooth/Main.qml" line="246"/>
<source>Forget This Device</source>
<translation></translation>
</message>
@ -628,54 +653,54 @@
<translation></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="65"/>
<location filename="../src/qml/Proxy/Main.qml" line="69"/>
<source>No Proxy</source>
<translation>使</translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="70"/>
<location filename="../src/qml/Proxy/Main.qml" line="78"/>
<source>Detect proxy configuration automatically</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="75"/>
<location filename="../src/qml/Proxy/Main.qml" line="87"/>
<source>Use proxy auto configuration URL</source>
<translation>使 URL</translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="80"/>
<location filename="../src/qml/Proxy/Main.qml" line="96"/>
<source>Use manually specified proxy configuration</source>
<translation>使</translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="100"/>
<location filename="../src/qml/Proxy/Main.qml" line="124"/>
<source>Select file</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="114"/>
<location filename="../src/qml/Proxy/Main.qml" line="138"/>
<source>HTTP Proxy</source>
<translation>HTTP </translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="124"/>
<location filename="../src/qml/Proxy/Main.qml" line="165"/>
<location filename="../src/qml/Proxy/Main.qml" line="186"/>
<location filename="../src/qml/Proxy/Main.qml" line="153"/>
<location filename="../src/qml/Proxy/Main.qml" line="207"/>
<location filename="../src/qml/Proxy/Main.qml" line="241"/>
<source>Port</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="139"/>
<location filename="../src/qml/Proxy/Main.qml" line="174"/>
<source>Also use this proxy for FTP</source>
<translation> FTP</translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="154"/>
<location filename="../src/qml/Proxy/Main.qml" line="190"/>
<source>FTP Proxy</source>
<translation>FTP </translation>
</message>
<message>
<location filename="../src/qml/Proxy/Main.qml" line="177"/>
<location filename="../src/qml/Proxy/Main.qml" line="225"/>
<source>SOCKS Proxy</source>
<translation>SOCKS </translation>
</message>
@ -683,17 +708,17 @@
<context>
<name>PairDialog</name>
<message>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="35"/>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="52"/>
<source>Bluetooth Pairing Request</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="42"/>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="69"/>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="51"/>
<location filename="../src/qml/Bluetooth/PairDialog.qml" line="78"/>
<source>OK</source>
<translation></translation>
</message>
@ -800,10 +825,6 @@
<source>Bluetooth</source>
<translation></translation>
</message>
<message>
<source>VPN</source>
<translation type="vanished">VPN</translation>
</message>
<message>
<location filename="../src/qml/SideBar.qml" line="159"/>
<location filename="../src/qml/SideBar.qml" line="168"/>

Loading…
Cancel
Save