Display secure icon on contacts if it has the capability.

Deactivate video if no codecs are selected.
Link to licence in about.
Fix loosing ICE configuration.
Fix click shortcut on the first item on smartsearch bar.
Add separated and editable prefix phone number in assistant.
This commit is contained in:
Julien Wadel 2023-07-24 11:30:54 +02:00
parent 03e94e6fdb
commit 9f9b624abd
36 changed files with 264 additions and 106 deletions

View file

@ -4,6 +4,7 @@ set(APPLICATION_NAME Linphone)
set(APPLICATION_URL "https://www.linphone.org")
set(APPLICATION_VENDOR "Belledonne Communications")
set(APPLICATION_LICENCE "GNU General Public License V3")
set(APPLICATION_LICENCE_URL "https://www.gnu.org/licenses/gpl-3.0.html")
set(APPLICATION_START_LICENCE "2010")
set(EXECUTABLE_NAME linphone)

View file

@ -15,7 +15,7 @@
<entry name="reg_identity" overwrite="true">sip:?@sip.linphone.org</entry>
<entry name="reg_proxy" overwrite="true">&lt;sip:sip.linphone.org;transport=tls&gt;</entry>
<entry name="reg_sendregister" overwrite="true">1</entry>
<entry name="nat_policy_ref" overwrite="true">nat_policy_default_values</entry>
<entry name="nat_policy_ref" overwrite="true">default_nat_policy_values</entry>
<entry name="realm" overwrite="true">sip.linphone.org</entry>
<entry name="contact_parameters" overwrite="true">message-expires=2419200</entry>
<entry name="conference_factory_uri" overwrite="true">sip:conference-factory@sip.linphone.org</entry>
@ -24,7 +24,7 @@
<entry name="rtp_bundle" overwrite="true">1</entry>
<entry name="lime_server_url" overwrite="true">https://lime.linphone.org/lime-server/lime-server.php</entry>
</section>
<section name="nat_policy_default_values">
<section name="default_nat_policy_values">
<entry name="stun_server" overwrite="true">stun.linphone.org</entry>
<entry name="protocols" overwrite="true">stun,ice</entry>
</section>

View file

@ -15,7 +15,7 @@
<entry name="reg_identity" overwrite="true">sip:?@sip.linphone.org</entry>
<entry name="reg_proxy" overwrite="true">&lt;sip:sip.linphone.org;transport=tls&gt;</entry>
<entry name="reg_sendregister" overwrite="true">1</entry>
<entry name="nat_policy_ref" overwrite="true">nat_policy_default_values</entry>
<entry name="nat_policy_ref" overwrite="true">default_nat_policy_values</entry>
<entry name="realm" overwrite="true">sip.linphone.org</entry>
<entry name="contact_parameters" overwrite="true">message-expires=2419200</entry>
<entry name="conference_factory_uri" overwrite="true">sip:conference-factory@sip.linphone.org</entry>
@ -24,7 +24,7 @@
<entry name="rtp_bundle" overwrite="true">1</entry>
<entry name="lime_server_url" overwrite="true">https://lime.linphone.org/lime-server/lime-server.php</entry>
</section>
<section name="nat_policy_default_values">
<section name="default_nat_policy_values">
<entry name="stun_server" overwrite="true">stun.linphone.org</entry>
<entry name="protocols" overwrite="true">stun,ice</entry>
</section>

View file

@ -22,7 +22,7 @@
<entry name="audio_video_conference_factory_uri" overwrite="true"></entry>
<entry name="lime_server_url" overwrite="true"></entry>
</section>
<section name="nat_policy_default_values">
<section name="default_nat_policy_values">
<entry name="stun_server" overwrite="true"></entry>
<entry name="protocols" overwrite="true"></entry>
</section>

View file

@ -456,6 +456,13 @@ void App::initContentApp () {
#else
mEngine->rootContext()->setContextProperty("applicationLicence", "");
#endif
#ifdef APPLICATION_LICENCE_URL
mEngine->rootContext()->setContextProperty("applicationLicenceUrl", APPLICATION_LICENCE_URL);
#else
mEngine->rootContext()->setContextProperty("applicationLicenceUrl", "");
#endif
#ifdef COPYRIGHT_RANGE_DATE
mEngine->rootContext()->setContextProperty("copyrightRangeDate", COPYRIGHT_RANGE_DATE);
#else

View file

@ -29,6 +29,7 @@ class ProxyAbstractObject : public QAbstractListModel{
Q_OBJECT
public:
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
Q_PROPERTY(int length READ getCount NOTIFY countChanged)
ProxyAbstractObject(QObject * parent = nullptr) : QAbstractListModel(parent){
connect(this, &ProxyAbstractObject::rowsInserted, this, &ProxyAbstractObject::countChanged);

View file

@ -53,11 +53,17 @@ public:
private:
void createAccount (const shared_ptr<linphone::AccountCreator> &creator) {
shared_ptr<linphone::ProxyConfig> proxyConfig = creator->createProxyConfig();
auto account = CoreManager::getInstance()->getCore()->getAccountByIdkey(proxyConfig->getIdkey());
auto account = creator->createAccountInCore();
if(account){
AccountSettingsModel *accountSettingsModel = CoreManager::getInstance()->getAccountSettingsModel();
CoreManager::getInstance()->addingAccount(account->getParams());
CoreManager::getInstance()->getAccountSettingsModel()->setDefaultAccount(account);
auto accountParams = account->getParams()->clone();
auto natPolicy = accountParams->getNatPolicy();
if(natPolicy)
accountParams->setNatPolicy(natPolicy->clone());// Be sure to have a 'ref' entry on a nat_policy. When using default values, the 'ref' entry is lost where it should be pointing to default. We get one by cloning the policy.
if (accountSettingsModel->addOrUpdateAccount(account, accountParams)) {
accountSettingsModel->setDefaultAccount(account);
}
}
}
@ -133,7 +139,7 @@ private:
QVariantMap description = doc.toVariant().toMap();
creator->setToken(description.value("token").toString().toStdString());
// it will automatically use the account creation token.
if (!mAssistant->mCountryCode.isEmpty()) {
if (mAssistant->mUsePhoneNumber) {
emit mAssistant->createStatusChanged("Recovering account");
creator->recoverAccount();
}else{
@ -144,7 +150,6 @@ private:
QTimer::singleShot(2000, [creator](){
creator->requestAccountCreationTokenUsingRequestToken();
});
}
void onActivateAccount (
@ -269,7 +274,8 @@ void AssistantModel::login () {
setIsProcessing(true);
if(mAccountCreator->getUsername().empty())
mAccountCreator->setUsername(mAccountCreator->getPhoneNumber());
if (!mCountryCode.isEmpty()) {// Recovering account from phone
if (mUsePhoneNumber) {
emit createStatusChanged("Requesting validation url");
mAccountCreator->requestAccountCreationRequestToken();
return;
}
@ -555,12 +561,29 @@ QString AssistantModel::getCountryCode () const {
void AssistantModel::setCountryCode (const QString &countryCode) {
mCountryCode = countryCode;
mAccountCreator->setPhoneNumber(Utils::appStringToCoreString(mPhoneNumber), Utils::appStringToCoreString(mCountryCode));
emit countryCodeChanged(countryCode);
emit computedPhoneNumberChanged();
}
// -----------------------------------------------------------------------------
bool AssistantModel::getUsePhoneNumber() const{
return mUsePhoneNumber;
}
void AssistantModel::setUsePhoneNumber(bool use) {
if(mUsePhoneNumber != use){
mUsePhoneNumber = use;
emit usePhoneNumberChanged();
}
}
QString AssistantModel::getPhoneNumber () const {
return mPhoneNumber;
}
QString AssistantModel::getComputedPhoneNumber () const{
return Utils::coreStringToAppString(mAccountCreator->getPhoneNumber());
}
@ -588,8 +611,20 @@ void AssistantModel::setPhoneNumber (const QString &phoneNumber) {
default:
break;
}
mPhoneNumber = phoneNumber;
emit phoneNumberChanged(phoneNumber, error);
emit computedPhoneNumberChanged();
}
QString AssistantModel::getPhoneCountryCode() const {
return mPhoneCountryCode;
}
void AssistantModel::setPhoneCountryCode(const QString &code) {
if( mPhoneCountryCode != code) {
mPhoneCountryCode = code;
emit phoneCountryCodeChanged();
}
}
// -----------------------------------------------------------------------------

View file

@ -32,18 +32,23 @@ class OAuth2Model;
class AssistantModel : public QObject {
class Handlers;
Q_OBJECT;
Q_OBJECT
Q_PROPERTY(QString email READ getEmail WRITE setEmail NOTIFY emailChanged)
Q_PROPERTY(QString password READ getPassword WRITE setPassword NOTIFY passwordChanged)
Q_PROPERTY(QString countryCode READ getCountryCode WRITE setCountryCode NOTIFY countryCodeChanged)
Q_PROPERTY(QString phoneNumber READ getPhoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged)
Q_PROPERTY(QString phoneCountryCode READ getPhoneCountryCode WRITE setPhoneCountryCode NOTIFY phoneCountryCodeChanged)
Q_PROPERTY(QString computedPhoneNumber READ getComputedPhoneNumber NOTIFY computedPhoneNumberChanged)
Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY usernameChanged)
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(QString activationCode READ getActivationCode WRITE setActivationCode NOTIFY activationCodeChanged)
Q_PROPERTY(QString configFilename READ getConfigFilename WRITE setConfigFilename NOTIFY configFilenameChanged)
Q_PROPERTY(bool isReadingQRCode READ getIsReadingQRCode WRITE setIsReadingQRCode NOTIFY isReadingQRCodeChanged)
Q_PROPERTY(bool isProcessing READ getIsProcessing WRITE setIsProcessing NOTIFY isProcessingChanged)
Q_PROPERTY(bool usePhoneNumber READ getUsePhoneNumber WRITE setUsePhoneNumber NOTIFY usePhoneNumberChanged)
Q_PROPERTY(QString email READ getEmail WRITE setEmail NOTIFY emailChanged);
Q_PROPERTY(QString password READ getPassword WRITE setPassword NOTIFY passwordChanged);
Q_PROPERTY(QString countryCode READ getCountryCode WRITE setCountryCode NOTIFY countryCodeChanged);
Q_PROPERTY(QString phoneNumber READ getPhoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged);
Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY usernameChanged);
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged);
Q_PROPERTY(QString activationCode READ getActivationCode WRITE setActivationCode NOTIFY activationCodeChanged);
Q_PROPERTY(QString configFilename READ getConfigFilename WRITE setConfigFilename NOTIFY configFilenameChanged);
Q_PROPERTY(bool isReadingQRCode READ getIsReadingQRCode WRITE setIsReadingQRCode NOTIFY isReadingQRCodeChanged);
Q_PROPERTY(bool isProcessing READ getIsProcessing WRITE setIsProcessing NOTIFY isProcessingChanged);
public:
AssistantModel (QObject *parent = Q_NULLPTR);
@ -78,7 +83,10 @@ signals:
void emailChanged (const QString &email, const QString &error);
void passwordChanged (const QString &password, const QString &error);
void countryCodeChanged (const QString &countryCode);
void usePhoneNumberChanged();
void phoneNumberChanged (const QString &phoneNumber, const QString &error);
void phoneCountryCodeChanged();
void computedPhoneNumberChanged();
void usernameChanged (const QString &username, const QString &error);
void displayNameChanged (const QString &displayName, const QString &error);
void activationCodeChanged (const QString &activationCode);
@ -115,9 +123,16 @@ private:
QString getCountryCode () const;
void setCountryCode (const QString &countryCode);
bool getUsePhoneNumber() const;
void setUsePhoneNumber(bool use);
QString getPhoneNumber () const;
QString getComputedPhoneNumber () const;
void setPhoneNumber (const QString &phoneNumber);
QString getPhoneCountryCode () const;
void setPhoneCountryCode (const QString &code);
QString getUsername () const;
void setUsername (const QString &username);
@ -142,8 +157,11 @@ private:
QString mCountryCode;
QString mConfigFilename;
QString mToken;
QString mPhoneCountryCode;
QString mPhoneNumber;
bool mIsReadingQRCode;
bool mIsProcessing;
bool mUsePhoneNumber = false;
std::shared_ptr<linphone::AccountCreator> mAccountCreator;
std::shared_ptr<Handlers> mHandlers;

View file

@ -20,6 +20,7 @@
#include "app/paths/Paths.hpp"
#include "components/core/CoreManager.hpp"
#include "components/settings/SettingsModel.hpp"
#include "utils/Utils.hpp"
#include "AbstractCodecsModel.hpp"
@ -45,6 +46,8 @@ void AbstractCodecsModel::enableCodec (int id, bool status) {
shared_ptr<linphone::PayloadType> codec = getCodecFromMap(map);
if (codec) {
codec->enable(status);
if(codec->getType() == PAYLOAD_VIDEO)
emit CoreManager::getInstance()->getSettingsModel()->haveAtLeastOneVideoCodecChanged();
map["enabled"] = codec->enabled();
emit dataChanged(index(id, 0), index(id, 0));
}

View file

@ -55,6 +55,7 @@ SettingsModel::SettingsModel (QObject *parent) : QObject(parent) {
mConfig = coreManager->getCore()->getConfig();
connect(this, &SettingsModel::dontAskAgainInfoEncryptionChanged, this, &SettingsModel::haveDontAskAgainChoicesChanged);
connect(this, &SettingsModel::haveAtLeastOneVideoCodecChanged, this, &SettingsModel::videoAvailableChanged);
QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callCreated,
this, &SettingsModel::handleCallCreated);
@ -678,6 +679,19 @@ void SettingsModel::setShowVideoCodecs (bool status) {
emit showVideoCodecsChanged(status);
}
bool SettingsModel::getVideoAvailable() const{
return getVideoEnabled() && haveAtLeastOneVideoCodec();
}
bool SettingsModel::haveAtLeastOneVideoCodec() const{
auto codecs = CoreManager::getInstance()->getCore()->getVideoPayloadTypes();
for (auto &codec : codecs){
if(codec->enabled() && codec->isUsable())
return true;
}
return false;
}
// =============================================================================
void SettingsModel::updateCameraMode(){
auto mode = mConfig->getString("video", "main_display_mode", "OccupyAllSpace");

View file

@ -100,6 +100,7 @@ class SettingsModel : public QObject {
Q_PROPERTY(QVariantMap videoDefinition READ getVideoDefinition WRITE setVideoDefinition NOTIFY videoDefinitionChanged)
Q_PROPERTY(bool videoEnabled READ getVideoEnabled WRITE setVideoEnabled NOTIFY videoEnabledChanged)
Q_PROPERTY(bool videoAvailable READ getVideoAvailable NOTIFY videoAvailableChanged)
Q_PROPERTY(bool showVideoCodecs READ getShowVideoCodecs WRITE setShowVideoCodecs NOTIFY showVideoCodecsChanged)
@ -387,8 +388,10 @@ public:
Q_INVOKABLE QVariantMap getCurrentPreviewVideoDefinition () const;
void setVideoDefinition (const QVariantMap &definition);
bool getVideoEnabled() const;
bool getVideoEnabled() const; // Enabled from settings
void setVideoEnabled(const bool& enable);
bool getVideoAvailable() const; // Enabled and have enough codecs.
bool haveAtLeastOneVideoCodec() const;
bool getShowVideoCodecs () const;
void setShowVideoCodecs (bool status);
@ -742,6 +745,7 @@ signals:
// Video. --------------------------------------------------------------------
void videoEnabledChanged();
void videoAvailableChanged();
void videoDevicesChanged (const QStringList &devices);
void videoDeviceChanged (const QString &device);
@ -758,6 +762,8 @@ signals:
void callCameraModeChanged();
void videoConferenceLayoutChanged();
void haveAtLeastOneVideoCodecChanged();
// Chat & calls. -------------------------------------------------------------
void autoAnswerStatusChanged (bool status);

View file

@ -253,7 +253,7 @@ const QList<QPair<QLocale::Country, QString>> TelephoneNumbersModel::mCountryCod
// -----------------------------------------------------------------------------
TelephoneNumbersModel::TelephoneNumbersModel (QObject *parent) : QAbstractListModel(parent) {}
TelephoneNumbersModel::TelephoneNumbersModel (QObject *parent) : ProxyAbstractObject(parent) {}
int TelephoneNumbersModel::rowCount (const QModelIndex &) const {
return mCountryCodes.count();
@ -275,13 +275,24 @@ QVariant TelephoneNumbersModel::data (const QModelIndex &index, int role) const
if (role == Qt::DisplayRole) {
return countryCode.second;
}else if(role == Qt::DisplayRole+1)
return QStringLiteral("%1 (+%2)")
.arg(Utils::getCountryName(countryCode.first))
.arg(countryCode.second);
return QStringLiteral("%1")
.arg(Utils::getCountryName(countryCode.first));
return QVariant();
}
QVariant TelephoneNumbersModel::getAt(int row){
if (row < 0 || row >= mCountryCodes.count())
return QVariant();
QVariantMap result;
auto roles = roleNames();
const QPair<QLocale::Country, QString> &countryCode = mCountryCodes[row];
result[roles[Qt::DisplayRole]] = countryCode.second;
result[roles[Qt::DisplayRole+1]] = QStringLiteral("%1")
.arg(Utils::getCountryName(countryCode.first));
return result;
}
int TelephoneNumbersModel::getDefaultIndex () const {
QLocale::Country country = QLocale().country();
const auto it = find_if(

View file

@ -21,12 +21,11 @@
#ifndef TELEPHONE_NUMBERS_MODEL_H_
#define TELEPHONE_NUMBERS_MODEL_H_
#include <QAbstractListModel>
#include <QLocale>
#include "app/proxyModel/ProxyAbstractObject.hpp"
// =============================================================================
class TelephoneNumbersModel : public QAbstractListModel {
class TelephoneNumbersModel : public ProxyAbstractObject {
Q_OBJECT
Q_PROPERTY(int defaultIndex READ getDefaultIndex CONSTANT)
@ -38,7 +37,8 @@ public:
QHash<int, QByteArray> roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE QVariant getAt(int);
private:
int getDefaultIndex () const;

View file

@ -26,6 +26,7 @@
#cmakedefine APPLICATION_VENDOR "${APPLICATION_VENDOR}"
#cmakedefine APPLICATION_URL "${APPLICATION_URL}"
#cmakedefine APPLICATION_LICENCE "${APPLICATION_LICENCE}"
#cmakedefine APPLICATION_LICENCE_URL "${APPLICATION_LICENCE_URL}"
#cmakedefine APPLICATION_SEMVER "${APPLICATION_SEMVER}"
#cmakedefine COPYRIGHT_RANGE_DATE "${COPYRIGHT_RANGE_DATE}"
#cmakedefine ENABLE_UPDATE_CHECK 1

View file

@ -66,9 +66,8 @@ function getSelectedEntryText () {
// With a `QAbstractListModel`, `text` is empty. QML bug?
var model = comboBox.model
if (model.data) {
var item = model.data(model.index(comboBox.currentIndex, 0))
var textRole = comboBox.textRole
return textRole.length > 0 ? item[textRole] : item
var item = model.data(model.index(comboBox.currentIndex, 0), comboBox.textRole)
return item ? item : ''
}
return ''

View file

@ -83,7 +83,7 @@ function getParams (call) {
if (status === CallModel.CallStatusIncoming) {
var optActions = []
if (Linphone.SettingsModel.videoEnabled) {
if (Linphone.SettingsModel.videoAvailable) {
optActions.push({
handler: call.acceptWithVideo,
name: qsTr('acceptVideoCall')

View file

@ -198,7 +198,7 @@ DialogPlus {
RowLayout {
spacing: MultimediaParametersDialogStyle.column.entry.spacing
width: parent.width
visible: SettingsModel.videoEnabled
visible: SettingsModel.videoAvailable
Icon {
icon: MultimediaParametersDialogStyle.column.entry.camera.icon

View file

@ -129,7 +129,7 @@ Rectangle{
: IncallMenuStyle.settingsIcons.activeSpeakerIcon
: IncallMenuStyle.settingsIcons.audioOnlyIcon)
, nextPage:layoutMenu
, visible: mainItem.callModel && mainItem.callModel.isConference && SettingsModel.videoEnabled},
, visible: mainItem.callModel && mainItem.callModel.isConference && SettingsModel.videoAvailable},
{ titleIndex: 2
, icon: IncallMenuStyle.settingsIcons.participantsIcon

View file

@ -62,7 +62,7 @@ Notification {
isCustom: true
backgroundRadius: 90
colorSet: NotificationReceivedCallStyle.acceptVideoCall
visible: SettingsModel.videoEnabled && notification.call.getRemoteVideoEnabled()
visible: SettingsModel.videoAvailable && notification.call.getRemoteVideoEnabled()
onClicked: notification._close(notification.call.acceptWithVideo)
}

View file

@ -67,7 +67,7 @@ SearchBox {
searchBox.launchVideoCall(entry.sipAddress)
searchBox.closeMenu()
},
visible: SettingsModel.videoEnabled && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
visible: SettingsModel.videoAvailable && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
}, {
colorSet: SipAddressesViewStyle.call,
secure: 0,

View file

@ -107,6 +107,10 @@ ScrollableListView {
haveEncryption:false,
securityLevel:1
})
MouseArea {
anchors.fill: parent
onClicked: sipAddressesView.entryClicked(contact.entry, -1)
}
}
ActionBar {

View file

@ -263,7 +263,7 @@ function _indexFinder (array, cb, context) {
var length = array.length
for (var i = 0; i < length; i++) {
if (cb(array[i], i, array)) {
if (cb( (array.getAt ? array.getAt(i) : array[i]), i, array)) {
return i
}
}

View file

@ -75,7 +75,7 @@ DialogPlus {
handler: function (entry) {
launchVideoCall(entry.sipAddress)
},
visible: SettingsModel.videoEnabled && SettingsModel.showStartVideoCallButton,
visible: SettingsModel.videoAvailable && SettingsModel.showStartVideoCallButton,
handlerSipAddress: function(sipAddress) {
launchVideoCall(sipAddress)
}

View file

@ -65,7 +65,7 @@ function handleStatusChanged (status, isFullscreen) {
}
function handleVideoRequested (call) {
if (window.virtualWindowVisible || !Linphone.SettingsModel.videoEnabled) {
if (window.virtualWindowVisible || !Linphone.SettingsModel.videoAvailable) {
call.rejectVideoRequest()
return
}

View file

@ -549,7 +549,7 @@ Rectangle {
colorSet: callModel && callModel.cameraEnabled ? IncallStyle.buttons.cameraOn : IncallStyle.buttons.cameraOff
updating: callModel.videoEnabled && callModel.updating && !mainItem.layoutChanging
enabled: callModel && !callModel.pausedByUser
visible: SettingsModel.videoEnabled
visible: SettingsModel.videoAvailable
property bool _activateCamera: false
onClicked: if(callModel && !mainItem.layoutChanging){
if( callModel.isConference){// Only deactivate camera in conference.

View file

@ -16,7 +16,7 @@ AbstractStartingCall {
isCustom: true
backgroundRadius: 90
colorSet: CallStyle.buttons.acceptVideoCall
visible: SettingsModel.videoEnabled
visible: SettingsModel.videoAvailable
onClicked: call.acceptWithVideo()
}

View file

@ -20,7 +20,7 @@ Rectangle {
color: WaitingRoomStyle.backgroundColor.color
property ConferenceInfoModel conferenceInfoModel
property CallModel callModel // Store the call for processing calling.
property bool previewLoaderEnabled: callModel ? callModel.videoEnabled : SettingsModel.videoEnabled
property bool previewLoaderEnabled: callModel ? callModel.videoEnabled : SettingsModel.videoAvailable
property var _sipAddressObserver: callModel ? SipAddressesModel.getSipAddressObserver(callModel.fullPeerAddress, callModel.fullLocalAddress) : undefined
property bool isEnded: callModel && callModel.status == CallModel.CallStatusEnded
@ -157,7 +157,7 @@ Rectangle {
: mainItem.callModel
? mainItem.callModel.conferenceModel
: null
deactivateCamera: !SettingsModel.videoEnabled || !mainItem.previewLoaderEnabled || mainItem.isEnded
deactivateCamera: !SettingsModel.videoAvailable || !mainItem.previewLoaderEnabled || mainItem.isEnded
/*
image: mainItem._sipAddressObserver && mainItem._sipAddressObserver.contact && mainItem._sipAddressObserver.contact.vcard.avatar
@ -307,7 +307,7 @@ Rectangle {
ActionSwitch {
id: camera
property bool cameraEnabled: true
visible: !mainItem.callModel && SettingsModel.videoEnabled
visible: !mainItem.callModel && SettingsModel.videoAvailable
isCustom: true
backgroundRadius: 90
colorSet: cameraEnabled ? WaitingRoomStyle.buttons.cameraOn : WaitingRoomStyle.buttons.cameraOff
@ -362,7 +362,7 @@ Rectangle {
anchors.right: optionsButton.left
anchors.rightMargin: 10
visible: !mainItem.callModel && SettingsModel.videoEnabled
visible: !mainItem.callModel && SettingsModel.videoAvailable
toggled: layoutMenu.visible
isCustom: true
backgroundRadius: width/2

View file

@ -22,13 +22,13 @@ AssistantAbstractView {
Column {
anchors.centerIn: parent
spacing: ActivateAppSipAccountWithPhoneNumberStyle.spacing
width: parent.width
width: parent.width - 10
Text {
color: ActivateAppSipAccountWithPhoneNumberStyle.activationSteps.colorModel.color
font.pointSize: ActivateAppSipAccountWithPhoneNumberStyle.activationSteps.pointSize
horizontalAlignment: Text.AlignHCenter
text: qsTr('activationSteps').replace('%1', assistantModel.phoneNumber)
text: qsTr('activationSteps').replace('%1', assistantModel.computedPhoneNumber)
width: parent.width
wrapMode: Text.WordWrap
}

View file

@ -1,9 +1,13 @@
import QtQuick 2.7
import QtQuick.Layouts 1.0
import Common 1.0
import Linphone 1.0
import Common.Styles 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
AssistantAbstractView {
@ -12,13 +16,6 @@ AssistantAbstractView {
property alias usernameError: username.error
property alias phoneNumberError: phoneNumber.error
function setCountryCode (index) {
if(index>=0){
var model = country.model
assistantModel.countryCode = model.data(model.index(index, 0),"countryCode")
}
}
title: qsTr('createAppSipAccountTitle').replace('%1', Qt.application.name.toUpperCase())
mainAction: requestBlock.execute
@ -45,39 +42,57 @@ AssistantAbstractView {
currentIndex: model.defaultIndex
model: TelephoneNumbersModel {}
textRole: 'countryName'
function setCode(code){
currentIndex = Utils.findIndex(model, function (phoneModel) {
return phoneModel.countryCode === code
})
assistantModel.setCountryCode(currentIndex)
}
onActivated: {
view.setCountryCode(index)
var text = phoneNumber.text
if (text.length > 0) {
assistantModel.phoneNumber = text
}
assistantModel.setCountryCode(index)
}
}
}
}
FormLine {
FormGroup {
label: qsTr('phoneNumberLabel')
TextField {
id: phoneNumber
inputMethodHints: Qt.ImhDialableCharactersOnly
onTextChanged: assistantModel.phoneNumber = text
}
}
}
}
FormLine {
FormGroup {
label: qsTr('phoneNumberLabel')
RowLayout{
spacing: 5
TextField {
id: countryCode
Layout.fillHeight: true
Layout.preferredWidth: 50
inputMethodHints: Qt.ImhDialableCharactersOnly
text: "+"+assistantModel.countryCode
cursorPosition:1
onCursorPositionChanged: if(cursorPosition == 0) cursorPosition = 1
onTextEdited: {
country.setCode(text.substring(1))
}
}
TextField {
id: phoneNumber
Layout.fillHeight: true
Layout.fillWidth: true
inputMethodHints: Qt.ImhDialableCharactersOnly
text: assistantModel.phoneNumber
onTextChanged: if( assistantModel.phoneNumber != text) assistantModel.phoneNumber = text
}
}
}
}
FormLine {
FormGroup {
label: qsTr('usernameLabel')
TextField {
id: username
placeholderText: phoneNumber.text
placeholderText: assistantModel.computedPhoneNumber
onTextChanged: assistantModel.username = text
}
}
@ -111,8 +126,15 @@ AssistantAbstractView {
id: assistantModel
configFilename: 'create-app-sip-account.rc'
function setCountryCode (index) {
if(index>=0){
var model = country.model
assistantModel.countryCode = model.data(model.index(index, 0),"countryCode")
}
}
Component.onCompleted: view.setCountryCode(country.model.defaultIndex)
Component.onCompleted: setCountryCode(country.model.defaultIndex)
onPhoneNumberChanged: phoneNumberError = error
onUsernameChanged: usernameError = error

View file

@ -12,7 +12,7 @@ import Common.Styles 1.0
AssistantAbstractView {
id: view
readonly property bool usePhoneNumber: SettingsModel.assistantSupportsPhoneNumbers && !checkBox.checked
readonly property alias usePhoneNumber: assistantModel.usePhoneNumber
mainAction: requestBlock.execute
mainActionEnabled: {
@ -94,26 +94,34 @@ AssistantAbstractView {
id: assistantModel
function setCountryCode (index) {
var model = telephoneNumbersModel
assistantModel.countryCode = index !== -1 ? model.data(model.index(index, 0),"countryCode") || '' : ''
if( index >= 0) {
var model = telephoneNumbersModel
//assistantModel.countryCode = index !== -1 ? model.data(model.index(index, 0),"countryCode") || '' : ''
assistantModel.countryCode = model.data(model.index(index, 0),"countryCode")
}
}
configFilename: 'use-app-sip-account.rc'
countryCode: setCountryCode(view.usePhoneNumber ? telephoneNumbersModel.defaultIndex : -1)
usePhoneNumber: SettingsModel.assistantSupportsPhoneNumbers && !checkBox.checked
//countryCode: setCountryCode(view.usePhoneNumber ? telephoneNumbersModel.defaultIndex : -1)
onPasswordChanged: {
if (!view.usePhoneNumber) {
if (!usePhoneNumber) {
loader.item.passwordError = error
}
}
onPhoneNumberChanged: {
if (view.usePhoneNumber) {
if (usePhoneNumber) {
loader.item.phoneNumberError = error
}
}
onCreateStatusChanged: {
requestBlock.setText(error)
if (error.length) {
return
}
}
onLoginStatusChanged: {
requestBlock.setText(error)
if (!error.length) {
@ -144,6 +152,7 @@ AssistantAbstractView {
})
}
}
Component.onCompleted: setCountryCode(telephoneNumbersModel.defaultIndex)
}
TelephoneNumbersModel {

View file

@ -1,5 +1,8 @@
import Common 1.0
import Linphone 1.0
import QtQuick.Layouts 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
@ -31,13 +34,15 @@ Form {
currentIndex: model.defaultIndex
model: telephoneNumbersModel
textRole: 'countryName'
function setCode(code){
currentIndex = Utils.findIndex(model, function (phoneModel) {
return phoneModel.countryCode === code
})
assistantModel.setCountryCode(currentIndex)
}
onActivated: {
assistantModel.setCountryCode(index)
var text = phoneNumber.text
if (text.length > 0) {
assistantModel.phoneNumber = text
}
}
}
}
@ -46,13 +51,30 @@ Form {
FormLine {
FormGroup {
label: qsTr('phoneNumberLabel')
TextField {
id: phoneNumber
RowLayout{
spacing: 5
TextField {
id: countryCode
Layout.fillHeight: true
Layout.preferredWidth: 50
inputMethodHints: Qt.ImhDialableCharactersOnly
text: "+"+assistantModel.countryCode
cursorPosition:1
onCursorPositionChanged: if(cursorPosition == 0) cursorPosition = 1
onTextEdited: {
country.setCode(text.substring(1))
}
}
TextField {
id: phoneNumber
Layout.fillHeight: true
Layout.fillWidth: true
inputMethodHints: Qt.ImhDialableCharactersOnly
text: assistantModel.phoneNumber
onTextChanged: if( assistantModel.phoneNumber != text) assistantModel.phoneNumber = text
inputMethodHints: Qt.ImhDialableCharactersOnly
text: assistantModel.phoneNumber
onTextChanged: if( assistantModel.phoneNumber != text) assistantModel.phoneNumber = text
}
}
}
}

View file

@ -160,7 +160,7 @@ ColumnLayout {
backgroundRadius: 90
colorSet: ContactEditStyle.videoCall
visible: SettingsModel.videoEnabled && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
visible: SettingsModel.videoAvailable && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
onClicked: sipAddressesMenu.open(sipAddressesMenu.startVideoCall)
}

View file

@ -142,7 +142,7 @@ ColumnLayout {
isCustom: true
backgroundRadius: 90
colorSet: ContactsStyle.videoCall
visible: SettingsModel.videoEnabled && SettingsModel.outgoingCallsEnabled && SettingsModel.getShowStartVideoCallButton()
visible: SettingsModel.videoAvailable && SettingsModel.outgoingCallsEnabled && SettingsModel.getShowStartVideoCallButton()
onClicked: actions.itemAt(0).open()
}
@ -168,7 +168,7 @@ ColumnLayout {
isCustom: true
backgroundRadius: 90
colorSet: SettingsModel.getShowStartChatButton() ? ContactsStyle.chat : ContactsStyle.history
visible: SettingsModel.secureChatEnabled
visible: SettingsModel.secureChatEnabled && $modelData && $modelData.hasCapability(LinphoneEnums.FriendCapabilityLimeX3Dh)
enabled: AccountSettingsModel.conferenceUri != ''
Icon{
icon:'secure_level_1'

View file

@ -262,7 +262,7 @@ ColumnLayout {
backgroundRadius: 1000
colorSet: ConversationStyle.bar.actions.videoCall
visible: SettingsModel.videoEnabled && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton && !conversation.haveMoreThanOneParticipants
visible: SettingsModel.videoAvailable && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton && !conversation.haveMoreThanOneParticipants
onClicked: CallsListModel.launchVideoCall(chatRoomModel.participants.addressesToString)
}

View file

@ -103,6 +103,11 @@ DialogPlus {
width: parent.width
horizontalAlignment: Text.AlignHCenter
MouseArea{
anchors.fill: parent
visible: applicationLicenceUrl
onClicked: Qt.openUrlExternally(applicationLicenceUrl)
}
}
Text {
elide: Text.ElideRight

View file

@ -94,7 +94,7 @@ ColumnLayout {
isCustom: true
backgroundRadius: 90
colorSet: HistoryViewStyle.videoCall
visible: peerAddress && SettingsModel.videoEnabled && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
visible: peerAddress && SettingsModel.videoAvailable && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
onClicked: CallsListModel.launchVideoCall(historyView.peerAddress)
}