blind+ attended transfer #LINQT-1345

This commit is contained in:
Gaelle Braud 2024-10-17 16:40:41 +02:00
parent 72e4d1c81e
commit 155b7af32e
39 changed files with 596 additions and 510 deletions

View file

@ -51,7 +51,6 @@ void CallHistoryProxy::removeEntriesWithFilter() {
bool CallHistoryProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
bool show = (mFilterText.isEmpty() || mFilterText == "*");
auto sortProxy = dynamic_cast<SortFilterList *>(sourceModel());
if (!show) {
QRegularExpression search(QRegularExpression::escape(mFilterText),

View file

@ -304,6 +304,13 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
if (linAddr) mCallModel->transferTo(linAddr);
});
});
mCallModelConnection->makeConnectToCore(&CallCore::lTransferCallToAnother, [this](QString uri) {
mCallModelConnection->invokeToModel([this, uri]() {
auto linCall = ToolModel::interpretUri(uri);
if (linCall) mCallModel->transferToAnother(linCall);
});
});
mCallModelConnection->makeConnectToModel(
&CallModel::transferStateChanged,
[this](const std::shared_ptr<linphone::Call> &call, linphone::Call::State state) {

View file

@ -286,6 +286,7 @@ signals:
void lSetVideoEnabled(bool enabled);
void lSetPaused(bool paused);
void lTransferCall(QString address);
void lTransferCallToAnother(QString uri);
void lStartRecording();
void lStopRecording();
void lCheckAuthenticationTokenSelected(const QString &token);

View file

@ -64,8 +64,9 @@ public:
beginInsertRows(QModelIndex(), row, row);
mList << item;
endInsertRows();
auto lastIndex = index(mList.size() - 1, 0);
emit dataChanged(lastIndex, lastIndex);
// Snippet in case of not refreshing beside begin/end
// auto lastIndex = index(mList.size() - 1, 0);
// emit dataChanged(lastIndex, lastIndex);
}
virtual void add(QList<T> items) {
int count = items.size();
@ -75,9 +76,10 @@ public:
beginInsertRows(QModelIndex(), currentCount, newCount - 1);
mList << items;
endInsertRows();
QModelIndex firstIndex = currentCount > 0 ? index(currentCount - 1, 0) : index(0, 0);
auto lastIndex = index(newCount - 1, 0);
emit dataChanged(firstIndex, lastIndex);
// Snippet in case of not refreshing beside begin/end
// QModelIndex firstIndex = currentCount > 0 ? index(currentCount - 1, 0) : index(0, 0);
// auto lastIndex = index(newCount - 1, 0);
// emit dataChanged(firstIndex, lastIndex);
}
}
@ -86,7 +88,8 @@ public:
beginInsertRows(QModelIndex(), 0, 0);
mList.prepend(item);
endInsertRows();
emit dataChanged(index(0), index(0));
// Snippet in case of not refreshing beside begin/end
// emit dataChanged(index(0), index(0));
}
virtual void prepend(QList<T> items) {
@ -98,7 +101,8 @@ public:
items << mList;
mList = items;
endInsertRows();
emit dataChanged(index(0), index(items.size() - 1));
// Snippet in case of not refreshing beside begin/end
// emit dataChanged(index(0), index(items.size() - 1));
}
}
@ -113,7 +117,8 @@ public:
for (int i = 0; i < count; ++i)
mList.takeAt(row);
endRemoveRows();
emit dataChanged(index(row), index(limit));
// Snippet in case of not refreshing beside begin/end (TODO: check crashs, empty list?)
// emit dataChanged(index(row), index(limit));
return true;
}
@ -126,16 +131,6 @@ public:
mList = newData;
endResetModel();
}
/*
void displayMore() {
int oldCount = rowCount();
int newCount = getDisplayCount(oldCount + mList.size(), mMaxDisplayItems + mDisplayItemsStep);
if (newCount != oldCount) {
setMaxDisplayItems(newCount);
beginInsertRows(QModelIndex(), oldCount, newCount - 1);
endInsertRows();
}
}*/
protected:
QList<T> mList;

View file

@ -106,6 +106,14 @@ void CallModel::transferTo(const std::shared_ptr<linphone::Address> &address) {
.arg(Utils::coreStringToAppString(address->asStringUriOnly()));
}
void CallModel::transferToAnother(const std::shared_ptr<linphone::Call> &call) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
if (mMonitor->transferToAnother(call) == -1)
qWarning() << log()
.arg(QStringLiteral("Unable to transfer: `%1`."))
.arg(Utils::coreStringToAppString(call->getRemoteAddress()->asStringUriOnly()));
}
void CallModel::terminateAllCalls() {
auto status = mMonitor->getCore()->terminateAllCalls();
}

View file

@ -61,6 +61,7 @@ public:
void setPaused(bool paused);
void transferTo(const std::shared_ptr<linphone::Address> &address);
void transferToAnother(const std::shared_ptr<linphone::Call> &call);
void terminateAllCalls();
float getMicrophoneVolumeGain() const;

View file

@ -48,6 +48,12 @@ std::shared_ptr<linphone::Address> ToolModel::interpretUrl(const QString &addres
return interpretedAddress;
}
std::shared_ptr<linphone::Call> ToolModel::interpretUri(const QString &uri) {
auto remoteAddress = ToolModel::interpretUrl(uri);
if (remoteAddress) return CoreModel::getInstance()->getCore()->getCallByRemoteAddress2(remoteAddress);
else return nullptr;
}
std::shared_ptr<linphone::FriendPhoneNumber> ToolModel::makeLinphoneNumber(const QString &label,
const QString &number) {
auto linphoneNumber = std::make_shared<linphone::FriendPhoneNumber>(nullptr);

View file

@ -35,6 +35,7 @@ public:
~ToolModel();
static std::shared_ptr<linphone::Address> interpretUrl(const QString &address);
static std::shared_ptr<linphone::Call> interpretUri(const QString &uri);
static std::shared_ptr<linphone::FriendPhoneNumber> makeLinphoneNumber(const QString &label, const QString &number);
static std::shared_ptr<linphone::AudioDevice> findAudioDevice(const QString &id,
linphone::AudioDevice::Capabilities capability);

View file

@ -7,6 +7,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
view/Control/Button/ComboBox.qml
view/Control/Button/HelpIconLabelButton.qml
view/Control/Button/IconLabelButton.qml
view/Control/Button/MenuButton.qml
view/Control/Button/MediumButton.qml
view/Control/Button/SmallButton.qml
view/Control/Button/CountryIndicatorCombobox.qml
@ -39,6 +40,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
view/Control/Display/Sticker.qml
view/Control/Display/Text.qml
view/Control/Display/ToolTip.qml
view/Control/Display/Call/CallListView.qml
view/Control/Display/Contact/Avatar.qml
view/Control/Display/Contact/Contact.qml
view/Control/Display/Contact/ContactListView.qml

View file

@ -1,4 +1,4 @@
import QtQuick 2.15
import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import Linphone

View file

@ -1,5 +1,5 @@
import QtQuick 2.7
import QtQuick.Controls.Basic 2.2 as Control
import QtQuick
import QtQuick.Controls.Basic as Control
import QtQuick.Effects
import QtQuick.Layouts
import Linphone

View file

@ -0,0 +1,18 @@
import QtQuick
import QtQuick.Controls.Basic as Control
import QtQuick.Effects
import QtQuick.Layouts
import Linphone
Button {
id: mainItem
background: Item{}
icon.width: 32 * DefaultStyle.dp
icon.height: 32 * DefaultStyle.dp
textColor: down || checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main
contentImageColor: down || checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main
textSize: 14 * DefaultStyle.dp
textWeight: 400 * DefaultStyle.dp
textHAlignment: Text.AlignLeft
spacing: 5 * DefaultStyle.dp
}

View file

@ -1,5 +1,5 @@
import QtQuick 2.7
import QtQuick.Controls.Basic 2.2 as Control
import QtQuick
import QtQuick.Controls.Basic as Control
import QtQuick.Effects
import QtQuick.Layouts
import Linphone

View file

@ -1,5 +1,5 @@
import QtQuick 2.7
import QtQuick.Controls.Basic 2.2 as Control
import QtQuick
import QtQuick.Controls.Basic as Control
import QtQuick.Effects
import QtQuick.Layouts
import Linphone

View file

@ -1,4 +1,4 @@
import QtQuick 2.15
import QtQuick
import QtQuick.Layouts
import Linphone

View file

@ -0,0 +1,107 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Effects
import Linphone
import QtQml
import UtilsCpp 1.0
ListView {
id: mainItem
model: CallProxy {
id: callProxy
}
implicitHeight: contentHeight
spacing: 15 * DefaultStyle.dp
clip: true
onCountChanged: forceLayout()
signal transferCallToAnotherRequested(CallGui dest)
property bool isTransferList: false
delegate: Item {
id: callDelegate
width: mainItem.width
height: 45 * DefaultStyle.dp
RowLayout {
id: delegateContent
anchors.fill: parent
spacing: 0
Avatar {
id: delegateAvatar
_address: modelData.core.remoteAddress
Layout.preferredWidth: 45 * DefaultStyle.dp
Layout.preferredHeight: 45 * DefaultStyle.dp
}
Text {
id: delegateName
property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress)
text: modelData.core.isConference
? modelData.core.conference.core.subject
: remoteNameObj ? remoteNameObj.value : ""
Layout.leftMargin: 8 * DefaultStyle.dp
}
Item {
Layout.fillHeight: true
Layout.fillWidth: true
}
Text {
id: callStateText
property string type: modelData.core.isConference ? qsTr('Réunion') : qsTr('Appel')
Layout.rightMargin: 2 * DefaultStyle.dp
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? type + qsTr(" en pause")
: type + qsTr(" en cours")
}
Button {
id: transferButton
Layout.preferredWidth: 24 * DefaultStyle.dp
Layout.preferredHeight: 24 * DefaultStyle.dp
visible: mainItem.isTransferList && callProxy?.currentCall.core.remoteAddress !== modelData.core.remoteAddress
onClicked: {
mainItem.transferCallToAnotherRequested(modelData)
}
icon.source: AppIcons.transferCall
contentImageColor: down ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main
background: Item {}
}
PopupButton {
visible: !mainItem.isTransferList
Layout.preferredWidth: 24 * DefaultStyle.dp
Layout.preferredHeight: 24 * DefaultStyle.dp
Layout.rightMargin: 10 * DefaultStyle.dp
Layout.leftMargin: 14 * DefaultStyle.dp
popup.contentItem: ColumnLayout {
spacing: 0
MenuButton {
id: pausingButton
onClicked: modelData.core.lSetPaused(!modelData.core.paused)
KeyNavigation.up: endCallButton
KeyNavigation.down: endCallButton
Layout.fillWidth: true
Layout.preferredHeight: icon.height
icon.source: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? AppIcons.phone : AppIcons.pause
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? qsTr("Reprendre l'appel") : qsTr("Mettre en pause")
}
MenuButton {
id: endCallButton
onClicked: mainWindow.endCall(modelData)
KeyNavigation.up: pausingButton
KeyNavigation.down: pausingButton
icon.source: AppIcons.endCall
contentImageColor: DefaultStyle.danger_500main
textColor: DefaultStyle.danger_500main
text: qsTr("Terminer l'appel")
}
}
}
}
}
}

View file

@ -60,7 +60,7 @@ ListView {
signal contactDeletionRequested(FriendGui contact)
signal contactAddedToSelection(string address)
signal contactRemovedFromSelection(string address)
signal clicked()
signal contactClicked(FriendGui contact)
function selectContact(address) {
var index = magicSearchProxy.findFriendIndexByAddress(address)
@ -93,9 +93,12 @@ ListView {
}
}
onActiveFocusChanged: if(activeFocus && (!footerItem || !footerItem.activeFocus)) {
currentIndex = 0
}
// strange behaviour with this lines
// When a popup opens after clicking on a contact, the selected contact
// changes because we lose focus on the list
// onActiveFocusChanged: if(activeFocus && (!footerItem || !footerItem.activeFocus)) {
// currentIndex = 0
// }
model: MagicSearchProxy {
id: magicSearchProxy
@ -369,7 +372,7 @@ ListView {
mainItem.removeContactFromSelection(indexInSelection, 1)
}
}
mainItem.clicked()
mainItem.contactClicked(modelData)
}
}
}

View file

@ -1,5 +1,5 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick
import QtQuick.Layouts
import QtQuick.Effects
import Linphone

View file

@ -1,5 +1,5 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick
import QtQuick.Layouts
import Linphone
import UtilsCpp 1.0

View file

@ -1,5 +1,5 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick
import QtQuick.Layouts
import Linphone
import UtilsCpp 1.0

View file

@ -9,15 +9,17 @@ Popup {
modal: true
anchors.centerIn: parent
closePolicy: Control.Popup.NoAutoClose
rightPadding: 10 * DefaultStyle.dp
leftPadding: 10 * DefaultStyle.dp
topPadding: 10 * DefaultStyle.dp
bottomPadding: 10 * DefaultStyle.dp
leftPadding: title.length === 0 ? 10 * DefaultStyle.dp : 33 * DefaultStyle.dp
rightPadding: title.length === 0 ? 10 * DefaultStyle.dp : 33 * DefaultStyle.dp
topPadding: title.length === 0 ? 10 * DefaultStyle.dp : 37 * DefaultStyle.dp
bottomPadding: title.length === 0 ? 10 * DefaultStyle.dp : 37 * DefaultStyle.dp
underlineColor: DefaultStyle.main1_500_main
property int radius: 16 * DefaultStyle.dp
radius: title.length === 0 ? 16 * DefaultStyle.dp : 0
property string title
property string text
property string details
property string firstButtonText: firstButtonAccept ? qsTr("Oui") : qsTr("Annuler")
property string secondButtonText: secondButtonAccept ? qsTr("Confirmer") : qsTr("Non")
property alias content: contentLayout.data
property alias buttons: buttonsLayout.data
property alias firstButton: firstButtonId
@ -50,8 +52,9 @@ Popup {
Layout.fillWidth: true
visible: text.length != 0
text: mainItem.title
color: DefaultStyle.main1_500_main
font {
pixelSize: 16 * DefaultStyle.dp
pixelSize: 22 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
wrapMode: Text.Wrap
@ -102,18 +105,19 @@ Popup {
RowLayout {
id: buttonsLayout
Layout.alignment: Qt.AlignBottom | ( titleText.visible ? Qt.AlignRight : Qt.AlignHCenter)
spacing: 10 * DefaultStyle.dp
spacing: titleText.visible ? 20 * DefaultStyle.dp : 10 * DefaultStyle.dp
// Default buttons only visible if no other children
// have been set
Button {
id:firstButtonId
visible: mainItem.buttons.length === 2
text: qsTr("Oui")
text: mainItem.firstButtonText
leftPadding: 20 * DefaultStyle.dp
rightPadding: 20 * DefaultStyle.dp
topPadding: 11 * DefaultStyle.dp
bottomPadding: 11 * DefaultStyle.dp
inversedColors: !mainItem.firstButtonAccept
focus: !firstButtonAccept
onClicked: {
if(firstButtonAccept)
@ -128,7 +132,7 @@ Popup {
Button {
id: secondButtonId
visible: mainItem.buttons.length === 2
text: qsTr("Non")
text: mainItem.secondButtonText
leftPadding: 20 * DefaultStyle.dp
rightPadding: 20 * DefaultStyle.dp
topPadding: 11 * DefaultStyle.dp

View file

@ -1,4 +1,4 @@
import QtQuick 2.7
import QtQuick
import QtQuick.Effects
import Linphone

View file

@ -1,5 +1,5 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick
import QtQuick.Layouts
import Linphone
import UtilsCpp
// =============================================================================

View file

@ -1,4 +1,4 @@
import QtQuick 2.7
import QtQuick
import QtQuick.Effects
import Linphone

View file

@ -1,4 +1,4 @@
import QtQuick 2.7
import QtQuick
MouseArea{
id: mainItem

View file

@ -1,4 +1,4 @@
import QtQuick 2.15
import QtQuick
Item {
id: root

View file

@ -10,154 +10,194 @@ import SettingsCpp
FocusScope {
id: mainItem
property bool groupCallVisible
property bool displayCurrentCalls: false
property color searchBarColor: DefaultStyle.grey_100
property color searchBarBorderColor: "transparent"
property alias searchBar: searchBar
property FriendGui selectedContact
property NumericPadPopup numPadPopup
signal callButtonPressed(string address)
signal callSelectedContact()
signal groupCallCreationRequested()
signal transferCallToAnotherRequested(CallGui dest)
signal contactClicked(FriendGui contact)
clip: true
Control.Control {
id: listLayout
ColumnLayout {
anchors.fill: parent
background: Item {
anchors.fill: parent
}
contentItem: ColumnLayout {
anchors.fill: parent
spacing: 10 * DefaultStyle.dp
SearchBar {
id: searchBar
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.rightMargin: 39 * DefaultStyle.dp
Layout.maximumWidth: mainItem.width
focus: true
color: mainItem.searchBarColor
borderColor: mainItem.searchBarBorderColor
placeholderText: qsTr("Rechercher un contact")
numericPadPopup: mainItem.numPadPopup
KeyNavigation.down: grouCallButton
spacing: 22 * DefaultStyle.dp
ColumnLayout {
spacing: 18 * DefaultStyle.dp
Text {
text: qsTr("Appels en cours")
font {
pixelSize: 16 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
}
Flickable {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: 25 * DefaultStyle.dp
Layout.preferredHeight: callList.height
Layout.maximumHeight: mainItem.height/2
// Layout.fillHeight: true
visible: mainItem.displayCurrentCalls
contentHeight: callList.height
contentWidth: width
contentHeight: content.height
clip: true
Control.ScrollBar.vertical: ScrollBar {
active: true
interactive: true
policy: Control.ScrollBar.AsNeeded
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: 8 * DefaultStyle.dp
}
ColumnLayout {
id: content
spacing: 32 * DefaultStyle.dp
RoundedPane {
id: callList
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 39 * DefaultStyle.dp
Button {
id: grouCallButton
visible: mainItem.groupCallVisible && !SettingsCpp.disableMeetingsFeature
Layout.preferredWidth: 320 * DefaultStyle.dp
Layout.preferredHeight: 44 * DefaultStyle.dp
padding: 0
KeyNavigation.up: searchBar
KeyNavigation.down: contactList.count >0 ? contactList : searchList
onClicked: mainItem.groupCallCreationRequested()
background: Rectangle {
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.main2_100}
GradientStop { position: 1.0; color: DefaultStyle.grey_0}
}
anchors.fill: parent
radius: 50 * DefaultStyle.dp
contentItem: CallListView {
isTransferList: true
onTransferCallToAnotherRequested: (dest) => {
mainItem.transferCallToAnotherRequested(dest)
}
contentItem: RowLayout {
spacing: 16 * DefaultStyle.dp
Image {
source: AppIcons.groupCall
Layout.preferredWidth: 44 * DefaultStyle.dp
sourceSize.width: 44 * DefaultStyle.dp
fillMode: Image.PreserveAspectFit
}
}
}
}
Control.Control {
id: listLayout
Layout.fillWidth: true
Layout.fillHeight: true
background: Item {
anchors.fill: parent
}
contentItem: ColumnLayout {
// anchors.fill: parent
spacing: 10 * DefaultStyle.dp
SearchBar {
id: searchBar
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.rightMargin: 39 * DefaultStyle.dp
Layout.maximumWidth: mainItem.width
focus: true
color: mainItem.searchBarColor
borderColor: mainItem.searchBarBorderColor
placeholderText: qsTr("Rechercher un contact")
numericPadPopup: mainItem.numPadPopup
KeyNavigation.down: grouCallButton
}
Flickable {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: 25 * DefaultStyle.dp
contentWidth: width
contentHeight: content.height
clip: true
Control.ScrollBar.vertical: ScrollBar {
active: true
interactive: true
policy: Control.ScrollBar.AsNeeded
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: 8 * DefaultStyle.dp
}
ColumnLayout {
id: content
spacing: 32 * DefaultStyle.dp
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 39 * DefaultStyle.dp
Button {
id: grouCallButton
visible: mainItem.groupCallVisible && !SettingsCpp.disableMeetingsFeature
Layout.preferredWidth: 320 * DefaultStyle.dp
Layout.preferredHeight: 44 * DefaultStyle.dp
padding: 0
KeyNavigation.up: searchBar
KeyNavigation.down: contactList.count >0 ? contactList : searchList
onClicked: mainItem.groupCallCreationRequested()
background: Rectangle {
anchors.fill: parent
radius: 50 * DefaultStyle.dp
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.main2_100}
GradientStop { position: 1.0; color: DefaultStyle.grey_0}
}
}
contentItem: RowLayout {
spacing: 16 * DefaultStyle.dp
anchors.verticalCenter: parent.verticalCenter
Image {
source: AppIcons.groupCall
Layout.preferredWidth: 44 * DefaultStyle.dp
sourceSize.width: 44 * DefaultStyle.dp
fillMode: Image.PreserveAspectFit
}
Text {
text: "Appel de groupe"
color: DefaultStyle.grey_1000
font {
pixelSize: 16 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
underline: grouCallButton.shadowEnabled
}
}
Item {
Layout.fillWidth: true
}
Image {
source: AppIcons.rightArrow
Layout.preferredWidth: 24 * DefaultStyle.dp
Layout.preferredHeight: 24 * DefaultStyle.dp
}
}
}
ColumnLayout {
visible: contactList.contentHeight > 0
spacing: 18 * DefaultStyle.dp
Text {
text: "Appel de groupe"
color: DefaultStyle.grey_1000
text: qsTr("Contacts")
font {
pixelSize: 16 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
underline: grouCallButton.shadowEnabled
}
}
Item {
ContactListView{
id: contactList
Layout.fillWidth: true
}
Image {
source: AppIcons.rightArrow
Layout.preferredWidth: 24 * DefaultStyle.dp
Layout.preferredHeight: 24 * DefaultStyle.dp
Layout.preferredHeight: contentHeight
Control.ScrollBar.vertical.visible: false
contactMenuVisible: false
searchBarText: searchBar.text
onContactClicked: (contact) => {
mainItem.contactClicked(contact)
}
}
}
}
ColumnLayout {
visible: contactList.contentHeight > 0
Text {
text: qsTr("Contacts")
font {
pixelSize: 16 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
ColumnLayout {
spacing: 18 * DefaultStyle.dp
Text {
text: qsTr("Suggestions")
font {
pixelSize: 16 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
}
ContactListView{
id: searchList
contactMenuVisible: false
Layout.fillWidth: true
Layout.fillHeight: true
Control.ScrollBar.vertical.visible: false
Layout.preferredHeight: contentHeight
initialHeadersVisible: false
displayNameCapitalization: false
searchBarText: searchBar.text
sourceFlags: LinphoneEnums.MagicSearchSource.All
onContactClicked: (contact) => {
mainItem.contactClicked(contact)
}
}
}
ContactListView{
id: contactList
Layout.fillWidth: true
Layout.preferredHeight: contentHeight
Control.ScrollBar.vertical.visible: false
contactMenuVisible: false
searchBarText: searchBar.text
onSelectedContactChanged: mainItem.selectedContact = selectedContact
onClicked: mainItem.callSelectedContact()
}
}
ColumnLayout {
spacing: 18 * DefaultStyle.dp
Text {
text: qsTr("Suggestions")
font {
pixelSize: 16 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
}
ContactListView{
id: searchList
contactMenuVisible: false
Layout.fillWidth: true
Item {
Layout.fillHeight: true
Control.ScrollBar.vertical.visible: false
Layout.preferredHeight: contentHeight
initialHeadersVisible: false
displayNameCapitalization: false
searchBarText: searchBar.text
sourceFlags: LinphoneEnums.MagicSearchSource.All
onSelectedContactChanged: mainItem.selectedContact = selectedContact
onClicked: mainItem.callSelectedContact()
}
}
Item {
Layout.fillHeight: true
}
}
}
}

View file

@ -217,7 +217,7 @@ AbstractSettingsLayout {
}
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup(
mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer ") + (model.core.displayName.length > 0 ? model.core.displayName : qsTr("le compte")) + " ?",
qsTr("Vous pouvez vous reconnecter à tout moment en cliquant sur \"Ajouter un compte\".\nCependant toutes les informations stockées sur ce périphérique seront supprimées."),
function (confirmed) {
@ -335,7 +335,7 @@ AbstractSettingsLayout {
contentImageColor: DefaultStyle.main1_500_main
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup(
mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer ") + modelData.core.deviceName + " ?", "",
function (confirmed) {
if (confirmed) {

View file

@ -26,7 +26,7 @@ AbstractSettingsLayout {
visible: !isNew
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup(
mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer le carnet d'adresse CardDAV ?"),
"",
function (confirmed) {

View file

@ -26,7 +26,7 @@ AbstractSettingsLayout {
visible: !isNew
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup(
mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer l'annuaire LDAP ?"),
"",
function (confirmed) {

View file

@ -124,6 +124,7 @@ AbstractMainPage {
Component {
id: historyListTitle
FocusScope{
objectName: "historyListTitle"
width: parent.width
height: titleCallLayout.implicitHeight
RowLayout {
@ -427,6 +428,7 @@ AbstractMainPage {
Component {
id: newCallTitle
FocusScope{
objectName: "newCallTitle"
width: parent.width
height: parent.height
RowLayout {
@ -481,8 +483,9 @@ AbstractMainPage {
numPadPopup: numericPadPopup
groupCallVisible: true
searchBarColor: DefaultStyle.grey_100
//onSelectedContactChanged: mainWindow.startCallWithContact(selectedContact, false, callContactsList)
onCallSelectedContact: mainWindow.startCallWithContact(selectedContact, false, callContactsList)
onContactClicked: (contact) => {
mainWindow.startCallWithContact(contact, false, callContactsList)
}
onGroupCallCreationRequested: {
console.log("groupe call requetsed")
listStackView.push(groupCallItem)
@ -506,6 +509,7 @@ AbstractMainPage {
Component {
id: groupCallTitle
FocusScope{
objectName: "groupCallTitle"
width: parent.width
height: parent.height
RowLayout {
@ -577,6 +581,7 @@ AbstractMainPage {
Component {
id: groupCallItem
FocusScope{
objectName: "groupCallItem"
Control.StackView.onActivated: {
titleLoader.sourceComponent = groupCallTitle
addParticipantsLayout.forceActiveFocus()
@ -638,11 +643,12 @@ AbstractMainPage {
Component{
id: emptySelection
Item{}
Item{objectName: "emptySelection"}
}
Component {
id: contactDetailComp
FocusScope{
objectName: "contactDetailComp"
width: parent?.width
height: parent?.height
ContactLayout {

View file

@ -55,6 +55,8 @@ Control.Page {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignVCenter
elide: Text.ElideRight
maximumLineCount: 1
verticalAlignment: Text.AlignVCenter
color: DefaultStyle.main1_500_main
font {

View file

@ -61,7 +61,7 @@ AbstractMainPage {
function deleteContact(contact) {
if (!contact) return
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup(
mainWin.showConfirmationLambdaPopup("",
contact.core.displayName + qsTr("sera supprimé des contacts. Voulez-vous continuer ?"),
"",
function (confirmed) {

View file

@ -32,10 +32,13 @@ ApplicationWindow {
onClosed: closePopup(index)
text: requestDialog?.message
details: requestDialog?.details
firstButtonAccept: title.length === 0
secondButtonAccept: title.length !== 0
Component.onCompleted: if (details.length != 0) radius = 0
// For C++, requestDialog need to be call directly
onAccepted: requestDialog ? requestDialog.result(1) : callback(1)
onRejected: requestDialog ? requestDialog.result(0) : callback(0)
width: 278 * DefaultStyle.dp
width: title.length === 0 ? 278 * DefaultStyle.dp : 637 * DefaultStyle.dp
}
}
@ -166,7 +169,7 @@ ApplicationWindow {
if (parentItem == undefined) parentItem = mainWindow.contentItem
startCallPopup.parent = parentItem
if (contact) {
console.log("TRANSFER CALL TO", contact.core.displayName, "addresses count", contact.core.allAddresses.length, call)
console.log("[AbstractWindow] Transfer call to", contact.core.displayName, "addresses count", contact.core.allAddresses.length, call)
if (contact.core.allAddresses.length > 1) {
startCallPopup.contact = contact
startCallPopup.currentCall = call
@ -178,7 +181,7 @@ ApplicationWindow {
? ""
: contact.core.phoneNumbers[0].address
: contact.core.defaultAddress
if (addressToCall.length != 0) call.core.lTransferCall(contact.core.defaultAddress)
if (addressToCall.length != 0) call.core.lTransferCall(addressToCall)
}
}
}
@ -213,9 +216,9 @@ ApplicationWindow {
popup.closePopup.connect(removeFromPopupLayout)
}
function showConfirmationLambdaPopup(title,details,callback){
function showConfirmationLambdaPopup(title,text, details,callback){
console.log("Showing confirmation lambda popup")
var popup = confirmPopupComp.createObject(popupLayout, {"text": title, "details":details,"callback":callback})
var popup = confirmPopupComp.createObject(popupLayout, {"title": title, "text": text, "details":details,"callback":callback})
popup.index = popupLayout.popupList.length
popupLayout.popupList.push(popup)
popup.open()

View file

@ -44,14 +44,24 @@ AbstractWindow {
onTransferStateChanged: {
console.log("Transfer state:", transferState)
if (transferState === LinphoneEnums.CallState.Error) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Le transfert d'appel a échoué"), false, mainWindow)
}
else if (transferState === LinphoneEnums.CallState.Connected){
var mainWin = UtilsCpp.getMainWindow()
UtilsCpp.smartShowWindow(mainWin)
mainWin.transferCallSucceed()
if (mainWindow.transferState === LinphoneEnums.CallState.OutgoingInit) {
var callsWin = UtilsCpp.getCallsWindow()
if (!callsWin) return
callsWin.showLoadingPopup(qsTr("Transfert en cours, veuillez patienter"))
}
else if (mainWindow.transferState === LinphoneEnums.CallState.Error
|| mainWindow.transferState === LinphoneEnums.CallState.End
|| mainWindow.transferState === LinphoneEnums.CallState.Released
|| mainWindow.transferState === LinphoneEnums.CallState.Connected) {
var callsWin = UtilsCpp.getCallsWindow()
callsWin.closeLoadingPopup()
if (transferState === LinphoneEnums.CallState.Error) UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Le transfert d'appel a échoué"), false, mainWindow)
else if (transferState === LinphoneEnums.CallState.Connected){
var mainWin = UtilsCpp.getMainWindow()
UtilsCpp.smartShowWindow(mainWin)
mainWin.transferCallSucceed()
}
}
}
onClosing: (close) => {
DesktopToolsCpp.screenSaverStatus = true
@ -198,44 +208,6 @@ AbstractWindow {
call: mainWindow.call
modal: true
}
Popup {
id: waitingPopup
modal: true
closePolicy: Control.Popup.NoAutoClose
anchors.centerIn: parent
padding: 20 * DefaultStyle.dp
underlineColor: DefaultStyle.main1_500_main
radius: 15 * DefaultStyle.dp
width: 278 * DefaultStyle.dp
height: 115 * DefaultStyle.dp
Connections {
target: mainWindow
function onTransferStateChanged() {
if (mainWindow.transferState === LinphoneEnums.CallState.OutgoingInit) waitingPopup.open()
else if (mainWindow.transferState === LinphoneEnums.CallState.Error
|| mainWindow.transferState === LinphoneEnums.CallState.End
|| mainWindow.transferState === LinphoneEnums.CallState.Released
|| mainWindow.transferState === LinphoneEnums.CallState.Connected)
waitingPopup.close()
}
}
contentItem: ColumnLayout {
spacing: 0
BusyIndicator{
Layout.preferredWidth: 33 * DefaultStyle.dp
Layout.preferredHeight: 33 * DefaultStyle.dp
Layout.alignment: Qt.AlignHCenter
}
Text {
Layout.alignment: Qt.AlignHCenter
text: qsTr("Transfert en cours, veuillez patienter")
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400 * DefaultStyle.dp
}
}
}
}
Timer {
id: autoCloseZrtpToast
interval: 4000
@ -307,101 +279,137 @@ AbstractWindow {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: 10 * DefaultStyle.dp
ColumnLayout {
RowLayout {
spacing: 10 * DefaultStyle.dp
EffectImage {
id: callStatusIcon
Layout.preferredWidth: 30 * DefaultStyle.dp
Layout.preferredHeight: 30 * DefaultStyle.dp
// TODO : change with broadcast or meeting icon when available
imageSource: !mainWindow.call
? AppIcons.meeting
: (mainWindow.callState === LinphoneEnums.CallState.End
|| mainWindow.callState === LinphoneEnums.CallState.Released)
? AppIcons.endCall
: (mainWindow.callState === LinphoneEnums.CallState.Paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote)
? AppIcons.pause
: mainWindow.conference
? AppIcons.usersThree
: mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing
? AppIcons.arrowUpRight
: AppIcons.arrowDownLeft
colorizationColor: !mainWindow.call || mainWindow.call.core.paused || mainWindow.callState === LinphoneEnums.CallState.Paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote || mainWindow.callState === LinphoneEnums.CallState.End
|| mainWindow.callState === LinphoneEnums.CallState.Released || mainWindow.conference
? DefaultStyle.danger_500main
: mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing
? DefaultStyle.info_500_main
: DefaultStyle.success_500main
onColorizationColorChanged: {
callStatusIcon.active = !callStatusIcon.active
callStatusIcon.active = !callStatusIcon.active
}
}
Text {
id: callStatusText
property string remoteName: mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
? mainWindow.call.core.remoteName
: EnumsToStringCpp.dirToString(mainWindow.call.core.dir) + qsTr(" call")
text: (mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released)
? qsTr("Fin d'appel")
: mainWindow.call && (mainWindow.call.core.paused
|| (mainWindow.callState === LinphoneEnums.CallState.Paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote))
? (mainWindow.conference ? qsTr('Réunion mise ') : qsTr('Appel mis')) + qsTr(" en pause")
RowLayout {
spacing: 10 * DefaultStyle.dp
EffectImage {
id: callStatusIcon
Layout.preferredWidth: 30 * DefaultStyle.dp
Layout.preferredHeight: 30 * DefaultStyle.dp
// TODO : change with broadcast or meeting icon when available
imageSource: !mainWindow.call
? AppIcons.meeting
: (mainWindow.callState === LinphoneEnums.CallState.End
|| mainWindow.callState === LinphoneEnums.CallState.Released)
? AppIcons.endCall
: (mainWindow.callState === LinphoneEnums.CallState.Paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote)
? AppIcons.pause
: mainWindow.conference
? mainWindow.conference.core.subject
: remoteName
color: DefaultStyle.grey_0
font {
pixelSize: 22 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
}
Rectangle {
visible: mainWindow.call && (mainWindow.callState === LinphoneEnums.CallState.Connected
|| mainWindow.callState === LinphoneEnums.CallState.StreamsRunning)
Layout.preferredHeight: parent.height
Layout.preferredWidth: 2 * DefaultStyle.dp
color: DefaultStyle.grey_0
}
Text {
text: mainWindow.call ? UtilsCpp.formatElapsedTime(mainWindow.call.core.duration) : ""
color: DefaultStyle.grey_0
font {
pixelSize: 22 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
visible: mainWindow.callState === LinphoneEnums.CallState.Connected
|| mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
}
Text {
Layout.leftMargin: 14 * DefaultStyle.dp
id: conferenceDate
text: mainWindow.conferenceInfo ? mainWindow.conferenceInfo.core.getStartEndDateString() : ""
color: DefaultStyle.grey_0
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400 * DefaultStyle.dp
capitalization: Font.Capitalize
}
? AppIcons.usersThree
: mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing
? AppIcons.arrowUpRight
: AppIcons.arrowDownLeft
colorizationColor: !mainWindow.call || mainWindow.call.core.paused || mainWindow.callState === LinphoneEnums.CallState.Paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote || mainWindow.callState === LinphoneEnums.CallState.End
|| mainWindow.callState === LinphoneEnums.CallState.Released || mainWindow.conference
? DefaultStyle.danger_500main
: mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing
? DefaultStyle.info_500_main
: DefaultStyle.success_500main
onColorizationColorChanged: {
callStatusIcon.active = !callStatusIcon.active
callStatusIcon.active = !callStatusIcon.active
}
}
RowLayout {
spacing: 5 * DefaultStyle.dp
visible: mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
BusyIndicator {
visible: mainWindow.call && mainWindow.callState != LinphoneEnums.CallState.Connected && mainWindow.callState != LinphoneEnums.CallState.StreamsRunning
Layout.preferredWidth: 15 * DefaultStyle.dp
Layout.preferredHeight: 15 * DefaultStyle.dp
indicatorColor: DefaultStyle.grey_0
ColumnLayout {
spacing: 6 * DefaultStyle.dp
RowLayout {
spacing: 10 * DefaultStyle.dp
Text {
id: callStatusText
property string remoteName: mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
? mainWindow.call.core.remoteName
: EnumsToStringCpp.dirToString(mainWindow.call.core.dir) + qsTr(" call")
text: (mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released)
? qsTr("Fin d'appel")
: mainWindow.call && (mainWindow.call.core.paused
|| (mainWindow.callState === LinphoneEnums.CallState.Paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote))
? (mainWindow.conference ? qsTr('Réunion mise ') : qsTr('Appel mis')) + qsTr(" en pause")
: mainWindow.conference
? mainWindow.conference.core.subject
: remoteName
color: DefaultStyle.grey_0
font {
pixelSize: 22 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
}
Rectangle {
visible: mainWindow.call && (mainWindow.callState === LinphoneEnums.CallState.Connected
|| mainWindow.callState === LinphoneEnums.CallState.StreamsRunning)
Layout.fillHeight: true
Layout.topMargin: 10 * DefaultStyle.dp
Layout.bottomMargin: 2 * DefaultStyle.dp
Layout.preferredWidth: 2 * DefaultStyle.dp
color: DefaultStyle.grey_0
}
Text {
text: mainWindow.call ? UtilsCpp.formatElapsedTime(mainWindow.call.core.duration) : ""
color: DefaultStyle.grey_0
font {
pixelSize: 22 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
visible: mainWindow.callState === LinphoneEnums.CallState.Connected
|| mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
}
Text {
Layout.leftMargin: 14 * DefaultStyle.dp
id: conferenceDate
text: mainWindow.conferenceInfo ? mainWindow.conferenceInfo.core.getStartEndDateString() : ""
color: DefaultStyle.grey_0
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400 * DefaultStyle.dp
capitalization: Font.Capitalize
}
}
}
EffectImage {
Layout.preferredWidth: 15 * DefaultStyle.dp
Layout.preferredHeight: 15 * DefaultStyle.dp
colorizationColor: mainWindow.call
RowLayout {
spacing: 5 * DefaultStyle.dp
visible: mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
BusyIndicator {
visible: mainWindow.call && mainWindow.callState != LinphoneEnums.CallState.Connected && mainWindow.callState != LinphoneEnums.CallState.StreamsRunning
Layout.preferredWidth: 15 * DefaultStyle.dp
Layout.preferredHeight: 15 * DefaultStyle.dp
indicatorColor: DefaultStyle.grey_0
}
EffectImage {
Layout.preferredWidth: 15 * DefaultStyle.dp
Layout.preferredHeight: 15 * DefaultStyle.dp
colorizationColor: mainWindow.call
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
? DefaultStyle.info_500_main
: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
? DefaultStyle.warning_600
: DefaultStyle.info_500_main
: DefaultStyle.grey_0
: "transparent"
visible: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
imageSource: mainWindow.call
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
? AppIcons.lockSimple
: mainWindow.call && mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
? AppIcons.warningCircle
: AppIcons.lockKey
: AppIcons.lockSimpleOpen
: ""
}
Text {
text: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
? qsTr("Appel chiffré de point à point")
: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
? qsTr("Vérification nécessaire")
: qsTr("Appel chiffré de bout en bout")
: qsTr("Appel non chiffré")
: qsTr("En attente de chiffrement")
color: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
? DefaultStyle.info_500_main
: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
@ -409,56 +417,27 @@ AbstractWindow {
? DefaultStyle.warning_600
: DefaultStyle.info_500_main
: DefaultStyle.grey_0
: "transparent"
visible: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
imageSource: mainWindow.call
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
? AppIcons.lockSimple
: mainWindow.call && mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
? AppIcons.warningCircle
: AppIcons.lockKey
: AppIcons.lockSimpleOpen
: ""
}
Text {
text: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
? qsTr("Appel chiffré de point à point")
: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
? qsTr("Vérification nécessaire")
: qsTr("Appel chiffré de bout en bout")
: qsTr("Appel non chiffré")
: qsTr("En attente de chiffrement")
color: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
? DefaultStyle.info_500_main
: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
? DefaultStyle.warning_600
: DefaultStyle.info_500_main
: DefaultStyle.grey_0
: DefaultStyle.grey_0
font {
pixelSize: 12 * DefaultStyle.dp
weight: 400 * DefaultStyle.dp
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
rightPanel.visible = true
rightPanel.replace(encryptionPanel)
: DefaultStyle.grey_0
font {
pixelSize: 12 * DefaultStyle.dp
weight: 400 * DefaultStyle.dp
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
rightPanel.visible = true
rightPanel.replace(encryptionPanel)
}
}
}
}
Item {
Layout.fillWidth: true
Item {
Layout.fillWidth: true
}
}
}
}
Item {
Layout.fillWidth: true
@ -569,7 +548,7 @@ AbstractWindow {
Component {
id: contactsListPanel
Item {
Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("Transfert d'appel")
Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("Transférer %1 à :").arg(mainWindow.call.core.remoteName)
Keys.onPressed: (event)=> {
if (event.key == Qt.Key_Escape) {
rightPanel.visible = false
@ -583,10 +562,35 @@ AbstractWindow {
anchors.leftMargin: 16 * DefaultStyle.dp
anchors.rightMargin: 16 * DefaultStyle.dp
groupCallVisible: false
displayCurrentCalls: true
searchBarColor: DefaultStyle.grey_0
searchBarBorderColor: DefaultStyle.grey_200
onSelectedContactChanged: {
if (selectedContact) mainWindow.transferCallToContact(mainWindow.call, selectedContact, newCallForm)
onContactClicked: (contact) => {
var callsWin = UtilsCpp.getCallsWindow()
if (contact) callsWin.showConfirmationLambdaPopup(
qsTr("Confirmer le transfert ?"),
qsTr("Vous allez transférer %1 à %2.").arg(mainWindow.call.core.remoteName).arg(contact.core.displayName),
"",
function (confirmed) {
if (confirmed) {
mainWindow.transferCallToContact(mainWindow.call, contact, newCallForm)
}
}
)
}
onTransferCallToAnotherRequested: (dest) => {
var callsWin = UtilsCpp.getCallsWindow()
console.log("transfer to", dest)
callsWin.showConfirmationLambdaPopup(
qsTr("Confirmer le transfert ?"),
qsTr("Vous allez transférer %1 à %2.").arg(mainWindow.call.core.remoteName).arg(dest.core.remoteName),
"",
function (confirmed) {
if (confirmed) {
mainWindow.call.core.lTransferCallToAnother(dest.core.remoteAddress)
}
}
)
}
numPadPopup: numPadPopup
Binding {
@ -632,7 +636,7 @@ AbstractWindow {
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.fillHeight: true
}
SearchBar {
id: dialerTextInput
@ -798,118 +802,8 @@ AbstractWindow {
Layout.leftMargin: 16 * DefaultStyle.dp
Layout.rightMargin: 16 * DefaultStyle.dp
contentItem: ListView {
contentItem: CallListView {
id: callList
model: CallProxy {
id: callProxy
}
implicitHeight: contentHeight// Math.min(contentHeight, rightPanel.height)
spacing: 15 * DefaultStyle.dp
clip: true
onCountChanged: forceLayout()
delegate: Item {
id: callDelegate
width: callList.width
height: 45 * DefaultStyle.dp
RowLayout {
id: delegateContent
anchors.fill: parent
spacing: 0
Avatar {
id: delegateAvatar
_address: modelData.core.remoteAddress
Layout.preferredWidth: 45 * DefaultStyle.dp
Layout.preferredHeight: 45 * DefaultStyle.dp
}
Text {
id: delegateName
property var remoteAddress: UtilsCpp.getDisplayName(modelData.core.remoteAddress)
text: modelData.core.isConference
? modelData.core.conference.core.subject
: remoteAddress ? remoteAddress.value : ""
Layout.leftMargin: 8 * DefaultStyle.dp
}
Item {
Layout.fillHeight: true
Layout.fillWidth: true
}
Text {
id: callStateText
Layout.rightMargin: 2 * DefaultStyle.dp
property string type: modelData.core.isConference ? qsTr('Réunion') : qsTr('Appel')
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? type + qsTr(" en pause")
: type + qsTr(" en cours")
}
PopupButton {
id: listCallOptionsButton
Layout.preferredWidth: 24 * DefaultStyle.dp
Layout.preferredHeight: 24 * DefaultStyle.dp
Layout.rightMargin: 10 * DefaultStyle.dp
popup.contentItem: ColumnLayout {
spacing: 0
Button {
id: pausingButton
onClicked: modelData.core.lSetPaused(!modelData.core.paused)
KeyNavigation.up: endCallButton
KeyNavigation.down: endCallButton
background: Item {}
contentItem: RowLayout {
spacing: 5 * DefaultStyle.dp
Image {
source: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? AppIcons.phone : AppIcons.pause
sourceSize.width: 32 * DefaultStyle.dp
sourceSize.height: 32 * DefaultStyle.dp
Layout.preferredWidth: 32 * DefaultStyle.dp
Layout.preferredHeight: 32 * DefaultStyle.dp
fillMode: Image.PreserveAspectFit
}
Text {
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? qsTr("Reprendre l'appel") : qsTr("Mettre en pause")
color: DefaultStyle.main2_500main
font.bold: pausingButton.shadowEnabled
}
Item {
Layout.fillWidth: true
}
}
}
Button {
id: endCallButton
onClicked: mainWindow.endCall(modelData)
KeyNavigation.up: pausingButton
KeyNavigation.down: pausingButton
background: Item {}
contentItem: RowLayout {
spacing: 5 * DefaultStyle.dp
EffectImage {
imageSource: AppIcons.endCall
colorizationColor: DefaultStyle.danger_500main
width: 32 * DefaultStyle.dp
height: 32 * DefaultStyle.dp
}
Text {
color: DefaultStyle.danger_500main
text: qsTr("Terminer l'appel")
font.bold: endCallButton.shadowEnabled
}
Item {
Layout.fillWidth: true
}
}
}
}
}
}
}
}
}
Item {
@ -1425,8 +1319,8 @@ AbstractWindow {
radius: 71 * DefaultStyle.dp
}
onClicked: {
mainWindow.endCall(mainWindow.call)
mainWindow.callTerminatedByUser = true
mainWindow.endCall(mainWindow.call)
}
}
RowLayout {
@ -1590,7 +1484,6 @@ AbstractWindow {
Layout.preferredWidth: 55 * DefaultStyle.dp
Layout.preferredHeight: 55 * DefaultStyle.dp
contentImageColor: enabled && !checked ? DefaultStyle.grey_0 : DefaultStyle.grey_500
icon.source: AppIcons.more
background: Rectangle {
anchors.fill: moreOptionsButton
color: moreOptionsButton.enabled
@ -1607,17 +1500,6 @@ AbstractWindow {
moreOptionsButton.popup.y = - moreOptionsButton.popup.height - moreOptionsButton.popup.padding
}
}
component MenuButton: Button {
background: Item{}
icon.width: 32 * DefaultStyle.dp
icon.height: 32 * DefaultStyle.dp
textColor: down || checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main
contentImageColor: down || checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main
textSize: 14 * DefaultStyle.dp
textWeight: 400 * DefaultStyle.dp
textHAlignment: Text.AlignLeft
spacing: 5 * DefaultStyle.dp
}
popup.contentItem: ColumnLayout {
id: optionsList
spacing: 5 * DefaultStyle.dp

View file

@ -25,26 +25,27 @@ AbstractWindow {
// height: 40 * DefaultStyle.dp
// color: DefaultStyle.grey_100
// }
function openMainPage(){
if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate)
}
function goToCallHistory() {
console.log("go to call history")
mainWindowStackView.replace(mainPage, StackView.Immediate)
openMainPage()
mainWindowStackView.currentItem.goToCallHistory()
}
function goToNewCall() {
mainWindowStackView.replace(mainPage, StackView.Immediate)
openMainPage()
mainWindowStackView.currentItem.goToNewCall()
}
function displayContactPage(contactAddress) {
mainWindowStackView.replace(mainPage, StackView.Immediate)
openMainPage()
mainWindowStackView.currentItem.displayContactPage(contactAddress)
}
function transferCallSucceed() {
mainWindowStackView.replace(mainPage, StackView.Immediate)
openMainPage()
UtilsCpp.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné"))
}
function initStackViewItem() {
if (accountProxy.haveAccount) mainWindowStackView.replace(mainPage, StackView.Immediate)
if (accountProxy.haveAccount) openMainPage()
else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate)
else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate)
else mainWindowStackView.replace(loginPage, StackView.Immediate)
@ -122,11 +123,11 @@ AbstractWindow {
id: loginPage
LoginPage {
showBackButton: accountProxy.haveAccount
onGoBack: mainWindowStackView.replace(mainPage)
onGoBack: openMainPage()
onUseSIPButtonClicked: mainWindowStackView.push(sipLoginPage)
onGoToRegister: mainWindowStackView.replace(registerPage)
onConnectionSucceed: {
mainWindowStackView.replace(mainPage)
openMainPage()
}
}
}
@ -134,15 +135,15 @@ AbstractWindow {
id: sipLoginPage
SIPLoginPage {
onGoBack: {
if(SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin)
mainWindowStackView.replace(mainPage)
else
if(SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin){
openMainPage()
}else
mainWindowStackView.pop()
}
onGoToRegister: mainWindowStackView.replace(registerPage)
onConnectionSucceed: {
mainWindowStackView.replace(mainPage)
openMainPage()
}
}
}
@ -192,7 +193,7 @@ AbstractWindow {
// TODO : connect to cpp part when ready
var selectedMode = index == 0 ? "chiffrement" : "interoperable"
console.debug("[SelectMode]User: User selected mode " + selectedMode)
mainWindowStackView.replace(mainPage)
openMainPage()
}
}
}

View file

@ -1,5 +1,5 @@
pragma Singleton
import QtQuick 2.15
import QtQuick
QtObject {
property string welcomeLinphoneLogo: "image://internal/linphone.svg"

View file

@ -1,5 +1,5 @@
pragma Singleton
import QtQuick 2.15
import QtQuick
QtObject {
property color main1_100: "#FFEACB"

View file

@ -1,4 +1,4 @@
import QtQuick 2.7
import QtQuick
Rectangle {
function genRandomColor(){