From d18c57c5bc59b6fd37ef2d3cbeeb235ebf75bb1f Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 27 Feb 2017 11:21:40 +0100 Subject: [PATCH] feat(ui/views/App/Settings/SettingsNetwork): supports video port --- linphone-desktop/resources.qrc | 2 + .../src/components/settings/SettingsModel.cpp | 43 +++++++--- .../src/components/settings/SettingsModel.hpp | 7 ++ .../modules/Common/Form/Fields/PortField.qml | 76 ++++++++++++++++++ linphone-desktop/ui/modules/Common/qmldir | 1 + .../ui/scripts/Utils/port-tools.js | 15 ++++ linphone-desktop/ui/scripts/Utils/utils.js | 8 ++ .../ui/views/App/Settings/SettingsNetwork.qml | 80 ++++++++++--------- 8 files changed, 182 insertions(+), 50 deletions(-) create mode 100644 linphone-desktop/ui/modules/Common/Form/Fields/PortField.qml create mode 100644 linphone-desktop/ui/scripts/Utils/port-tools.js diff --git a/linphone-desktop/resources.qrc b/linphone-desktop/resources.qrc index c11aa5908..07c9622f4 100644 --- a/linphone-desktop/resources.qrc +++ b/linphone-desktop/resources.qrc @@ -187,6 +187,7 @@ ui/modules/Common/Form/ComboBox.qml ui/modules/Common/Form/DroppableTextArea.qml ui/modules/Common/Form/Fields/NumericField.qml + ui/modules/Common/Form/Fields/PortField.qml ui/modules/Common/Form/Fields/TextAreaField.qml ui/modules/Common/Form/Fields/TextField.qml ui/modules/Common/Form/+linux/SearchBox.qml @@ -301,6 +302,7 @@ ui/modules/Linphone/Timeline.qml ui/scripts/LinphoneUtils/linphone-utils.js ui/scripts/LinphoneUtils/qmldir + ui/scripts/Utils/port-tools.js ui/scripts/Utils/qmldir ui/scripts/Utils/uri-tools.js ui/scripts/Utils/utils.js diff --git a/linphone-desktop/src/components/settings/SettingsModel.cpp b/linphone-desktop/src/components/settings/SettingsModel.cpp index 616db664a..f357bdb9d 100644 --- a/linphone-desktop/src/components/settings/SettingsModel.cpp +++ b/linphone-desktop/src/components/settings/SettingsModel.cpp @@ -42,22 +42,23 @@ SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { // Network. // ============================================================================= -bool SettingsModel::getUseRfc2833ForDtmfs () const { - return CoreManager::getInstance()->getCore()->getUseRfc2833ForDtmf(); +QList SettingsModel::getVideoPortRange () const { + int a, b; + CoreManager::getInstance()->getCore()->getVideoPortRange(a, b); + return QList() << a << b; } -void SettingsModel::setUseRfc2833ForDtmfs (bool status) { +void SettingsModel::setVideoPortRange (const QList &range) { shared_ptr core = CoreManager::getInstance()->getCore(); + int a = range[0]; + int b = range[1]; - if (status) { - core->setUseInfoForDtmf(false); - core->setUseRfc2833ForDtmf(true); - } else { - core->setUseRfc2833ForDtmf(false); - core->setUseInfoForDtmf(true); - } + if (b == -1) + core->setVideoPort(a); + else + core->setVideoPortRange(a, b); - emit dtmfsProtocolChanged(); + emit videoPortRangeChanged(a, b); } // ----------------------------------------------------------------------------- @@ -82,6 +83,26 @@ void SettingsModel::setUseSipInfoForDtmfs (bool status) { // ----------------------------------------------------------------------------- +bool SettingsModel::getUseRfc2833ForDtmfs () const { + return CoreManager::getInstance()->getCore()->getUseRfc2833ForDtmf(); +} + +void SettingsModel::setUseRfc2833ForDtmfs (bool status) { + shared_ptr core = CoreManager::getInstance()->getCore(); + + if (status) { + core->setUseInfoForDtmf(false); + core->setUseRfc2833ForDtmf(true); + } else { + core->setUseRfc2833ForDtmf(false); + core->setUseInfoForDtmf(true); + } + + emit dtmfsProtocolChanged(); +} + +// ----------------------------------------------------------------------------- + bool SettingsModel::getIpv6Enabled () const { return CoreManager::getInstance()->getCore()->ipv6Enabled(); } diff --git a/linphone-desktop/src/components/settings/SettingsModel.hpp b/linphone-desktop/src/components/settings/SettingsModel.hpp index 89247a279..d3ccfa018 100644 --- a/linphone-desktop/src/components/settings/SettingsModel.hpp +++ b/linphone-desktop/src/components/settings/SettingsModel.hpp @@ -31,6 +31,8 @@ class SettingsModel : public QObject { Q_OBJECT; + Q_PROPERTY(QList videoPortRange READ getVideoPortRange WRITE setVideoPortRange NOTIFY videoPortRangeChanged); + Q_PROPERTY(bool useSipInfoForDtmfs READ getUseSipInfoForDtmfs WRITE setUseSipInfoForDtmfs NOTIFY dtmfsProtocolChanged); Q_PROPERTY(bool useRfc2833ForDtmfs READ getUseRfc2833ForDtmfs WRITE setUseRfc2833ForDtmfs NOTIFY dtmfsProtocolChanged); @@ -47,6 +49,9 @@ public: // Network. ------------------------------------------------------------------ + QList getVideoPortRange () const; + void setVideoPortRange (const QList &range); + bool getUseSipInfoForDtmfs () const; void setUseSipInfoForDtmfs (bool status); @@ -75,6 +80,8 @@ public: static const std::string UI_SECTION; signals: + void videoPortRangeChanged (int a, int b); + void dtmfsProtocolChanged (); void ipv6EnabledChanged (bool status); diff --git a/linphone-desktop/ui/modules/Common/Form/Fields/PortField.qml b/linphone-desktop/ui/modules/Common/Form/Fields/PortField.qml new file mode 100644 index 000000000..32711dbde --- /dev/null +++ b/linphone-desktop/ui/modules/Common/Form/Fields/PortField.qml @@ -0,0 +1,76 @@ +import QtQuick 2.7 + +import Utils 1.0 + +// ============================================================================= + +Item { + id: wrapper + + // --------------------------------------------------------------------------- + + property string text + property bool supportsRange: false + + // --------------------------------------------------------------------------- + + signal editingFinished (int portA, int portB) + + // --------------------------------------------------------------------------- + + function _extractPorts (text) { + var portA = +text.split(':')[0] + var portB = (function () { + var port = text.split(':')[1] + return port && port.length > 0 ? +port : -1 + })() + + if (portB < 0 || portA === portB) { + return [ portA, -1 ] + } + + if (portA < portB) { + return [ portA, portB ] + } + + return [ portB, portA ] + } + + function _computeText (range) { + return range[1] < 0 + ? range[0] + : range[0] + ':' + range[1] + } + + // --------------------------------------------------------------------------- + + implicitWidth: textField.width + implicitHeight: textField.height + + onTextChanged: textField.text = _computeText(_extractPorts(text)) + + // --------------------------------------------------------------------------- + + TextField { + id: textField + + property bool locked: false + + validator: RegExpValidator { + regExp: wrapper.supportsRange + ? Utils.PORT_RANGE_REGEX + : Utils.PORT_REGEX + } + + // Workaround to supports empty string. + Keys.onReturnPressed: editingFinished() + onActiveFocusChanged: !activeFocus && !text.length && editingFinished() + + onEditingFinished: { + var range = _extractPorts(textField.text) + + wrapper.text = textField.text = _computeText(range) + wrapper.editingFinished(range[0], range[1]) + } + } +} diff --git a/linphone-desktop/ui/modules/Common/qmldir b/linphone-desktop/ui/modules/Common/qmldir index e291216af..945b20c42 100644 --- a/linphone-desktop/ui/modules/Common/qmldir +++ b/linphone-desktop/ui/modules/Common/qmldir @@ -34,6 +34,7 @@ TextButtonA 1.0 Form/Buttons/TextButtonA.qml TextButtonB 1.0 Form/Buttons/TextButtonB.qml NumericField 1.0 Form/Fields/NumericField.qml +PortField 1.0 Form/Fields/PortField.qml TextAreaField 1.0 Form/Fields/TextAreaField.qml TextField 1.0 Form/Fields/TextField.qml diff --git a/linphone-desktop/ui/scripts/Utils/port-tools.js b/linphone-desktop/ui/scripts/Utils/port-tools.js new file mode 100644 index 000000000..ed7019a5a --- /dev/null +++ b/linphone-desktop/ui/scripts/Utils/port-tools.js @@ -0,0 +1,15 @@ +// ============================================================================= +// Library to deal with Ports. +// ============================================================================= + +.pragma library + +// ----------------------------------------------------------------------------- + +var PORT = '([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])' +var PORT_RANGE = PORT + '(?::' + PORT + ')?' + +// ----------------------------------------------------------------------------- + +var PORT_REGEX = new RegExp('^' + PORT + '$') +var PORT_RANGE_REGEX = new RegExp('^' + PORT_RANGE + '$') diff --git a/linphone-desktop/ui/scripts/Utils/utils.js b/linphone-desktop/ui/scripts/Utils/utils.js index d79a05e60..0aae4811b 100644 --- a/linphone-desktop/ui/scripts/Utils/utils.js +++ b/linphone-desktop/ui/scripts/Utils/utils.js @@ -6,8 +6,16 @@ .import QtQuick 2.0 as QtQuick +.import 'port-tools.js' as PortTools .import 'uri-tools.js' as UriTools +// ============================================================================= +// Constants. +// ============================================================================= + +var PORT_REGEX = PortTools.PORT_REGEX +var PORT_RANGE_REGEX = PortTools.PORT_RANGE_REGEX + // ============================================================================= // QML helpers. // ============================================================================= diff --git a/linphone-desktop/ui/views/App/Settings/SettingsNetwork.qml b/linphone-desktop/ui/views/App/Settings/SettingsNetwork.qml index 4f3f1e230..a15857cb9 100644 --- a/linphone-desktop/ui/views/App/Settings/SettingsNetwork.qml +++ b/linphone-desktop/ui/views/App/Settings/SettingsNetwork.qml @@ -12,41 +12,6 @@ TabContainer { spacing: SettingsWindowStyle.forms.spacing width: parent.width - // ------------------------------------------------------------------------- - // Transport. - // ------------------------------------------------------------------------- - - Form { - title: qsTr('transportTitle') - width: parent.width - - FormLine { - FormGroup { - label: qsTr('sendDtmfsLabel') - - ExclusiveButtons { - selectedButton: Number(!SettingsModel.useSipInfoForDtmfs) - texts: [ - 'SIP INFO', - 'RFC 2833' - ] - - onClicked: SettingsModel.useSipInfoForDtmfs = !button - } - } - - FormGroup { - label: qsTr('allowIpV6Label') - - Switch { - checked: SettingsModel.ipv6Enabled - - onClicked: SettingsModel.ipv6Enabled = !checked - } - } - } - } - // ------------------------------------------------------------------------- // Network protocol and ports. // ------------------------------------------------------------------------- @@ -73,10 +38,12 @@ TabContainer { FormGroup { label: qsTr('sipUdpPortLabel') - NumericField { - minValue: 0 - maxValue: 65535 - readOnly: randomSipUdpPort.checked || !enableSipUdpPort.checked + PortField { + //readOnly: randomSipUdpPort.checked || !enableSipUdpPort.checked + supportsRange: true + text: SettingsModel.videoPortRange.join(':') + + onEditingFinished: SettingsModel.videoPortRange = [ portA, portB ] } } @@ -184,6 +151,41 @@ TabContainer { } } + // ------------------------------------------------------------------------- + // Transport. + // ------------------------------------------------------------------------- + + Form { + title: qsTr('transportTitle') + width: parent.width + + FormLine { + FormGroup { + label: qsTr('sendDtmfsLabel') + + ExclusiveButtons { + selectedButton: Number(!SettingsModel.useSipInfoForDtmfs) + texts: [ + 'SIP INFO', + 'RFC 2833' + ] + + onClicked: SettingsModel.useSipInfoForDtmfs = !button + } + } + + FormGroup { + label: qsTr('allowIpV6Label') + + Switch { + checked: SettingsModel.ipv6Enabled + + onClicked: SettingsModel.ipv6Enabled = !checked + } + } + } + } + // ------------------------------------------------------------------------- // DSCP fields. // -------------------------------------------------------------------------