diff options
-rw-r--r-- | src/serialport/qserialport.cpp | 89 | ||||
-rw-r--r-- | src/serialport/qserialport.h | 25 | ||||
-rw-r--r-- | src/serialport/qserialport_p.h | 44 | ||||
-rw-r--r-- | tests/auto/qserialport/tst_qserialport.cpp | 146 |
4 files changed, 262 insertions, 42 deletions
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp index 75aded42..fc6b204f 100644 --- a/src/serialport/qserialport.cpp +++ b/src/serialport/qserialport.cpp @@ -99,8 +99,8 @@ void QSerialPortPrivate::setError(const QSerialPortErrorInfo &errorInfo) { Q_Q(QSerialPort); - error = errorInfo.errorCode; q->setErrorString(errorInfo.errorString); + error.setValue(errorInfo.errorCode); emit q->errorOccurred(error); } @@ -518,7 +518,7 @@ void QSerialPort::close() } d->close(); - d->isBreakEnabled = false; + d->isBreakEnabled.setValue(false); QIODevice::close(); } @@ -607,13 +607,14 @@ bool QSerialPort::setDataBits(DataBits dataBits) { Q_D(QSerialPort); + const auto currentDataBits = d->dataBits.value(); if (!isOpen() || d->setDataBits(dataBits)) { - if (d->dataBits != dataBits) { - d->dataBits = dataBits; - emit dataBitsChanged(d->dataBits); - } + d->dataBits.setValue(dataBits); + if (currentDataBits != dataBits) + emit dataBitsChanged(dataBits); return true; } + d->dataBits.setValue(currentDataBits); // removes the binding if necessary, keep return false; } @@ -624,6 +625,11 @@ QSerialPort::DataBits QSerialPort::dataBits() const return d->dataBits; } +QBindable<QSerialPort::DataBits> QSerialPort::bindableDataBits() +{ + return &d_func()->dataBits; +} + /*! \fn void QSerialPort::dataBitsChanged(DataBits dataBits) @@ -652,13 +658,14 @@ bool QSerialPort::setParity(Parity parity) { Q_D(QSerialPort); + const auto currentParity = d->parity.value(); if (!isOpen() || d->setParity(parity)) { - if (d->parity != parity) { - d->parity = parity; - emit parityChanged(d->parity); - } + d->parity.setValue(parity); + if (currentParity != parity) + emit parityChanged(parity); return true; } + d->parity.setValue(currentParity); // removes the binding if necessary, keep return false; } @@ -669,6 +676,11 @@ QSerialPort::Parity QSerialPort::parity() const return d->parity; } +QBindable<QSerialPort::Parity> QSerialPort::bindableParity() +{ + return &d_func()->parity; +} + /*! \fn void QSerialPort::parityChanged(Parity parity) @@ -696,13 +708,14 @@ bool QSerialPort::setStopBits(StopBits stopBits) { Q_D(QSerialPort); + const auto currentStopBits = d->stopBits.value(); if (!isOpen() || d->setStopBits(stopBits)) { - if (d->stopBits != stopBits) { - d->stopBits = stopBits; - emit stopBitsChanged(d->stopBits); - } + d->stopBits.setValue(stopBits); + if (currentStopBits != stopBits) + emit stopBitsChanged(stopBits); return true; } + d->stopBits.setValue(currentStopBits); // removes the binding if necessary, keep return false; } @@ -713,6 +726,11 @@ QSerialPort::StopBits QSerialPort::stopBits() const return d->stopBits; } +QBindable<bool> QSerialPort::bindableStopBits() +{ + return &d_func()->stopBits; +} + /*! \fn void QSerialPort::stopBitsChanged(StopBits stopBits) @@ -740,13 +758,14 @@ bool QSerialPort::setFlowControl(FlowControl flowControl) { Q_D(QSerialPort); + const auto currentFlowControl = d->flowControl.value(); if (!isOpen() || d->setFlowControl(flowControl)) { - if (d->flowControl != flowControl) { - d->flowControl = flowControl; - emit flowControlChanged(d->flowControl); - } + d->flowControl.setValue(flowControl); + if (currentFlowControl != flowControl) + emit flowControlChanged(flowControl); return true; } + d->flowControl.setValue(currentFlowControl); // removes the binding if necessary, keep return false; } @@ -757,6 +776,11 @@ QSerialPort::FlowControl QSerialPort::flowControl() const return d->flowControl; } +QBindable<QSerialPort::FlowControl> QSerialPort::bindableFlowControl() +{ + return &d_func()->flowControl; +} + /*! \fn void QSerialPort::flowControlChanged(FlowControl flow) @@ -977,6 +1001,11 @@ void QSerialPort::clearError() d->setError(QSerialPortErrorInfo(QSerialPort::NoError)); } +QBindable<QSerialPort::SerialPortError> QSerialPort::bindableError() const +{ + return &d_func()->error; +} + /*! \fn void QSerialPort::errorOccurred(SerialPortError error) \since 5.8 @@ -1149,19 +1178,20 @@ bool QSerialPort::setBreakEnabled(bool set) { Q_D(QSerialPort); - if (!isOpen()) { + const auto currentSet = d->isBreakEnabled.value(); + if (isOpen()) { + if (d->setBreakEnabled(set)) { + d->isBreakEnabled.setValue(set); + if (currentSet != set) + emit breakEnabledChanged(set); + return true; + } + } else { d->setError(QSerialPortErrorInfo(QSerialPort::NotOpenError)); qWarning("%s: device not open", Q_FUNC_INFO); - return false; } + d->isBreakEnabled.setValue(currentSet); // removes the binding if necessary, keep - if (d->setBreakEnabled(set)) { - if (d->isBreakEnabled != set) { - d->isBreakEnabled = set; - emit breakEnabledChanged(d->isBreakEnabled); - } - return true; - } return false; } @@ -1171,6 +1201,11 @@ bool QSerialPort::isBreakEnabled() const return d->isBreakEnabled; } +QBindable<bool> QSerialPort::bindableIsBreakEnabled() +{ + return &d_func()->isBreakEnabled; +} + /*! \reimp diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h index cf126ddf..8ef0f6b6 100644 --- a/src/serialport/qserialport.h +++ b/src/serialport/qserialport.h @@ -56,14 +56,19 @@ class Q_SERIALPORT_EXPORT QSerialPort : public QIODevice Q_DECLARE_PRIVATE(QSerialPort) Q_PROPERTY(qint32 baudRate READ baudRate WRITE setBaudRate NOTIFY baudRateChanged) - Q_PROPERTY(DataBits dataBits READ dataBits WRITE setDataBits NOTIFY dataBitsChanged) - Q_PROPERTY(Parity parity READ parity WRITE setParity NOTIFY parityChanged) - Q_PROPERTY(StopBits stopBits READ stopBits WRITE setStopBits NOTIFY stopBitsChanged) - Q_PROPERTY(FlowControl flowControl READ flowControl WRITE setFlowControl NOTIFY flowControlChanged) - Q_PROPERTY(bool dataTerminalReady READ isDataTerminalReady WRITE setDataTerminalReady NOTIFY dataTerminalReadyChanged) + Q_PROPERTY(DataBits dataBits READ dataBits WRITE setDataBits NOTIFY dataBitsChanged + BINDABLE bindableDataBits) + Q_PROPERTY(Parity parity READ parity WRITE setParity NOTIFY parityChanged BINDABLE bindableParity) + Q_PROPERTY(StopBits stopBits READ stopBits WRITE setStopBits NOTIFY stopBitsChanged + BINDABLE bindableStopBits) + Q_PROPERTY(FlowControl flowControl READ flowControl WRITE setFlowControl NOTIFY flowControlChanged + BINDABLE bindableFlowControl) + Q_PROPERTY(bool dataTerminalReady READ isDataTerminalReady WRITE setDataTerminalReady + NOTIFY dataTerminalReadyChanged) Q_PROPERTY(bool requestToSend READ isRequestToSend WRITE setRequestToSend NOTIFY requestToSendChanged) - Q_PROPERTY(SerialPortError error READ error RESET clearError NOTIFY error) - Q_PROPERTY(bool breakEnabled READ isBreakEnabled WRITE setBreakEnabled NOTIFY breakEnabledChanged) + Q_PROPERTY(SerialPortError error READ error RESET clearError NOTIFY errorOccurred BINDABLE bindableError) + Q_PROPERTY(bool breakEnabled READ isBreakEnabled WRITE setBreakEnabled NOTIFY breakEnabledChanged + BINDABLE bindableIsBreakEnabled) #if defined(Q_OS_WIN32) typedef void* Handle; @@ -171,15 +176,19 @@ public: bool setDataBits(DataBits dataBits); DataBits dataBits() const; + QBindable<DataBits> bindableDataBits(); bool setParity(Parity parity); Parity parity() const; + QBindable<Parity> bindableParity(); bool setStopBits(StopBits stopBits); StopBits stopBits() const; + QBindable<bool> bindableStopBits(); bool setFlowControl(FlowControl flowControl); FlowControl flowControl() const; + QBindable<FlowControl> bindableFlowControl(); bool setDataTerminalReady(bool set); bool isDataTerminalReady(); @@ -194,6 +203,7 @@ public: SerialPortError error() const; void clearError(); + QBindable<SerialPortError> bindableError() const; qint64 readBufferSize() const; void setReadBufferSize(qint64 size); @@ -209,6 +219,7 @@ public: bool setBreakEnabled(bool set = true); bool isBreakEnabled() const; + QBindable<bool> bindableIsBreakEnabled(); Handle handle() const; diff --git a/src/serialport/qserialport_p.h b/src/serialport/qserialport_p.h index 7348aed6..a9c08e95 100644 --- a/src/serialport/qserialport_p.h +++ b/src/serialport/qserialport_p.h @@ -55,9 +55,11 @@ #include "qserialport.h" -#include <private/qiodevice_p.h> #include <qdeadlinetimer.h> +#include <private/qiodevice_p.h> +#include <private/qproperty_p.h> + #if defined(Q_OS_WIN32) # include <qt_windows.h> #elif defined(Q_OS_UNIX) @@ -114,7 +116,7 @@ QString serialPortLockFilePath(const QString &portName); class QSerialPortErrorInfo { public: - explicit QSerialPortErrorInfo(QSerialPort::SerialPortError newErrorCode = QSerialPort::UnknownError, + QSerialPortErrorInfo(QSerialPort::SerialPortError newErrorCode = QSerialPort::UnknownError, const QString &newErrorString = QString()); QSerialPort::SerialPortError errorCode = QSerialPort::UnknownError; QString errorString; @@ -164,16 +166,42 @@ public: static QList<qint32> standardBaudRates(); qint64 readBufferMaxSize = 0; - QSerialPort::SerialPortError error = QSerialPort::NoError; + + void setBindableError(QSerialPort::SerialPortError error) + { setError(error); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::SerialPortError, error, + &QSerialPortPrivate::setBindableError, QSerialPort::NoError) + QString systemLocation; qint32 inputBaudRate = QSerialPort::Baud9600; qint32 outputBaudRate = QSerialPort::Baud9600; - QSerialPort::DataBits dataBits = QSerialPort::Data8; - QSerialPort::Parity parity = QSerialPort::NoParity; - QSerialPort::StopBits stopBits = QSerialPort::OneStop; - QSerialPort::FlowControl flowControl = QSerialPort::NoFlowControl; + + bool setBindableDataBits(QSerialPort::DataBits dataBits) + { return q_func()->setDataBits(dataBits); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::DataBits, dataBits, + &QSerialPortPrivate::setBindableDataBits, QSerialPort::Data8) + + bool setBindableParity(QSerialPort::Parity parity) + { return q_func()->setParity(parity); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::Parity, parity, + &QSerialPortPrivate::setBindableParity, QSerialPort::NoParity) + + bool setBindableStopBits(QSerialPort::StopBits stopBits) + { return q_func()->setStopBits(stopBits); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::StopBits, stopBits, + &QSerialPortPrivate::setBindableStopBits, QSerialPort::OneStop) + + bool setBindableFlowControl(QSerialPort::FlowControl flowControl) + { return q_func()->setFlowControl(flowControl); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::FlowControl, flowControl, + &QSerialPortPrivate::setBindableFlowControl, QSerialPort::NoFlowControl) + bool settingsRestoredOnClose = true; - bool isBreakEnabled = false; + + bool setBindableBreakEnabled(bool isBreakEnabled) + { return q_func()->setBreakEnabled(isBreakEnabled); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, bool, isBreakEnabled, + &QSerialPortPrivate::setBindableBreakEnabled, false) bool startAsyncRead(); diff --git a/tests/auto/qserialport/tst_qserialport.cpp b/tests/auto/qserialport/tst_qserialport.cpp index f55dac76..84bb7a56 100644 --- a/tests/auto/qserialport/tst_qserialport.cpp +++ b/tests/auto/qserialport/tst_qserialport.cpp @@ -132,6 +132,8 @@ private slots: void readWriteWithDifferentBaudRate_data(); void readWriteWithDifferentBaudRate(); + void bindingsAndProperties(); + protected slots: void handleBytesWrittenAndExitLoopSlot(qint64 bytesWritten); void handleBytesWrittenAndExitLoopSlot2(qint64 bytesWritten); @@ -1284,5 +1286,149 @@ void tst_QSerialPort::readWriteWithDifferentBaudRate() } } +void tst_QSerialPort::bindingsAndProperties() +{ + QSerialPort sp; + + // -- data bits + + QProperty<QSerialPort::DataBits> dbProp(QSerialPort::DataBits::Data6); + QCOMPARE(dbProp.value(), QSerialPort::DataBits::Data6); + + sp.bindableDataBits().setBinding(Qt::makePropertyBinding(dbProp)); + QCOMPARE(sp.dataBits(), QSerialPort::DataBits::Data6); + + const QSignalSpy dataBitsChangedSpy(&sp, &QSerialPort::dataBitsChanged); + + dbProp = QSerialPort::DataBits::Data5; + QCOMPARE(sp.dataBits(), QSerialPort::DataBits::Data5); + QCOMPARE(dataBitsChangedSpy.count(), 1); + QCOMPARE(dataBitsChangedSpy.at(0).value(0).toInt(), QSerialPort::DataBits::Data5); + + dbProp.setBinding(sp.bindableDataBits().makeBinding()); + sp.setDataBits(QSerialPort::DataBits::Data8); + QCOMPARE(dbProp.value(), QSerialPort::DataBits::Data8); + + dbProp.setBinding([&] { return sp.dataBits(); }); + sp.setDataBits(QSerialPort::DataBits::Data7); + QCOMPARE(dbProp.value(), QSerialPort::DataBits::Data7); + + // -- parity + + QProperty<QSerialPort::Parity> parityProp(QSerialPort::Parity::SpaceParity); + QCOMPARE(parityProp.value(), QSerialPort::Parity::SpaceParity); + + sp.bindableParity().setBinding(Qt::makePropertyBinding(parityProp)); + QCOMPARE(sp.parity(), QSerialPort::Parity::SpaceParity); + + const QSignalSpy parityChangedSpy(&sp, &QSerialPort::parityChanged); + + parityProp = QSerialPort::Parity::EvenParity; + QCOMPARE(sp.parity(), QSerialPort::Parity::EvenParity); + QCOMPARE(parityChangedSpy.count(), 1); + QCOMPARE(parityChangedSpy.at(0).value(0).toInt(), QSerialPort::Parity::EvenParity); + + parityProp.setBinding(sp.bindableParity().makeBinding()); + sp.setParity(QSerialPort::Parity::NoParity); + QCOMPARE(parityProp.value(), QSerialPort::Parity::NoParity); + + parityProp.setBinding([&] { return sp.parity(); }); + sp.setParity(QSerialPort::Parity::OddParity); + QCOMPARE(parityProp.value(), QSerialPort::Parity::OddParity); + + // -- stop bits + + QProperty<QSerialPort::StopBits> sbProp(QSerialPort::StopBits::OneAndHalfStop); + QCOMPARE(sbProp.value(), QSerialPort::StopBits::OneAndHalfStop); + + sp.bindableStopBits().setBinding(Qt::makePropertyBinding(sbProp)); + QCOMPARE(sp.stopBits(), QSerialPort::StopBits::OneAndHalfStop); + + const QSignalSpy stopBitsChangedSpy(&sp, &QSerialPort::stopBitsChanged); + + sbProp = QSerialPort::StopBits::OneStop; + QCOMPARE(sp.stopBits(), QSerialPort::StopBits::OneStop); + QCOMPARE(stopBitsChangedSpy.count(), 1); + QCOMPARE(stopBitsChangedSpy.at(0).value(0).toInt(), QSerialPort::StopBits::OneStop); + + sbProp.setBinding(sp.bindableStopBits().makeBinding()); + sp.setStopBits(QSerialPort::StopBits::TwoStop); + QCOMPARE(sbProp.value(), QSerialPort::StopBits::TwoStop); + + sbProp.setBinding([&] { return sp.stopBits(); }); + sp.setStopBits(QSerialPort::StopBits::OneAndHalfStop); + QCOMPARE(sbProp.value(), QSerialPort::StopBits::OneAndHalfStop); + + // -- flow control + + QProperty<QSerialPort::FlowControl> fcProp(QSerialPort::FlowControl::HardwareControl); + QCOMPARE(fcProp.value(), QSerialPort::FlowControl::HardwareControl); + + sp.bindableFlowControl().setBinding(Qt::makePropertyBinding(fcProp)); + QCOMPARE(sp.flowControl(), QSerialPort::FlowControl::HardwareControl); + + const QSignalSpy flowControlChangedSpy(&sp, &QSerialPort::flowControlChanged); + + fcProp = QSerialPort::FlowControl::NoFlowControl; + QCOMPARE(sp.flowControl(), QSerialPort::FlowControl::NoFlowControl); + QCOMPARE(flowControlChangedSpy.count(), 1); + QCOMPARE(flowControlChangedSpy.at(0).value(0).toInt(), QSerialPort::FlowControl::NoFlowControl); + + fcProp.setBinding(sp.bindableFlowControl().makeBinding()); + sp.setFlowControl(QSerialPort::FlowControl::SoftwareControl); + QCOMPARE(fcProp.value(), QSerialPort::FlowControl::SoftwareControl); + + fcProp.setBinding([&] { return sp.flowControl(); }); + sp.setFlowControl(QSerialPort::FlowControl::NoFlowControl); + QCOMPARE(fcProp.value(), QSerialPort::FlowControl::NoFlowControl); + + // -- error + + QProperty<QSerialPort::SerialPortError> errorProp(QSerialPort::SerialPortError::PermissionError); + QCOMPARE(errorProp.value(), QSerialPort::SerialPortError::PermissionError); + + sp.bindableError().setBinding(Qt::makePropertyBinding(errorProp)); + QCOMPARE(sp.error(), QSerialPort::SerialPortError::NoError); + + const QSignalSpy errorChangedSpy(&sp, &QSerialPort::errorOccurred); + + // this shall not change the error, we do not have a public setter + errorProp = QSerialPort::SerialPortError::DeviceNotFoundError; + QCOMPARE(sp.error(), QSerialPort::SerialPortError::NoError); + QCOMPARE(errorChangedSpy.count(), 0); + + errorProp.setBinding(sp.bindableError().makeBinding()); + sp.clearError(); + QCOMPARE(errorProp.value(), QSerialPort::SerialPortError::NoError); + QCOMPARE(errorChangedSpy.count(), 1); + QCOMPARE(errorChangedSpy.at(0).value(0).toInt(), QSerialPort::SerialPortError::NoError); + + sp.setPortName(m_receiverPortName); + sp.open(QIODevice::ReadOnly); + + // -- break enabled + + QProperty<bool> beProp(false); + QCOMPARE(beProp.value(), false); + + sp.bindableIsBreakEnabled().setBinding(Qt::makePropertyBinding(beProp)); + QCOMPARE(sp.isBreakEnabled(), false); + + const QSignalSpy breakEnabledChangedSpy(&sp, &QSerialPort::breakEnabledChanged); + + beProp = true; + QCOMPARE(sp.isBreakEnabled(), true); + QCOMPARE(breakEnabledChangedSpy.count(), 1); + QCOMPARE(breakEnabledChangedSpy.at(0).value(0).toBool(), true); + + beProp.setBinding(sp.bindableIsBreakEnabled().makeBinding()); + sp.setBreakEnabled(false); + QCOMPARE(beProp.value(), false); + + beProp.setBinding([&] { return sp.isBreakEnabled(); }); + sp.setBreakEnabled(true); + QCOMPARE(beProp.value(), true); +} + QTEST_MAIN(tst_QSerialPort) #include "tst_qserialport.moc" |