diff options
author | Jerome Pasion <jerome.pasion@digia.com> | 2012-09-25 15:20:41 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-09-27 14:43:52 +0200 |
commit | d8a179128c0fa8e9cc482df58b9334c696602be6 (patch) | |
tree | dd5032440aa87dfd63c973265adc9947db0918f6 /examples/bluetooth/btfiletransfer | |
parent | 9d89c661395347bdda9362a77d38c86ad60f486b (diff) |
Qt Bluetooth: Modularized documentation
-moved documentation to src/bluetooth/doc
-added a qdocconf file for Qt Bluetooth
-fixed relative paths for snippets
-moved examples to examples/bluetooth
Change-Id: Id41bac50dca628400568d191f1c3ccfbaac790a1
Reviewed-by: Alex <ablasche@gmail.com>
Diffstat (limited to 'examples/bluetooth/btfiletransfer')
16 files changed, 1283 insertions, 0 deletions
diff --git a/examples/bluetooth/btfiletransfer/btfiletransfer.pro b/examples/bluetooth/btfiletransfer/btfiletransfer.pro new file mode 100644 index 00000000..bc634193 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/btfiletransfer.pro @@ -0,0 +1,27 @@ +TEMPLATE = app +TARGET = btfiletransfer + +QT += concurrent bluetooth widgets + +SOURCES = \ + main.cpp \ + remoteselector.cpp \ + progress.cpp \ + pindisplay.cpp + +HEADERS = \ + remoteselector.h \ + progress.h \ + pindisplay.h + +FORMS = \ + remoteselector.ui \ + progress.ui \ + pindisplay.ui + +OTHER_FILES += \ + busy.gif \ + pairing.gif + +RESOURCES += \ + btfiletransfer.qrc diff --git a/examples/bluetooth/btfiletransfer/btfiletransfer.qrc b/examples/bluetooth/btfiletransfer/btfiletransfer.qrc new file mode 100644 index 00000000..10697d5b --- /dev/null +++ b/examples/bluetooth/btfiletransfer/btfiletransfer.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/icons"> + <file>busy.gif</file> + <file>pairing.gif</file> + </qresource> +</RCC> diff --git a/examples/bluetooth/btfiletransfer/busy.gif b/examples/bluetooth/btfiletransfer/busy.gif Binary files differnew file mode 100644 index 00000000..e192ca89 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/busy.gif diff --git a/examples/bluetooth/btfiletransfer/doc/images/btfiletransfer-example.png b/examples/bluetooth/btfiletransfer/doc/images/btfiletransfer-example.png Binary files differnew file mode 100644 index 00000000..f98241d6 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/doc/images/btfiletransfer-example.png diff --git a/examples/bluetooth/btfiletransfer/doc/src/btfiletransfer.qdoc b/examples/bluetooth/btfiletransfer/doc/src/btfiletransfer.qdoc new file mode 100644 index 00000000..200b3d6f --- /dev/null +++ b/examples/bluetooth/btfiletransfer/doc/src/btfiletransfer.qdoc @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt local connectivty modules. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example btfiletransfer + \title Bluetooth File Transfer Example + + The Bluetooth File Transfer example is an application to transfer files + via a bluetooth connection. + + \image btfiletransfer-example.png + +*/ diff --git a/examples/bluetooth/btfiletransfer/main.cpp b/examples/bluetooth/btfiletransfer/main.cpp new file mode 100644 index 00000000..4362c023 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/main.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "remoteselector.h" + +#include <QApplication> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + RemoteSelector d; + QObject::connect(&d, SIGNAL(accepted()), &app, SLOT(quit())); + d.startDiscovery(); + d.show(); + + app.exec(); + + return 0; +} + diff --git a/examples/bluetooth/btfiletransfer/pairing.gif b/examples/bluetooth/btfiletransfer/pairing.gif Binary files differnew file mode 100644 index 00000000..e147f3ec --- /dev/null +++ b/examples/bluetooth/btfiletransfer/pairing.gif diff --git a/examples/bluetooth/btfiletransfer/pindisplay.cpp b/examples/bluetooth/btfiletransfer/pindisplay.cpp new file mode 100644 index 00000000..bdef6b36 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/pindisplay.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pindisplay.h" +#include "ui_pindisplay.h" + +pinDisplay::pinDisplay(QString title, QString pin, QWidget *parent) : + QDialog(parent), + ui(new Ui::pinDisplay) +{ + ui->setupUi(this); + ui->label->setText(title); + ui->pin->setText(pin); + + connect(ui->buttonBox, SIGNAL(accepted()), this, SIGNAL(accepted())); + connect(ui->buttonBox, SIGNAL(rejected()), this, SIGNAL(rejected())); +} + +pinDisplay::~pinDisplay() +{ + delete ui; +} + +void pinDisplay::on_buttonBox_accepted() +{ + deleteLater(); +} + +void pinDisplay::setOkCancel() +{ + ui->buttonBox->addButton(QDialogButtonBox::Cancel); +} diff --git a/examples/bluetooth/btfiletransfer/pindisplay.h b/examples/bluetooth/btfiletransfer/pindisplay.h new file mode 100644 index 00000000..fd1b50aa --- /dev/null +++ b/examples/bluetooth/btfiletransfer/pindisplay.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PINDISPLAY_H +#define PINDISPLAY_H + +#include <QDialog> + +QT_BEGIN_NAMESPACE +namespace Ui { + class pinDisplay; +} +QT_END_NAMESPACE + +class pinDisplay : public QDialog +{ + Q_OBJECT + +public: + explicit pinDisplay(QString title, QString pin, QWidget *parent = 0); + ~pinDisplay(); + + void setOkCancel(); + +private Q_SLOTS: + void on_buttonBox_accepted(); + +private: + Ui::pinDisplay *ui; +}; + +#endif // PINDISPLAY_H diff --git a/examples/bluetooth/btfiletransfer/pindisplay.ui b/examples/bluetooth/btfiletransfer/pindisplay.ui new file mode 100644 index 00000000..02bf7d50 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/pindisplay.ui @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>pinDisplay</class> + <widget class="QDialog" name="pinDisplay"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>240</width> + <height>153</height> + </rect> + </property> + <property name="windowTitle"> + <string>Enter Pin Code</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="pin"> + <property name="font"> + <font> + <family>Monospace</family> + <pointsize>24</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>012345</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>pinDisplay</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>pinDisplay</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/examples/bluetooth/btfiletransfer/progress.cpp b/examples/bluetooth/btfiletransfer/progress.cpp new file mode 100644 index 00000000..d589e9b5 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/progress.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "progress.h" +#include "ui_progress.h" + +#include <qbluetoothdeviceinfo.h> +#include <qbluetoothaddress.h> +#include <qbluetoothtransferrequest.h> +#include <qbluetoothtransferreply.h> + +QTBLUETOOTH_USE_NAMESPACE + +Progress::Progress(QWidget *parent) : + QDialog(parent), + ui(new Ui::Progress) +{ + ui->setupUi(this); + ui->progressBar->setRange(0, 1); + connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(close())); +} + +Progress::~Progress() +{ + delete ui; +} + +void Progress::setStatus(QString title, QString filename) { + ui->titleLabel->setText(title); + ui->statusLabel->setText(filename); +} + +void Progress::finished(QBluetoothTransferReply *reply){ + if (reply->error() != QBluetoothTransferReply::NoError){ + ui->progressBar->setDisabled(true); + ui->statusLabel->setText(tr("Failed: %1").arg(reply->errorString())); + } + else { + ui->statusLabel->setText(tr("Transfer complete")); + } + ui->cancelButton->setText(tr("Dismiss")); +} + +void Progress::uploadProgress(qint64 bytesSent, qint64 bytesTotal) +{ + if (bytesSent == 0){ + start.start(); + } + + ui->progressBar->setMaximum(bytesTotal); + ui->progressBar->setValue(bytesSent); + if (bytesSent && bytesTotal && + (start.elapsed() > 1000) && + (bytesSent > start.elapsed()/1000)) { + + ui->statusLabel->setText(tr("Transferring...ETA: %1s") + .arg(((bytesTotal-bytesSent)/(bytesSent/(start.elapsed()/1000))))); + } +} + diff --git a/examples/bluetooth/btfiletransfer/progress.h b/examples/bluetooth/btfiletransfer/progress.h new file mode 100644 index 00000000..400c9b70 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/progress.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PROGRESS_H +#define PROGRESS_H + +#include <QDialog> +#include <qbluetoothglobal.h> +#include <QTime> + +QTBLUETOOTH_BEGIN_NAMESPACE +class QBluetoothTransferReply; +QTBLUETOOTH_END_NAMESPACE + +QTBLUETOOTH_USE_NAMESPACE + +QT_BEGIN_NAMESPACE +namespace Ui { + class Progress; +} +QT_END_NAMESPACE + +class Progress : public QDialog +{ + Q_OBJECT + +public: + explicit Progress(QWidget *parent = 0); + ~Progress(); + + void setStatus(QString title, QString filename); + +public Q_SLOTS: + void finished(QBluetoothTransferReply *); + void uploadProgress(qint64 bytesSent, qint64 bytesTotal); + +private: + Ui::Progress *ui; + + QTime start; +}; + +#endif // PROGRESS_H diff --git a/examples/bluetooth/btfiletransfer/progress.ui b/examples/bluetooth/btfiletransfer/progress.ui new file mode 100644 index 00000000..3b151f06 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/progress.ui @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Progress</class> + <widget class="QDialog" name="Progress"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>408</width> + <height>115</height> + </rect> + </property> + <property name="windowTitle"> + <string>Transfer Progress</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="titleLabel"> + <property name="text"> + <string>Filename</string> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="minimumSize"> + <size> + <width>390</width> + <height>0</height> + </size> + </property> + <property name="value"> + <number>24</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="statusLabel"> + <property name="text"> + <string>Status</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/examples/bluetooth/btfiletransfer/remoteselector.cpp b/examples/bluetooth/btfiletransfer/remoteselector.cpp new file mode 100644 index 00000000..80d8761e --- /dev/null +++ b/examples/bluetooth/btfiletransfer/remoteselector.cpp @@ -0,0 +1,372 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "remoteselector.h" +#include "ui_remoteselector.h" + +#include <qbluetoothdeviceinfo.h> +#include <qbluetoothaddress.h> +#include <qbluetoothtransferrequest.h> +#include <qbluetoothtransferreply.h> +#include <qbluetoothlocaldevice.h> + +#include <QMovie> +#include <QMessageBox> +#include <QFileDialog> +#include <QCheckBox> + +#include "progress.h" +#include "pindisplay.h" + +QTBLUETOOTH_USE_NAMESPACE + +RemoteSelector::RemoteSelector(QWidget *parent) +: QDialog(parent), ui(new Ui::RemoteSelector), + m_discoveryAgent(new QBluetoothServiceDiscoveryAgent), m_localDevice(new QBluetoothLocalDevice), m_pindisplay(0) +{ + ui->setupUi(this); + + connect(m_discoveryAgent, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)), + this, SLOT(serviceDiscovered(QBluetoothServiceInfo))); + connect(m_discoveryAgent, SIGNAL(finished()), this, SLOT(discoveryFinished())); + + ui->remoteDevices->setColumnWidth(3, 75); + ui->remoteDevices->setColumnWidth(4, 100); + + connect(m_localDevice, SIGNAL(pairingDisplayPinCode(const QBluetoothAddress &,QString)), this, SLOT(displayPin(const QBluetoothAddress &, QString))); + connect(m_localDevice, SIGNAL(pairingDisplayConfirmation(QBluetoothAddress,QString)), this, SLOT(displayConfirmation(QBluetoothAddress,QString))); + connect(m_localDevice, SIGNAL(pairingFinished(QBluetoothAddress,QBluetoothLocalDevice::Pairing)), this, SLOT(pairingFinished(QBluetoothAddress,QBluetoothLocalDevice::Pairing))); + + ui->busyWidget->setMovie(new QMovie(":/icons/busy.gif")); + ui->busyWidget->movie()->start(); + + ui->pairingBusy->setMovie(new QMovie(":/icons/pairing.gif")); + ui->pairingBusy->hide(); + + ui->remoteDevices->clearContents(); + ui->remoteDevices->setRowCount(0); + + +} + +RemoteSelector::~RemoteSelector() +{ + delete ui; + delete m_discoveryAgent; + delete m_localDevice; +} + +void RemoteSelector::startDiscovery(const QBluetoothUuid &uuid) +{ + ui->stopButton->setDisabled(false); + if (m_discoveryAgent->isActive()) + m_discoveryAgent->stop(); + + m_discoveryAgent->setUuidFilter(uuid); + m_discoveryAgent->start(); + + ui->status->setText(tr("Scanning...")); + ui->busyWidget->show(); + ui->busyWidget->movie()->start(); +} + +QBluetoothServiceInfo RemoteSelector::service() const +{ + return m_service; +} + +void RemoteSelector::serviceDiscovered(const QBluetoothServiceInfo &serviceInfo) +{ +#if 0 + qDebug() << "Discovered service on" + << serviceInfo.device().name() << serviceInfo.device().address().toString(); + qDebug() << "\tService name:" << serviceInfo.serviceName(); + qDebug() << "\tDescription:" + << serviceInfo.attribute(QBluetoothServiceInfo::ServiceDescription).toString(); + qDebug() << "\tProvider:" + << serviceInfo.attribute(QBluetoothServiceInfo::ServiceProvider).toString(); + qDebug() << "\tL2CAP protocol service multiplexer:" + << serviceInfo.protocolServiceMultiplexer(); + qDebug() << "\tRFCOMM server channel:" << serviceInfo.serverChannel(); +#endif + + QString remoteName; + if (serviceInfo.device().name().isEmpty()) + remoteName = serviceInfo.device().address().toString(); + else + remoteName = serviceInfo.device().name(); + +// QListWidgetItem *item = +// new QListWidgetItem(QString::fromLatin1("%1\t%2\t%3").arg(serviceInfo.device().address().toString(), +// serviceInfo.device().name(), serviceInfo.serviceName())); + + QMutableMapIterator<int, QBluetoothServiceInfo> i(m_discoveredServices); + while (i.hasNext()){ + i.next(); + if (serviceInfo.device().address() == i.value().device().address()){ + i.setValue(serviceInfo); + return; + } + } + + int row = ui->remoteDevices->rowCount(); + ui->remoteDevices->insertRow(row); + QTableWidgetItem *item = new QTableWidgetItem(serviceInfo.device().address().toString()); + ui->remoteDevices->setItem(row, 0, item); + item = new QTableWidgetItem(serviceInfo.device().name()); + ui->remoteDevices->setItem(row, 1, item); + item = new QTableWidgetItem(serviceInfo.serviceName()); + + ui->remoteDevices->setItem(row, 2, item); + + QBluetoothLocalDevice::Pairing p; + + p = m_localDevice->pairingStatus(serviceInfo.device().address()); + + ui->remoteDevices->blockSignals(true); + + item = new QTableWidgetItem(); + if ((p&QBluetoothLocalDevice::Paired) || (p&QBluetoothLocalDevice::AuthorizedPaired)) + item->setCheckState(Qt::Checked); + else + item->setCheckState(Qt::Unchecked); + ui->remoteDevices->setItem(row, 3, item); + + item = new QTableWidgetItem(); + if (p&QBluetoothLocalDevice::AuthorizedPaired) + item->setCheckState(Qt::Checked); + else + item->setCheckState(Qt::Unchecked); + + ui->remoteDevices->setItem(row, 4, item); + + ui->remoteDevices->blockSignals(false); + + + m_discoveredServices.insert(row, serviceInfo); +} + +void RemoteSelector::discoveryFinished() +{ + ui->status->setText(tr("Select the device to send to.")); + ui->stopButton->setDisabled(true); + ui->busyWidget->movie()->stop(); + ui->busyWidget->hide(); +} + +void RemoteSelector::startDiscovery() +{ + startDiscovery(QBluetoothUuid(QBluetoothUuid::ObexObjectPush)); +} + +void RemoteSelector::on_refreshPB_clicked() +{ + startDiscovery(); + ui->stopButton->setDisabled(false); +} + +void RemoteSelector::on_fileSelectPB_clicked() +{ + ui->fileName->setText(QFileDialog::getOpenFileName()); + if (m_service.isValid()) + ui->sendButton->setDisabled(false); +} + +void RemoteSelector::on_sendButton_clicked() +{ + QBluetoothTransferManager mgr; + QBluetoothTransferRequest req(m_service.device().address()); + + m_file = new QFile(ui->fileName->text()); + + Progress *p = new Progress; + p->setStatus("Sending to: " + m_service.device().name(), "Waiting for start"); + p->show(); + + QBluetoothTransferReply *reply = mgr.put(req, m_file); + if (reply->error()){ + qDebug() << "Failed to send file"; + delete reply; + p->finished(reply); + return; + } + + connect(reply, SIGNAL(uploadProgress(qint64,qint64)), p, SLOT(uploadProgress(qint64,qint64))); + connect(reply, SIGNAL(finished(QBluetoothTransferReply*)), p, SLOT(finished(QBluetoothTransferReply*))); + connect(p, SIGNAL(rejected()), reply, SLOT(abort())); +} + +void RemoteSelector::on_stopButton_clicked() +{ + m_discoveryAgent->stop(); +} + +QString RemoteSelector::addressToName(const QBluetoothAddress &address) +{ + QMapIterator<int, QBluetoothServiceInfo> i(m_discoveredServices); + while (i.hasNext()){ + i.next(); + if (i.value().device().address() == address) + return i.value().device().name(); + } + return address.toString(); +} + +void RemoteSelector::displayPin(const QBluetoothAddress &address, QString pin) +{ + if (m_pindisplay) + m_pindisplay->deleteLater(); + m_pindisplay = new pinDisplay(QString("Enter pairing pin on: %1").arg(addressToName(address)), pin, this); + m_pindisplay->show(); +} + +void RemoteSelector::displayConfirmation(const QBluetoothAddress &address, QString pin) +{ + Q_UNUSED(address); + + if (m_pindisplay) + m_pindisplay->deleteLater(); + m_pindisplay = new pinDisplay(QString("Confirm this pin is the same"), pin, this); + connect(m_pindisplay, SIGNAL(accepted()), this, SLOT(displayConfAccepted())); + connect(m_pindisplay, SIGNAL(rejected()), this, SLOT(displayConfReject())); + m_pindisplay->setOkCancel(); + m_pindisplay->show(); +} + +void RemoteSelector::displayConfAccepted() +{ + m_localDevice->pairingConfirmation(true); +} +void RemoteSelector::displayConfReject() +{ + m_localDevice->pairingConfirmation(false); +} + +void RemoteSelector::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing status) +{ + QBluetoothServiceInfo service; + int row = 0; + + ui->pairingBusy->hide(); + ui->pairingBusy->movie()->stop(); + + ui->remoteDevices->blockSignals(true); + + for (int i = 0; i < m_discoveredServices.count(); i++){ + if (m_discoveredServices.value(i).device().address() == address){ + service = m_discoveredServices.value(i); + row = i; + break; + } + } + + if (m_pindisplay) + delete m_pindisplay; + + QMessageBox msgBox; + if (status == QBluetoothLocalDevice::Paired || + status == QBluetoothLocalDevice::AuthorizedPaired){ + msgBox.setText("Paired successfully with" + address.toString()); + } + else { + msgBox.setText("Pairing failed with " + address.toString()); + } + + if (service.isValid()){ + if (status == QBluetoothLocalDevice::AuthorizedPaired){ + ui->remoteDevices->item(row, 3)->setCheckState(Qt::Checked); + ui->remoteDevices->item(row, 4)->setCheckState(Qt::Checked); + } + else if (status == QBluetoothLocalDevice::Paired){ + ui->remoteDevices->item(row, 3)->setCheckState(Qt::Checked); + ui->remoteDevices->item(row, 4)->setCheckState(Qt::Unchecked); + } + else { + ui->remoteDevices->item(row, 3)->setCheckState(Qt::Unchecked); + ui->remoteDevices->item(row, 4)->setCheckState(Qt::Unchecked); + } + } + + msgBox.exec(); + + ui->remoteDevices->blockSignals(false); + + +} + +void RemoteSelector::on_remoteDevices_cellClicked(int row, int column) +{ + Q_UNUSED(column); + + m_service = m_discoveredServices.value(row); + if (!ui->fileName->text().isEmpty()) { + ui->sendButton->setDisabled(false); + } +} + +void RemoteSelector::on_remoteDevices_itemChanged(QTableWidgetItem* item) +{ + int row = item->row(); + int column = item->column(); + m_service = m_discoveredServices.value(row); + + if (column < 3) + return; + + if (item->checkState() == Qt::Unchecked && column == 3){ + m_localDevice->requestPairing(m_service.device().address(), QBluetoothLocalDevice::Unpaired); + return; // don't continue and start movie + } + else if ((item->checkState() == Qt::Checked && column == 3) || + (item->checkState() == Qt::Unchecked && column == 4)){ + m_localDevice->requestPairing(m_service.device().address(), QBluetoothLocalDevice::Paired); + ui->remoteDevices->blockSignals(true); + ui->remoteDevices->item(row, column)->setCheckState(Qt::PartiallyChecked); + ui->remoteDevices->blockSignals(false); + } + else if (item->checkState() == Qt::Checked && column == 4){ + m_localDevice->requestPairing(m_service.device().address(), QBluetoothLocalDevice::AuthorizedPaired); + ui->remoteDevices->blockSignals(true); + ui->remoteDevices->item(row, column)->setCheckState(Qt::PartiallyChecked); + ui->remoteDevices->blockSignals(false); + } + ui->pairingBusy->show(); + ui->pairingBusy->movie()->start(); +} diff --git a/examples/bluetooth/btfiletransfer/remoteselector.h b/examples/bluetooth/btfiletransfer/remoteselector.h new file mode 100644 index 00000000..d3300c9a --- /dev/null +++ b/examples/bluetooth/btfiletransfer/remoteselector.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef REMOTESELECTOR_H +#define REMOTESELECTOR_H + +#include <QDialog> +#include <QPointer> + +#include <qbluetoothuuid.h> +#include <qbluetoothserviceinfo.h> +#include <qbluetoothservicediscoveryagent.h> +#include <qbluetoothlocaldevice.h> + +QT_FORWARD_DECLARE_CLASS(QModelIndex) +QT_FORWARD_DECLARE_CLASS(QTableWidgetItem) +QT_FORWARD_DECLARE_CLASS(QFile) + +class pinDisplay; + +QTBLUETOOTH_USE_NAMESPACE + +QT_BEGIN_NAMESPACE +namespace Ui { + class RemoteSelector; +} +QT_END_NAMESPACE + +class RemoteSelector : public QDialog +{ + Q_OBJECT + +public: + explicit RemoteSelector(QWidget *parent = 0); + ~RemoteSelector(); + + void startDiscovery(const QBluetoothUuid &uuid); + QBluetoothServiceInfo service() const; + +private: + Ui::RemoteSelector *ui; + + QBluetoothServiceDiscoveryAgent *m_discoveryAgent; + QBluetoothServiceInfo m_service; + QMap<int, QBluetoothServiceInfo> m_discoveredServices; + QFile *m_file; + QBluetoothLocalDevice *m_localDevice; + QPointer<pinDisplay> m_pindisplay; + + QString addressToName(const QBluetoothAddress &address); + +public Q_SLOTS: + void startDiscovery(); + +private slots: + void serviceDiscovered(const QBluetoothServiceInfo &serviceInfo); + void discoveryFinished(); + void on_refreshPB_clicked(); + void on_fileSelectPB_clicked(); + void on_sendButton_clicked(); + void on_stopButton_clicked(); + + void pairingFinished(const QBluetoothAddress &address,QBluetoothLocalDevice::Pairing pairing); + void displayPin(const QBluetoothAddress &address, QString pin); + void displayConfirmation(const QBluetoothAddress &address, QString pin); + void displayConfReject(); + void displayConfAccepted(); + + void on_remoteDevices_cellClicked(int row, int column); + void on_remoteDevices_itemChanged(QTableWidgetItem* item); +}; + +#endif // REMOTESELECTOR_H diff --git a/examples/bluetooth/btfiletransfer/remoteselector.ui b/examples/bluetooth/btfiletransfer/remoteselector.ui new file mode 100644 index 00000000..f99deaa7 --- /dev/null +++ b/examples/bluetooth/btfiletransfer/remoteselector.ui @@ -0,0 +1,214 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>RemoteSelector</class> + <widget class="QDialog" name="RemoteSelector"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>681</width> + <height>394</height> + </rect> + </property> + <property name="windowTitle"> + <string>Available file transfer services</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <property name="horizontalSpacing"> + <number>6</number> + </property> + <item row="7" column="0" colspan="2"> + <widget class="QLineEdit" name="fileName"/> + </item> + <item row="7" column="2"> + <widget class="QPushButton" name="fileSelectPB"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Select File</string> + </property> + </widget> + </item> + <item row="8" column="0" colspan="3"> + <widget class="QPushButton" name="sendButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Send</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="3"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="busyWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="status"> + <property name="text"> + <string>Scanning...</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="pairingBusy"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="stopButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="refreshPB"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="0" colspan="3"> + <widget class="QTableWidget" name="remoteDevices"> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAsNeeded</enum> + </property> + <property name="editTriggers"> + <set>QAbstractItemView::NoEditTriggers</set> + </property> + <property name="showDropIndicator" stdset="0"> + <bool>false</bool> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::SingleSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectRows</enum> + </property> + <property name="showGrid"> + <bool>false</bool> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + <property name="rowCount"> + <number>1</number> + </property> + <attribute name="horizontalHeaderCascadingSectionResizes"> + <bool>true</bool> + </attribute> + <attribute name="horizontalHeaderDefaultSectionSize"> + <number>150</number> + </attribute> + <attribute name="horizontalHeaderStretchLastSection"> + <bool>true</bool> + </attribute> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> + <attribute name="verticalHeaderCascadingSectionResizes"> + <bool>false</bool> + </attribute> + <row> + <property name="text"> + <string>Test</string> + </property> + </row> + <column> + <property name="text"> + <string>MAC Address</string> + </property> + </column> + <column> + <property name="text"> + <string>Device Name</string> + </property> + </column> + <column> + <property name="text"> + <string>Device Service</string> + </property> + </column> + <column> + <property name="text"> + <string>Paired</string> + </property> + <property name="toolTip"> + <string comment="Paired" extracomment="Paired"/> + </property> + <property name="whatsThis"> + <string comment="Paired" extracomment="Paired"/> + </property> + <property name="textAlignment"> + <set>AlignHCenter|AlignVCenter|AlignCenter</set> + </property> + </column> + <column> + <property name="text"> + <string>Authorized</string> + </property> + <property name="textAlignment"> + <set>AlignHCenter|AlignVCenter|AlignCenter</set> + </property> + </column> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> |