Format QML files

This commit is contained in:
Alexandre Jörgensen 2026-03-10 12:32:35 +01:00
parent ae75e5eff9
commit c73eea248f
180 changed files with 16325 additions and 16134 deletions

View file

@ -5,8 +5,8 @@ import QtQuick.Layouts
import QtQml import QtQml
import Linphone import Linphone
import CustomControls 1.0 import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.Button { Control.Button {
id: mainItem id: mainItem
@ -14,9 +14,7 @@ Control.Button {
property bool asynchronous: false property bool asynchronous: false
hoverEnabled: enabled hoverEnabled: enabled
activeFocusOnTab: true activeFocusOnTab: true
property color disabledFilterColor: color.hslLightness > 0.5 property color disabledFilterColor: color.hslLightness > 0.5 ? DefaultStyle.grey_0 : DefaultStyle.grey_400
? DefaultStyle.grey_0
: DefaultStyle.grey_400
property bool hasNavigationFocus: enabled && (activeFocus || hovered) property bool hasNavigationFocus: enabled && (activeFocus || hovered)
property bool keyboardFocus: FocusHelper.keyboardFocus property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties // Background properties
@ -26,13 +24,9 @@ Control.Button {
property color checkedColor: style?.color?.checked || style?.color?.pressed || Qt.darker(color, 1.1) property color checkedColor: style?.color?.checked || style?.color?.pressed || Qt.darker(color, 1.1)
property bool shadowEnabled: false property bool shadowEnabled: false
property int capitalization property int capitalization
property color backgroundColor: mainItem.checkable && mainItem.checked property color backgroundColor: mainItem.checkable && mainItem.checked ? mainItem.checkedColor
? mainItem.checkedColor || mainItem.pressedColor || mainItem.pressedColor : mainItem.pressed ? mainItem.pressedColor : mainItem.hovered
: mainItem.pressed ? mainItem.hoveredColor : mainItem.color
? mainItem.pressedColor
: mainItem.hovered
? mainItem.hoveredColor
: mainItem.color
// Text properties // Text properties
property bool underline: false property bool underline: false
property real textSize: Utils.getSizeWithScreenRatio(18) property real textSize: Utils.getSizeWithScreenRatio(18)
@ -51,18 +45,16 @@ Control.Button {
property real borderWidth: Utils.getSizeWithScreenRatio(1) property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Image properties // Image properties
property var contentImageColor: style?.image? style.image.normal : DefaultStyle.main2_600 property var contentImageColor: style?.image ? style.image.normal : DefaultStyle.main2_600
property var hoveredImageColor: style && style.image && style.image.hovered ? style.image.hovered : Qt.darker(contentImageColor, 1.05) property var hoveredImageColor: style && style.image && style.image.hovered ? style.image.hovered : Qt.darker(
property var checkedImageColor: style && style.image && style.image.checked ? style.image.checked : Qt.darker(contentImageColor, 1.1) contentImageColor, 1.05)
property var pressedImageColor: style && style.image && style.image.pressed ? style.image.pressed : Qt.darker(contentImageColor, 1.1) property var checkedImageColor: style && style.image && style.image.checked ? style.image.checked : Qt.darker(
contentImageColor, 1.1)
property var pressedImageColor: style && style.image && style.image.pressed ? style.image.pressed : Qt.darker(
contentImageColor, 1.1)
icon.source: style?.iconSource || "" icon.source: style?.iconSource || ""
property color colorizationColor: checkable && checked property color colorizationColor: checkable && checked ? checkedImageColor : pressed ? pressedImageColor : hovered
? checkedImageColor ? hoveredImageColor : contentImageColor
: pressed
? pressedImageColor
: hovered
? hoveredImageColor
: contentImageColor
// Size properties // Size properties
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
property real radius: Math.ceil(height / 2) property real radius: Math.ceil(height / 2)
@ -76,7 +68,7 @@ Control.Button {
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
} }
background: Loader{ background: Loader {
asynchronous: mainItem.asynchronous asynchronous: mainItem.asynchronous
anchors.fill: parent anchors.fill: parent
@ -126,18 +118,16 @@ Control.Button {
text: mainItem.text text: mainItem.text
textFormat: mainItem.textFormat textFormat: mainItem.textFormat
maximumLineCount: 1 maximumLineCount: 1
color: mainItem.checkable && mainItem.checked || mainItem.pressed color: mainItem.checkable && mainItem.checked || mainItem.pressed ? mainItem.pressedTextColor : mainItem.hovered
? mainItem.pressedTextColor ? mainItem.hoveredTextColor : mainItem.textColor
: mainItem.hovered
? mainItem.hoveredTextColor
: mainItem.textColor
font { font {
pixelSize: mainItem.textSize pixelSize: mainItem.textSize
weight: mainItem.textWeight weight: mainItem.textWeight
family: DefaultStyle.defaultFont family: DefaultStyle.defaultFont
capitalization: mainItem.capitalization capitalization: mainItem.capitalization
underline: mainItem.underline underline: mainItem.underline
bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (mainItem.hovered || mainItem.pressed) bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (
mainItem.hovered || mainItem.pressed)
} }
ToolTip { ToolTip {
parent: mainItem parent: mainItem
@ -159,38 +149,43 @@ Control.Button {
colorizationColor: mainItem.colorizationColor colorizationColor: mainItem.colorizationColor
} }
contentItem: Control.StackView{ contentItem: Control.StackView {
id: stacklayout id: stacklayout
function updateComponent(){ function updateComponent() {
var item var item;
var component = mainItem.text.length != 0 && mainItem.icon.source.toString().length != 0 var component = mainItem.text.length != 0 && mainItem.icon.source.toString().length != 0 ? imageTextComponent :
? imageTextComponent mainItem.text.length != 0 ? textComponent : mainItem.icon.source.toString().length != 0
: mainItem.text.length != 0 ? imageComponent : emptyComponent;
? textComponent if (stacklayout.depth == 0)
: mainItem.icon.source.toString().length != 0 item = stacklayout.push(component, Control.StackView.Immediate);
? imageComponent else if (component != stacklayout.get(0))
: emptyComponent item = stacklayout.replace(component, Control.StackView.Immediate);
if( stacklayout.depth == 0) if (item) {
item = stacklayout.push(component, Control.StackView.Immediate) // Workaround for Qt bug : set from the item and not from the contentItem which seems to be lost
else if( component != stacklayout.get(0)) implicitHeight = Qt.binding(function () {
item = stacklayout.replace(component, Control.StackView.Immediate) return item.implicitHeight;
if(item){// Workaround for Qt bug : set from the item and not from the contentItem which seems to be lost });
implicitHeight = Qt.binding(function() { return item.implicitHeight}) implicitWidth = Qt.binding(function () {
implicitWidth = Qt.binding(function() { return item.implicitWidth}) return item.implicitWidth;
});
} }
} }
Component.onCompleted: { Component.onCompleted: {
updateComponent() updateComponent();
} }
Connections{ Connections {
target: mainItem target: mainItem
function onTextChanged(){stacklayout.updateComponent()} function onTextChanged() {
function onIconChanged(){stacklayout.updateComponent()} stacklayout.updateComponent();
}
function onIconChanged() {
stacklayout.updateComponent();
}
} }
Component{ Component {
id: imageTextComponent id: imageTextComponent
// Workaround for centering the content when its // Workaround for centering the content when its
// width is smaller than the button width // width is smaller than the button width
@ -201,25 +196,26 @@ Control.Button {
id: content id: content
spacing: mainItem.spacing spacing: mainItem.spacing
anchors.centerIn: parent anchors.centerIn: parent
ButtonImage{ ButtonImage {
Layout.preferredWidth: mainItem.icon.width Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height Layout.preferredHeight: mainItem.icon.height
} }
ButtonText { ButtonText {}
} }
} }
} }
} Component {
Component{
id: textComponent id: textComponent
ButtonText { ButtonText {
width: stacklayout.width width: stacklayout.width
height: stacklayout.height height: stacklayout.height
// Hack for StackView binding loop // Hack for StackView binding loop
onImplicitHeightChanged: {implicitHeight} onImplicitHeightChanged: {
implicitHeight;
} }
} }
Component{ }
Component {
id: imageComponent id: imageComponent
Item { Item {
width: stacklayout.width width: stacklayout.width
@ -237,7 +233,7 @@ Control.Button {
} }
} }
} }
Component{ Component {
id: emptyComponent id: emptyComponent
Item { Item {
width: stacklayout.width width: stacklayout.width

View file

@ -43,7 +43,7 @@ ComboBox {
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
radius: Utils.getSizeWithScreenRatio(16) radius: Utils.getSizeWithScreenRatio(16)
border.color: DefaultStyle.main1_500_main border.color: DefaultStyle.main1_500_main
border.width: calendar.activeFocus? 1 : 0 border.width: calendar.activeFocus ? 1 : 0
} }
MultiEffect { MultiEffect {
anchors.fill: calendarBg anchors.fill: calendarBg

View file

@ -7,7 +7,7 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.CheckBox { Control.CheckBox {
id: mainItem id: mainItem
hoverEnabled: enabled hoverEnabled: enabled
indicator: Item{ indicator: Item {
implicitWidth: Utils.getSizeWithScreenRatio(20) implicitWidth: Utils.getSizeWithScreenRatio(20)
implicitHeight: Utils.getSizeWithScreenRatio(20) implicitHeight: Utils.getSizeWithScreenRatio(20)
x: (parent.width - width) / 2 x: (parent.width - width) / 2

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Button { Button {
id: mainItem id: mainItem
@ -14,11 +14,7 @@ Button {
color: style?.color?.normal || DefaultStyle.grey_500 color: style?.color?.normal || DefaultStyle.grey_500
pressedColor: checkedIconUrl ? color : style?.color?.pressed || DefaultStyle.grey_500 pressedColor: checkedIconUrl ? color : style?.color?.pressed || DefaultStyle.grey_500
hoveredColor: checked ? Qt.darker(pressedColor, 1.05) : style?.color?.hovered || DefaultStyle.grey_500 hoveredColor: checked ? Qt.darker(pressedColor, 1.05) : style?.color?.hovered || DefaultStyle.grey_500
property color backgroundColor: hovered property color backgroundColor: hovered ? hoveredColor : checked ? pressedColor : color
? hoveredColor
: checked
? pressedColor
: color
checkable: true checkable: true
Accessible.role: Accessible.Button Accessible.role: Accessible.Button
icon.source: checkedIconUrl && mainItem.checked ? checkedIconUrl : iconUrl icon.source: checkedIconUrl && mainItem.checked ? checkedIconUrl : iconUrl

View file

@ -53,7 +53,8 @@ Control.ComboBox {
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (!mainItem.contentItem.activeFocus && (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return)) { if (!mainItem.contentItem.activeFocus && (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key
== Qt.Key_Return)) {
mainItem.popup.open(); mainItem.popup.open();
event.accepted = true; event.accepted = true;
} }
@ -65,7 +66,9 @@ Control.ComboBox {
anchors.fill: parent anchors.fill: parent
radius: Math.round(mainItem.height / 2) radius: Math.round(mainItem.height / 2)
color: mainItem.enabled ? mainItem.color : mainItem.disabledColor color: mainItem.enabled ? mainItem.color : mainItem.disabledColor
border.color: !mainItem.enabled ? mainItem.disabledBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus || mainItem.popup.opened ? mainItem.activeFocusedBorderColor : mainItem.borderColor border.color: !mainItem.enabled ? mainItem.disabledBorderColor : mainItem.keyboardFocus
? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus || mainItem.popup.opened
? mainItem.activeFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
MultiEffect { MultiEffect {
@ -185,7 +188,9 @@ Control.ComboBox {
height: mainItem.height height: mainItem.height
// anchors.left: listView.left // anchors.left: listView.left
// anchors.right: listView.right // anchors.right: listView.right
Accessible.name: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : "" Accessible.name: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text
? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] :
$modelData : ""
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
EffectImage { EffectImage {
@ -209,14 +214,17 @@ Control.ComboBox {
pixelSize: mainItem.pixelSize pixelSize: mainItem.pixelSize
weight: mainItem.weight weight: mainItem.weight
} }
text: mainItem.flagRole ? typeof (modelData) != "undefined" ? modelData[mainItem.flagRole] : $modelData[mainItem.flagRole] : "" text: mainItem.flagRole ? typeof (modelData) != "undefined" ? modelData[mainItem.flagRole] :
$modelData[mainItem.flagRole] : ""
} }
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(flagItem.visble ? 5 : 25) Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(flagItem.visble ? 5 : 25)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20) Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
text: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : "" text: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text
? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] :
$modelData : ""
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere

View file

@ -15,8 +15,10 @@ Control.ComboBox {
property color keyboardFocusedBorderColor: DefaultStyle.main2_900 property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1) property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
property string text: combobox.model.getAt(combobox.currentIndex) ? combobox.model.getAt(combobox.currentIndex).countryCallingCode : "" property string text: combobox.model.getAt(combobox.currentIndex) ? combobox.model.getAt(
currentIndex: phoneNumberModel.count > 0 ? Math.max(0, phoneNumberModel.findIndexByCountryCallingCode(defaultCallingCode)) : -1 combobox.currentIndex).countryCallingCode : ""
currentIndex: phoneNumberModel.count > 0 ? Math.max(0, phoneNumberModel.findIndexByCountryCallingCode(
defaultCallingCode)) : -1
Accessible.name: mainItem.Accessible.name Accessible.name: mainItem.Accessible.name
model: PhoneNumberProxy { model: PhoneNumberProxy {
id: phoneNumberModel id: phoneNumberModel
@ -25,15 +27,10 @@ Control.ComboBox {
anchors.fill: parent anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(63) radius: Utils.getSizeWithScreenRatio(63)
color: mainItem.enableBackgroundColor ? DefaultStyle.grey_100 : "transparent" color: mainItem.enableBackgroundColor ? DefaultStyle.grey_100 : "transparent"
border.color: mainItem.keyboardFocus border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.enableBackgroundColors ? (
? mainItem.keyboardFocusedBorderColor mainItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : mainItem.activeFocus
: mainItem.enableBackgroundColors || textField.activeFocus ? DefaultStyle.main1_500_main :
? (mainItem.errorMessage.length > 0 DefaultStyle.grey_200) : "transparent"
? DefaultStyle.danger_500_main
: mainItem.activeFocus || textField.activeFocus
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200)
: "transparent"
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
contentItem: RowLayout { contentItem: RowLayout {
@ -97,7 +94,7 @@ Control.ComboBox {
id: listView id: listView
clip: true clip: true
anchors.fill: parent anchors.fill: parent
model: PhoneNumberProxy{} model: PhoneNumberProxy {}
currentIndex: combobox.highlightedIndex >= 0 ? combobox.highlightedIndex : 0 currentIndex: combobox.highlightedIndex >= 0 ? combobox.highlightedIndex : 0
keyNavigationEnabled: true keyNavigationEnabled: true
keyNavigationWraps: true keyNavigationWraps: true
@ -171,16 +168,16 @@ Control.ComboBox {
visible: parent.containsMouse visible: parent.containsMouse
} }
onClicked: { onClicked: {
combobox.currentIndex = index combobox.currentIndex = index;
listPopup.close() listPopup.close();
} }
} }
} }
Control.ScrollIndicator.vertical: Control.ScrollIndicator { } Control.ScrollIndicator.vertical: Control.ScrollIndicator {}
} }
onOpened: { onOpened: {
listView.positionViewAtIndex(listView.currentIndex, ListView.Center) listView.positionViewAtIndex(listView.currentIndex, ListView.Center);
} }
background: Item { background: Item {

View file

@ -3,7 +3,7 @@ import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
MouseArea { MouseArea {
id: mainItem id: mainItem
@ -19,16 +19,16 @@ MouseArea {
height: content.implicitHeight height: content.implicitHeight
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
activeFocusOnTab: true activeFocusOnTab: true
Keys.onPressed: (event) => { Keys.onPressed: event => {
if(event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return){ if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
mainItem.clicked(undefined) mainItem.clicked(undefined);
event.accepted = true event.accepted = true;
} }
} }
RowLayout { RowLayout {
id: content id: content
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.fill:parent anchors.fill: parent
EffectImage { EffectImage {
id: image id: image
Layout.preferredWidth: mainItem.iconSize Layout.preferredWidth: mainItem.iconSize
@ -63,7 +63,9 @@ MouseArea {
font: Typography.p1 font: Typography.p1
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
EffectImage { EffectImage {
id: arrowImage id: arrowImage
visible: mainItem.arrowImageVisible visible: mainItem.arrowImageVisible

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Button { Button {
@ -18,11 +18,8 @@ Button {
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
radius: mainItem.radius radius: mainItem.radius
color: mainItem.pressed color: mainItem.pressed ? mainItem.pressedColor : mainItem.hovered || mainItem.hasNavigationFocus ? mainItem.hoveredColor :
? mainItem.pressedColor mainItem.color
: mainItem.hovered || mainItem.hasNavigationFocus
? mainItem.hoveredColor
: mainItem.color
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
@ -31,11 +28,8 @@ Button {
imageSource: mainItem.icon.source imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed colorizationColor: mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor :
? mainItem.pressedImageColor mainItem.contentImageColor
: mainItem.hovered
? mainItem.hoveredImageColor
: mainItem.contentImageColor
Layout.preferredWidth: mainItem.icon.width Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height Layout.preferredHeight: mainItem.icon.height
} }

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Button { Button {
@ -19,16 +19,13 @@ Button {
contentItem: RowLayout { contentItem: RowLayout {
spacing: mainItem.spacing spacing: mainItem.spacing
layoutDirection: mainItem.inverseLayout ? Qt.RightToLeft: Qt.LeftToRight layoutDirection: mainItem.inverseLayout ? Qt.RightToLeft : Qt.LeftToRight
EffectImage { EffectImage {
imageSource: mainItem.icon.source imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed colorizationColor: mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor :
? mainItem.pressedImageColor mainItem.contentImageColor
: mainItem.hovered
? mainItem.hoveredImageColor
: mainItem.contentImageColor
Layout.preferredWidth: mainItem.icon.width Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height Layout.preferredHeight: mainItem.icon.height
} }
@ -41,18 +38,15 @@ Button {
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
text: mainItem.text text: mainItem.text
maximumLineCount: 1 maximumLineCount: 1
color: pressed color: pressed ? mainItem.pressedTextColor : mainItem.hovered ? mainItem.hoveredTextColor : mainItem.textColor
? mainItem.pressedTextColor
: mainItem.hovered
? mainItem.hoveredTextColor
: mainItem.textColor
font { font {
pixelSize: mainItem.textSize pixelSize: mainItem.textSize
weight: mainItem.textWeight weight: mainItem.textWeight
family: DefaultStyle.defaultFont family: DefaultStyle.defaultFont
capitalization: mainItem.capitalization capitalization: mainItem.capitalization
underline: mainItem.underline underline: mainItem.underline
bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (mainItem.hovered || mainItem.pressed) bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (
mainItem.hovered || mainItem.pressed)
} }
} }
TextMetrics { TextMetrics {
@ -67,6 +61,8 @@ Button {
bold: true bold: true
} }
} }
Item {Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
} }
} }

View file

@ -3,7 +3,7 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {

View file

@ -47,15 +47,18 @@ Button {
} }
function getPreviousItem(index) { function getPreviousItem(index) {
return _getPreviousItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, index); return _getPreviousItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem,
index);
} }
function getNextItem(index) { function getNextItem(index) {
return _getNextItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, index); return _getNextItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem,
index);
} }
function _getPreviousItem(content, index) { function _getPreviousItem(content, index) {
if (!content.visible) return null if (!content.visible)
return null;
if (content.visibleChildren.length == 0 || !hasFocusableChild(content)) if (content.visibleChildren.length == 0 || !hasFocusableChild(content))
return null; return null;
--index; --index;

View file

@ -16,9 +16,9 @@ Control.RadioButton {
property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered
//onClicked: if (checkOnClick && !mainItem.checked) mainItem.toggle() //onClicked: if (checkOnClick && !mainItem.checked) mainItem.toggle()
MouseArea{ MouseArea {
id: mouseArea id: mouseArea
anchors.fill:parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
@ -31,16 +31,16 @@ Control.RadioButton {
Rectangle { Rectangle {
id: backgroundArea id: backgroundArea
anchors.fill: parent anchors.fill: parent
radius: mainItem.indicatorSize/2 radius: mainItem.indicatorSize / 2
color: "transparent" color: "transparent"
border.color: mainItem.color border.color: mainItem.color
border.width: Utils.getSizeWithScreenRatio(2) border.width: Utils.getSizeWithScreenRatio(2)
Rectangle { Rectangle {
width: parent.width/2 width: parent.width / 2
height: parent.height/2 height: parent.height / 2
x: parent.width/4 x: parent.width / 4
y: parent.width/4 y: parent.width / 4
radius: width/2 radius: width / 2
color: mainItem.color color: mainItem.color
visible: mainItem.checked visible: mainItem.checked
} }

View file

@ -16,7 +16,8 @@ Control.RadioButton {
anchors.fill: parent anchors.fill: parent
hoverEnabled: false hoverEnabled: false
cursorShape: mainItem.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: mainItem.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: if (!mainItem.checked) mainItem.toggle() onClicked: if (!mainItem.checked)
mainItem.toggle()
} }
background: Rectangle { background: Rectangle {
@ -34,15 +35,15 @@ Control.RadioButton {
Rectangle { Rectangle {
implicitWidth: Utils.getSizeWithScreenRatio(16) implicitWidth: Utils.getSizeWithScreenRatio(16)
implicitHeight: Utils.getSizeWithScreenRatio(16) implicitHeight: Utils.getSizeWithScreenRatio(16)
radius: implicitWidth/2 radius: implicitWidth / 2
border.color: mainItem.color border.color: mainItem.color
Rectangle { Rectangle {
width: parent.width/2 width: parent.width / 2
height: parent.height/2 height: parent.height / 2
x: parent.width/4 x: parent.width / 4
y: parent.width/4 y: parent.width / 4
radius: width/2 radius: width / 2
color: mainItem.color color: mainItem.color
visible: mainItem.checked visible: mainItem.checked
} }

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Basic import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ComboBox { ComboBox {
id: mainItem id: mainItem
@ -14,16 +14,16 @@ ComboBox {
property alias entries: mainItem.model property alias entries: mainItem.model
oneLine: true oneLine: true
currentIndex: Utils.findIndex(model, function (entry) { currentIndex: Utils.findIndex(model, function (entry) {
if(propertyOwnerGui) if (propertyOwnerGui)
return Utils.equalObject(entry,propertyOwnerGui.core[propertyName]) return Utils.equalObject(entry, propertyOwnerGui.core[propertyName]);
else else
return Utils.equalObject(entry,propertyOwner[propertyName]) return Utils.equalObject(entry, propertyOwner[propertyName]);
}) })
onCurrentValueChanged: { onCurrentValueChanged: {
if(propertyOwnerGui) { if (propertyOwnerGui) {
binding.when = !Utils.equalObject(currentValue,propertyOwnerGui.core[propertyName]) binding.when = !Utils.equalObject(currentValue, propertyOwnerGui.core[propertyName]);
}else{ } else {
binding.when = !Utils.equalObject(currentValue,propertyOwner[propertyName]) binding.when = !Utils.equalObject(currentValue, propertyOwner[propertyName]);
} }
} }
Binding { Binding {

View file

@ -2,10 +2,10 @@ import QtQuick
import QtQuick.Controls.Basic import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
RowLayout { RowLayout {
id:mainItem id: mainItem
property string titleText property string titleText
property string subTitleText property string subTitleText
property string propertyName property string propertyName
@ -13,9 +13,9 @@ RowLayout {
property var propertyOwnerGui property var propertyOwnerGui
property bool enabled: true property bool enabled: true
property alias checked: switchButton.checked property alias checked: switchButton.checked
spacing : Utils.getSizeWithScreenRatio(20) spacing: Utils.getSizeWithScreenRatio(20)
signal toggled() signal toggled
ColumnLayout { ColumnLayout {
Layout.minimumHeight: Utils.getSizeWithScreenRatio(32) Layout.minimumHeight: Utils.getSizeWithScreenRatio(32)
@ -39,12 +39,12 @@ RowLayout {
Switch { Switch {
id: switchButton id: switchButton
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
checked: propertyOwnerGui ? propertyOwnerGui.core[mainItem.propertyName] checked: propertyOwnerGui ? propertyOwnerGui.core[mainItem.propertyName] : propertyOwner
: propertyOwner ? propertyOwner[mainItem.propertyName] : false ? propertyOwner[mainItem.propertyName] : false
enabled: mainItem.enabled enabled: mainItem.enabled
onToggled: { onToggled: {
binding.when = true binding.when = true;
mainItem.toggled() mainItem.toggled();
} }
implicitHeight: Utils.getSizeWithScreenRatio(30) implicitHeight: Utils.getSizeWithScreenRatio(30)
Accessible.name: "%1 %2".arg(mainItem.titleText).arg(mainItem.subTitleText) Accessible.name: "%1 %2".arg(mainItem.titleText).arg(mainItem.subTitleText)

View file

@ -16,7 +16,7 @@ Control.Slider {
property color keyboardFocusedBorderColor: DefaultStyle.main2_900 property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: 0 property real borderWidth: 0
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
background: Item{ background: Item {
x: mainItem.leftPadding x: mainItem.leftPadding
y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2 y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2
implicitWidth: Utils.getSizeWithScreenRatio(200) implicitWidth: Utils.getSizeWithScreenRatio(200)
@ -35,8 +35,14 @@ Control.Slider {
height: parent.height height: parent.height
gradient: Gradient { gradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.main1_300 } GradientStop {
GradientStop { position: 1.0; color: DefaultStyle.main1_500_main } position: 0.0
color: DefaultStyle.main1_300
}
GradientStop {
position: 1.0
color: DefaultStyle.main1_500_main
}
} }
radius: Math.round(height / 2) radius: Math.round(height / 2)
} }

View file

@ -16,24 +16,21 @@ Item {
property alias call: allDevices.currentCall property alias call: allDevices.currentCall
property ConferenceGui conference: call && call.core.conference || null property ConferenceGui conference: call && call.core.conference || null
property var callState: call && call.core.state || undefined property var callState: call && call.core.state || undefined
property string localAddress: call property string localAddress: call ? call.conference ? call.conference.core.me.core.sipAddress :
? call.conference call.core.localAddress : ""
? call.conference.core.me.core.sipAddress
: call.core.localAddress
: ""
property bool sideStickersVisible: sideStickers.visible property bool sideStickersVisible: sideStickers.visible
// currently speaking address (for hiding in list view) // currently speaking address (for hiding in list view)
property string activeSpeakerAddress property string activeSpeakerAddress
property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy { property ParticipantDeviceProxy participantDevices: ParticipantDeviceProxy {
id: allDevices id: allDevices
qmlName: "AS" qmlName: "AS"
onCountChanged: console.log("Device count changed : " +count) onCountChanged: console.log("Device count changed : " + count)
Component.onCompleted: console.log("Loaded : " +allDevices) Component.onCompleted: console.log("Loaded : " + allDevices)
} }
RowLayout{ RowLayout {
anchors.fill: parent anchors.fill: parent
anchors.rightMargin: Utils.getSizeWithScreenRatio(10) anchors.rightMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(16) spacing: Utils.getSizeWithScreenRatio(16)
@ -46,7 +43,8 @@ Item {
displayAll: !mainItem.conference displayAll: !mainItem.conference
participantDevice: mainItem.conference && mainItem.conference.core.activeSpeakerDevice participantDevice: mainItem.conference && mainItem.conference.core.activeSpeakerDevice
property var address: participantDevice && participantDevice.core.address property var address: participantDevice && participantDevice.core.address
videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call && call.core.remoteVideoEnabled) videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call
&& call.core.remoteVideoEnabled)
qmlName: 'AS' qmlName: 'AS'
securityBreach: !mainItem.conference && mainItem.call?.core.isMismatch || false securityBreach: !mainItem.conference && mainItem.call?.core.isMismatch || false
displayPresence: false displayPresence: false
@ -57,7 +55,7 @@ Item {
when: true when: true
} }
} }
ListView{ ListView {
id: sideStickers id: sideStickers
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(300) Layout.preferredWidth: Utils.getSizeWithScreenRatio(300)
@ -68,24 +66,26 @@ Item {
model: allDevices model: allDevices
snapMode: ListView.SnapOneItem snapMode: ListView.SnapOneItem
clip: true clip: true
delegate: Item{ // Spacing workaround delegate: Item {
visible: $modelData && mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released // Spacing workaround
&& ($modelData.core.address != activeSpeakerAddress || mainItem.conference?.core.isScreenSharingEnabled) || false visible: $modelData && mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState
!= LinphoneEnums.CallState.Released && ($modelData.core.address != activeSpeakerAddress || mainItem.conference
?.core.isScreenSharingEnabled) || false
height: visible ? Utils.getSizeWithScreenRatio(180 + 15) : 0 height: visible ? Utils.getSizeWithScreenRatio(180 + 15) : 0
width: Utils.getSizeWithScreenRatio(300) width: Utils.getSizeWithScreenRatio(300)
Sticker { Sticker {
previewEnabled: index == 0 // before anchors for priority initialization previewEnabled: index == 0 // before anchors for priority initialization
anchors.fill: parent anchors.fill: parent
anchors.bottomMargin: Utils.getSizeWithScreenRatio(15)// Spacing anchors.bottomMargin: Utils.getSizeWithScreenRatio(15)// Spacing
qmlName: 'S_'+index qmlName: 'S_' + index
visible: parent.visible visible: parent.visible
videoEnabled: (index === 0 && mainItem.call.core.cameraEnabled) videoEnabled: (index === 0 && mainItem.call.core.cameraEnabled) || (!previewEnabled && call
|| (!previewEnabled && call && call.core.remoteVideoEnabled) && call.core.remoteVideoEnabled) || (!previewEnabled && participantDevice
|| (!previewEnabled && participantDevice && participantDevice.core.videoEnabled) && participantDevice.core.videoEnabled)
participantDevice: $modelData participantDevice: $modelData
displayAll: false displayAll: false
displayPresence: false displayPresence: false
Component.onCompleted: console.log(qmlName + " is " +($modelData ? $modelData.core.address : "-")) Component.onCompleted: console.log(qmlName + " is " + ($modelData ? $modelData.core.address : "-"))
} }
} }
} }

View file

@ -18,19 +18,23 @@ Mosaic {
margins: 0 margins: 0
// On grid view, we limit the quality if there are enough participants// The vga mode has been activated from the factory rc // On grid view, we limit the quality if there are enough participants// The vga mode has been activated from the factory rc
//onParticipantCountChanged: participantCount > ConstantsCpp.maxMosaicParticipants ? SettingsModel.setLimitedMosaicQuality() : SettingsModel.setHighMosaicQuality() //onParticipantCountChanged: participantCount > ConstantsCpp.maxMosaicParticipants ? SettingsModel.setLimitedMosaicQuality() : SettingsModel.setHighMosaicQuality()
delegateModel: DelegateModel{ delegateModel: DelegateModel {
id: gridModel id: gridModel
property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy { property ParticipantDeviceProxy participantDevices: ParticipantDeviceProxy {
id: allDevices id: allDevices
qmlName: "G" qmlName: "G"
Component.onCompleted: console.log("Loaded : " +allDevices + " = " +allDevices.count) Component.onCompleted: console.log("Loaded : " + allDevices + " = " + allDevices.count)
} }
model: grid.call && grid.call.core.isConference ? participantDevices: [0,1] model: grid.call && grid.call.core.isConference ? participantDevices : [0, 1]
delegate: Item{ delegate: Item {
id: avatarCell id: avatarCell
property ParticipantDeviceGui currentDevice: index >= 0 && grid.call && grid.call.core.isConference ? $modelData : null property ParticipantDeviceGui currentDevice: index >= 0 && grid.call && grid.call.core.isConference ? $modelData :
null
onCurrentDeviceChanged: { onCurrentDeviceChanged: {
if(index < 0) cameraView.enabled = false // this is a delegate destruction. We need to stop camera before Qt change its currentDevice (and then, let CameraView to delete wrong renderer) if (index < 0)
cameraView.enabled
= false; // this is a delegate destruction. We need to stop camera before Qt change its currentDevice (and then, let CameraView to delete wrong renderer)
} }
height: grid.cellHeight - Utils.getSizeWithScreenRatio(10) height: grid.cellHeight - Utils.getSizeWithScreenRatio(10)
@ -40,14 +44,15 @@ Mosaic {
previewEnabled: index == 0 previewEnabled: index == 0
visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
anchors.fill: parent anchors.fill: parent
qmlName: 'G_'+index qmlName: 'G_' + index
call: grid.call && !grid.call.core.isConference ? grid.call : null call: grid.call && !grid.call.core.isConference ? grid.call : null
property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress) property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress)
account: (index == 0 && accountObj) ? accountObj.value : null account: (index == 0 && accountObj) ? accountObj.value : null
displayAll: false displayAll: false
displayPresence: false displayPresence: false
participantDevice: avatarCell.currentDevice participantDevice: avatarCell.currentDevice
Component.onCompleted: console.log(qmlName + " is " +(call ? call.core.remoteAddress : currentDevice ? currentDevice.core.address : 'addr_NotDefined')) Component.onCompleted: console.log(qmlName + " is " + (call ? call.core.remoteAddress : currentDevice
? currentDevice.core.address : 'addr_NotDefined'))
} }
} }
} }

View file

@ -5,7 +5,7 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
@ -20,12 +20,9 @@ ColumnLayout {
property bool isConference: conferenceInfo != undefined && conferenceInfo != null property bool isConference: conferenceInfo != undefined && conferenceInfo != null
property string contactAddress: specificAddress != "" ? specificAddress : contact && contact.core.defaultAddress || "" property string contactAddress: specificAddress != "" ? specificAddress : contact && contact.core.defaultAddress || ""
property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress) property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress)
property string computedContactName: computedContactNameObj ? computedContactNameObj.value: "" property string computedContactName: computedContactNameObj ? computedContactNameObj.value : ""
property string contactName: contact property string contactName: contact ? contact.core.fullName : callHistoryGui ? callHistoryGui.core.displayName :
? contact.core.fullName computedContactName
: callHistoryGui
? callHistoryGui.core.displayName
: computedContactName
// Set this property to get the security informations // Set this property to get the security informations
// for a specific address and not for the entire contact // for a specific address and not for the entire contact
@ -34,8 +31,8 @@ ColumnLayout {
property alias buttonContent: rightButton.data property alias buttonContent: rightButton.data
property alias detailContent: detailControl.data property alias detailContent: detailControl.data
signal conferenceChatDisplayRequested() signal conferenceChatDisplayRequested
signal conferenceCallHistoryDisplayRequested() signal conferenceCallHistoryDisplayRequested
ColumnLayout { ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(13) spacing: Utils.getSizeWithScreenRatio(13)
@ -119,9 +116,9 @@ ColumnLayout {
style: ButtonStyle.grey style: ButtonStyle.grey
onClicked: { onClicked: {
if (mainItem.conferenceInfo) { if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow() var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfo) callsWindow.setupConference(mainItem.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow) UtilsCpp.smartShowWindow(callsWindow);
} }
} }
} }
@ -142,9 +139,9 @@ ColumnLayout {
//: "Join" //: "Join"
label: qsTr("meeting_info_join_title") label: qsTr("meeting_info_join_title")
button.onClicked: if (mainItem.conferenceInfo) { button.onClicked: if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow() var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfo) callsWindow.setupConference(mainItem.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow) UtilsCpp.smartShowWindow(callsWindow);
} }
} }
LabelButton { LabelButton {
@ -155,14 +152,16 @@ ColumnLayout {
button.icon.width: Utils.getSizeWithScreenRatio(24) button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24) button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: button.checked ? AppIcons.callList : AppIcons.chatTeardropText button.icon.source: button.checked ? AppIcons.callList : AppIcons.chatTeardropText
label: button.checked label: button.checked ?
//: "Call history" //: "Call history"
? qsTr("contact_call_history_action") qsTr("contact_call_history_action") :
//: "Conversation" //: "Conversation"
: qsTr("contact_conversation_action") qsTr("contact_conversation_action")
button.onCheckedChanged: { button.onCheckedChanged: {
if (button.checked) mainItem.conferenceChatDisplayRequested() if (button.checked)
else mainItem.conferenceCallHistoryDisplayRequested() mainItem.conferenceChatDisplayRequested();
else
mainItem.conferenceCallHistoryDisplayRequested();
} }
} }
} }
@ -181,8 +180,10 @@ ColumnLayout {
//: "Appel" //: "Appel"
label: qsTr("contact_call_action") label: qsTr("contact_call_action")
button.onClicked: { button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, false, mainItem) if (mainItem.specificAddress === "")
else UtilsCpp.createCall(mainItem.specificAddress) mainWindow.startCallWithContact(mainItem.contact, false, mainItem);
else
UtilsCpp.createCall(mainItem.specificAddress);
} }
} }
LabelButton { LabelButton {
@ -195,13 +196,12 @@ ColumnLayout {
//: "Message" //: "Message"
label: qsTr("contact_message_action") label: qsTr("contact_message_action")
button.onClicked: { button.onClicked: {
console.debug("[CallHistoryLayout.qml] Open conversation") console.debug("[CallHistoryLayout.qml] Open conversation");
if (mainItem.specificAddress === "") { if (mainItem.specificAddress === "") {
mainWindow.sendMessageToContact(mainItem.contact) mainWindow.sendMessageToContact(mainItem.contact);
} } else {
else { console.log("specific address", mainItem.specificAddress);
console.log("specific address", mainItem.specificAddress) mainWindow.displayChatPage(mainItem.specificAddress);
mainWindow.displayChatPage(mainItem.specificAddress)
} }
} }
} }
@ -215,8 +215,12 @@ ColumnLayout {
//: "Appel Video" //: "Appel Video"
label: qsTr("contact_video_call_action") label: qsTr("contact_video_call_action")
button.onClicked: { button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, true, mainItem) if (mainItem.specificAddress === "")
else UtilsCpp.createCall(mainItem.specificAddress, {'localVideoEnabled': true}) mainWindow.startCallWithContact(mainItem.contact, true, mainItem);
else
UtilsCpp.createCall(mainItem.specificAddress, {
'localVideoEnabled': true
});
} }
} }
} }

View file

@ -16,53 +16,49 @@ Item {
property CallGui call property CallGui call
property ConferenceGui conference: call && call.core.conference property ConferenceGui conference: call && call.core.conference
property bool callTerminatedByUser: false property bool callTerminatedByUser: false
property bool callStarted: call? call.core.isStarted : false property bool callStarted: call ? call.core.isStarted : false
readonly property var callState: call?.core.state readonly property var callState: call?.core.state
onCallStateChanged: if (callState === LinphoneEnums.CallState.End || callState === LinphoneEnums.CallState.Released) preview.visible = false onCallStateChanged: if (callState === LinphoneEnums.CallState.End || callState === LinphoneEnums.CallState.Released)
preview.visible = false
property int conferenceLayout: call ? call.core.conferenceVideoLayout : LinphoneEnums.ConferenceLayout.ActiveSpeaker property int conferenceLayout: call ? call.core.conferenceVideoLayout : LinphoneEnums.ConferenceLayout.ActiveSpeaker
property int participantDeviceCount: conference ? conference.core.participantDeviceCount : -1 property int participantDeviceCount: conference ? conference.core.participantDeviceCount : -1
property int lastConfLayoutBeforeSharing: -1 property int lastConfLayoutBeforeSharing: -1
property string localAddress: call property string localAddress: call ? call.conference ? call.conference.core.me.core.sipAddress :
? call.conference call.core.localAddress : ""
? call.conference.core.me.core.sipAddress
: call.core.localAddress
: ""
onParticipantDeviceCountChanged: { onParticipantDeviceCountChanged: {
setConferenceLayout() setConferenceLayout();
} }
Component.onCompleted: setConferenceLayout() Component.onCompleted: setConferenceLayout()
onConferenceLayoutChanged: { onConferenceLayoutChanged: {
console.log("CallLayout change : " +conferenceLayout) console.log("CallLayout change : " + conferenceLayout);
setConferenceLayout() setConferenceLayout();
} }
Connections { Connections {
target: mainItem.conference? mainItem.conference.core : null target: mainItem.conference ? mainItem.conference.core : null
function onIsScreenSharingEnabledChanged() { function onIsScreenSharingEnabledChanged() {
setConferenceLayout() setConferenceLayout();
} }
function onIsLocalScreenSharingChanged() { function onIsLocalScreenSharingChanged() {
if (mainItem.conference.core.isLocalScreenSharing) { if (mainItem.conference.core.isLocalScreenSharing) {
mainItem.lastConfLayoutBeforeSharing = mainItem.conferenceLayout mainItem.lastConfLayoutBeforeSharing = mainItem.conferenceLayout;
} }
setConferenceLayout() setConferenceLayout();
} }
} }
function setConferenceLayout() { function setConferenceLayout() {
callLayout.sourceComponent = undefined // unload old view before opening the new view to avoid conflicts in Video UI. callLayout.sourceComponent = undefined; // unload old view before opening the new view to avoid conflicts in Video UI.
// If stop sharing screen, reset conference layout to the previous one // If stop sharing screen, reset conference layout to the previous one
if (mainItem.conference && !mainItem.conference.core.isLocalScreenSharing && mainItem.lastConfLayoutBeforeSharing !== -1) { if (mainItem.conference && !mainItem.conference.core.isLocalScreenSharing && mainItem.lastConfLayoutBeforeSharing !==
mainItem.conferenceLayout = mainItem.lastConfLayoutBeforeSharing -1) {
mainItem.lastConfLayoutBeforeSharing = -1 mainItem.conferenceLayout = mainItem.lastConfLayoutBeforeSharing;
mainItem.lastConfLayoutBeforeSharing = -1;
} }
callLayout.sourceComponent = conference callLayout.sourceComponent = conference ? conference.core.isScreenSharingEnabled || (mainItem.conferenceLayout
? conference.core.isScreenSharingEnabled || (mainItem.conferenceLayout == LinphoneEnums.ConferenceLayout.ActiveSpeaker && participantDeviceCount > 1) == LinphoneEnums.ConferenceLayout.ActiveSpeaker && participantDeviceCount > 1)
? activeSpeakerComponent ? activeSpeakerComponent : participantDeviceCount <= 1 ? waitingForOthersComponent : gridComponent :
: participantDeviceCount <= 1 activeSpeakerComponent;
? waitingForOthersComponent
: gridComponent
: activeSpeakerComponent
} }
Text { Text {
@ -71,17 +67,15 @@ Item {
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: Utils.getSizeWithScreenRatio(25) anchors.topMargin: Utils.getSizeWithScreenRatio(25)
z: 1 z: 1
visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error || mainItem.callState === LinphoneEnums.CallState.Released visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error
text: mainItem.conference || mainItem.callState === LinphoneEnums.CallState.Released
text: mainItem.conference ?
//: "Vous avez quitté la conférence" //: "Vous avez quitté la conférence"
? qsTr("meeting_event_conference_destroyed") qsTr("meeting_event_conference_destroyed") : mainItem.callTerminatedByUser ?
: mainItem.callTerminatedByUser
//: "Vous avez terminé l'appel" //: "Vous avez terminé l'appel"
? qsTr("call_ended_by_user") qsTr("call_ended_by_user") : mainItem.callStarted ?
: mainItem.callStarted
//: "Votre correspondant a terminé l'appel" //: "Votre correspondant a terminé l'appel"
? qsTr("call_ended_by_remote") qsTr("call_ended_by_remote") : call && call.core.lastErrorMessage || ""
: call && call.core.lastErrorMessage || ""
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font { font {
pixelSize: Utils.getSizeWithScreenRatio(22) pixelSize: Utils.getSizeWithScreenRatio(22)
@ -89,23 +83,20 @@ Item {
} }
} }
Loader{ Loader {
id: callLayout id: callLayout
anchors.fill: parent anchors.fill: parent
sourceComponent: mainItem.participantDeviceCount === 0 sourceComponent: mainItem.participantDeviceCount === 0 ? waitingForOthersComponent : activeSpeakerComponent
? waitingForOthersComponent
: activeSpeakerComponent
} }
Sticker { Sticker {
id: preview id: preview
qmlName: 'P' qmlName: 'P'
previewEnabled: true previewEnabled: true
visible: (callLayout.sourceComponent === activeSpeakerComponent || callLayout.sourceComponent === waitingForOthersComponent) visible: (callLayout.sourceComponent === activeSpeakerComponent || callLayout.sourceComponent
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingProgress === waitingForOthersComponent) && mainItem.callState !== LinphoneEnums.CallState.OutgoingProgress
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingRinging && mainItem.callState !== LinphoneEnums.CallState.OutgoingRinging && mainItem.callState
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingInit !== LinphoneEnums.CallState.OutgoingInit && !mainItem.conference?.core.isScreenSharingEnabled
&& !mainItem.conference?.core.isScreenSharingEnabled
&& mainItem.participantDeviceCount <= 2 && mainItem.participantDeviceCount <= 2
height: Utils.getSizeWithScreenRatio(180) height: Utils.getSizeWithScreenRatio(180)
width: Utils.getSizeWithScreenRatio(300) width: Utils.getSizeWithScreenRatio(300)
@ -113,7 +104,7 @@ Item {
anchors.bottom: mainItem.bottom anchors.bottom: mainItem.bottom
anchors.rightMargin: Utils.getSizeWithScreenRatio(20) anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10) anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
onVideoEnabledChanged: console.log("Preview : " +videoEnabled + " / " +visible +" / " +mainItem.call) onVideoEnabledChanged: console.log("Preview : " + videoEnabled + " / " + visible + " / " + mainItem.call)
property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress) property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress)
account: accountObj && accountObj.value || null account: accountObj && accountObj.value || null
call: mainItem.call call: mainItem.call
@ -125,19 +116,19 @@ Item {
anchors.fill: parent anchors.fill: parent
movableArea: mainItem movableArea: mainItem
margin: Utils.getSizeWithScreenRatio(10) margin: Utils.getSizeWithScreenRatio(10)
function resetPosition(){ function resetPosition() {
preview.anchors.right = mainItem.right preview.anchors.right = mainItem.right;
preview.anchors.bottom = mainItem.bottom preview.anchors.bottom = mainItem.bottom;
preview.anchors.rightMargin = previewMouseArea.margin preview.anchors.rightMargin = previewMouseArea.margin;
preview.anchors.bottomMargin = previewMouseArea.margin preview.anchors.bottomMargin = previewMouseArea.margin;
} }
onVisibleChanged: if(!visible){ onVisibleChanged: if (!visible) {
resetPosition() resetPosition();
} }
drag.target: preview drag.target: preview
onDraggingChanged: if(dragging) { onDraggingChanged: if (dragging) {
preview.anchors.right = undefined preview.anchors.right = undefined;
preview.anchors.bottom = undefined preview.anchors.bottom = undefined;
} }
onRequestResetPosition: resetPosition() onRequestResetPosition: resetPosition()
} }
@ -178,10 +169,10 @@ Item {
textColor: DefaultStyle.main2_400 textColor: DefaultStyle.main2_400
onClicked: { onClicked: {
if (mainItem.conference) { if (mainItem.conference) {
UtilsCpp.copyToClipboard(mainItem.conference.core.uri) UtilsCpp.copyToClipboard(mainItem.conference.core.uri);
showInformationPopup(qsTr("copied"), showInformationPopup(qsTr("copied"),
//: Le lien de la réunion a été copié dans le presse-papier //: Le lien de la réunion a été copié dans le presse-papier
qsTr("information_popup_meeting_address_copied_to_clipboard"), true) qsTr("information_popup_meeting_address_copied_to_clipboard"), true);
} }
} }
} }
@ -190,19 +181,18 @@ Item {
} }
} }
Component{ Component {
id: activeSpeakerComponent id: activeSpeakerComponent
ActiveSpeakerLayout{ ActiveSpeakerLayout {
id: activeSpeaker id: activeSpeaker
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
call: mainItem.call call: mainItem.call
} }
} }
Component{ Component {
id: gridComponent id: gridComponent
CallGridLayout{ CallGridLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
call: mainItem.call call: mainItem.call

View file

@ -12,99 +12,100 @@ ColumnLayout {
property alias cellWidth: grid.cellWidth property alias cellWidth: grid.cellWidth
property alias margins: grid.margin property alias margins: grid.margin
function appendItem(item){ function appendItem(item) {
mainLayout.delegateModel.model.append(item) mainLayout.delegateModel.model.append(item);
} }
function add(item){ function add(item) {
if( !grid.isLayoutWillChanged()) if (!grid.isLayoutWillChanged())
appendItem(item) appendItem(item);
else else
bufferModels.append(item) bufferModels.append(item);
} }
function remove(index){ function remove(index) {
if(mainLayout.delegateModel.model.count > index) if (mainLayout.delegateModel.model.count > index)
mainLayout.delegateModel.model.remove( index, 1) mainLayout.delegateModel.model.remove(index, 1);
} }
function get(index){ function get(index) {
return mainLayout.delegateModel.model.get(index) return mainLayout.delegateModel.model.get(index);
} }
function tryToAdd(item){ function tryToAdd(item) {
if( !grid.isLayoutWillChanged()) { if (!grid.isLayoutWillChanged()) {
appendItem(item) appendItem(item);
return true return true;
}else } else
return false return false;
} }
function clear(){ function clear() {
if(mainLayout.delegateModel.model.clear) { if (mainLayout.delegateModel.model.clear) {
mainLayout.delegateModel.model.clear() mainLayout.delegateModel.model.clear();
bufferModels.clear() bufferModels.clear();
} }
} }
property int transitionCount: 0
property int transitionCount : 0 property var bufferModels: ListModel {}
property var bufferModels : ListModel{}
onWidthChanged: grid.updateLayout() onWidthChanged: grid.updateLayout()
onHeightChanged: grid.updateLayout() onHeightChanged: grid.updateLayout()
spacing: 0 spacing: 0
GridView{ GridView {
id: grid id: grid
property real margin: Utils.getSizeWithScreenRatio(10) property real margin: Utils.getSizeWithScreenRatio(10)
property int itemCount: model.count ? model.count :( model.length ? model.length : 0) property int itemCount: model.count ? model.count : (model.length ? model.length : 0)
property int columns: 1 property int columns: 1
property int rows: 1 property int rows: 1
function getBestLayout(itemCount){ function getBestLayout(itemCount) {
var availableW = mainLayout.width - grid.margin var availableW = mainLayout.width - grid.margin;
var availableH = mainLayout.height - grid.margin var availableH = mainLayout.height - grid.margin;
var bestSize = 0 var bestSize = 0;
var bestC = 1, bestR = 1 var bestC = 1, bestR = 1;
for(var R = 1 ; R <= itemCount ; ++R){ for (var R = 1; R <= itemCount; ++R) {
for(var C = itemCount ; C >= 1 ; --C){ for (var C = itemCount; C >= 1; --C) {
if( R * C >= itemCount){// This is a good layout candidate if (R * C >= itemCount) {
var estimatedSize = Math.min(availableW / C, availableH / R) // This is a good layout candidate
if(estimatedSize > bestSize // Size is better var estimatedSize = Math.min(availableW / C, availableH / R);
|| (estimatedSize == bestSize && Math.abs(bestR-bestC) > Math.abs(R - C) )){// Stickers are more homogenized if (estimatedSize > bestSize // Size is better
bestSize = estimatedSize || (estimatedSize == bestSize && Math.abs(bestR - bestC) > Math.abs(R - C))) {
bestC = C // Stickers are more homogenized
bestR = R bestSize = estimatedSize;
bestC = C;
bestR = R;
} }
} }
} }
} }
return [bestR, bestC] return [bestR, bestC];
} }
function updateLayout(){ function updateLayout() {
var bestLayout = getBestLayout(itemCount) var bestLayout = getBestLayout(itemCount);
if( rows != bestLayout[0]) if (rows != bestLayout[0])
rows = bestLayout[0] rows = bestLayout[0];
if( columns != bestLayout[1]) if (columns != bestLayout[1])
columns = bestLayout[1] columns = bestLayout[1];
} }
function updateCells(){ function updateCells() {
cellWidth = Math.min(computedWidth, computedHeight) cellWidth = Math.min(computedWidth, computedHeight);
cellHeight = Math.min(computedWidth, computedHeight) cellHeight = Math.min(computedWidth, computedHeight);
} }
onItemCountChanged: updateLayout() onItemCountChanged: updateLayout()
property real computedWidth: (mainLayout.width - grid.margin ) / columns property real computedWidth: (mainLayout.width - grid.margin) / columns
property real computedHeight: (mainLayout.height - grid.margin ) / rows property real computedHeight: (mainLayout.height - grid.margin) / rows
onComputedHeightChanged: Qt.callLater(updateCells) onComputedHeightChanged: Qt.callLater(updateCells)
onComputedWidthChanged: Qt.callLater(updateCells) onComputedWidthChanged: Qt.callLater(updateCells)
cellWidth: Math.min(computedWidth, computedHeight) cellWidth: Math.min(computedWidth, computedHeight)
cellHeight: Math.min(computedWidth, computedHeight) cellHeight: Math.min(computedWidth, computedHeight)
function isLayoutWillChanged(){ function isLayoutWillChanged() {
var bestLayout = getBestLayout(itemCount+1) var bestLayout = getBestLayout(itemCount + 1);
return rows !== bestLayout[0] || columns !== bestLayout[1] return rows !== bestLayout[0] || columns !== bestLayout[1];
} }
Layout.preferredWidth: cellWidth * columns Layout.preferredWidth: cellWidth * columns
@ -112,7 +113,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
interactive: false interactive: false
model: DelegateModel{} model: DelegateModel {}
onCountChanged: grid.updateLayout() onCountChanged: grid.updateLayout()
} }

View file

@ -16,7 +16,7 @@ ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(61) spacing: Utils.getSizeWithScreenRatio(61)
function goToSlide(index) { function goToSlide(index) {
carouselStackLayout.goToSlideAtIndex(index) carouselStackLayout.goToSlideAtIndex(index);
} }
StackLayout { StackLayout {
@ -26,15 +26,18 @@ ColumnLayout {
currentIndex: 0 currentIndex: 0
function goToSlideAtIndex(index) { function goToSlideAtIndex(index) {
carouselStackLayout.previousIndex = carouselStackLayout.currentIndex carouselStackLayout.previousIndex = carouselStackLayout.currentIndex;
carouselStackLayout.currentIndex = index carouselStackLayout.currentIndex = index;
} }
onCurrentIndexChanged: { onCurrentIndexChanged: {
var currentItem = children[currentIndex] var currentItem = children[currentIndex];
var crossFaderAnim = crossFader.createObject(parent, {fadeInTarget: currentItem, mirrored: (previousIndex > currentIndex)}) var crossFaderAnim = crossFader.createObject(parent, {
crossFaderAnim.restart() fadeInTarget: currentItem,
mainItem.currentIndex = currentIndex mirrored: (previousIndex > currentIndex)
});
crossFaderAnim.restart();
mainItem.currentIndex = currentIndex;
} }
Component { Component {
@ -56,7 +59,7 @@ ColumnLayout {
XAnimator { XAnimator {
target: fadeInTarget target: fadeInTarget
from: (mirrored ? -1 : 1) * fadeInTarget.width/3. from: (mirrored ? -1 : 1) * fadeInTarget.width / 3.
to: 0 to: 0
duration: 300 duration: 300
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
@ -73,8 +76,13 @@ ColumnLayout {
radius: Utils.getSizeWithScreenRatio(30) radius: Utils.getSizeWithScreenRatio(30)
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
z: 1 z: 1
x: mainItem.currentIndex >= 0 && mainItem.currentItem ? mainItem.currentItem.x - width/2 + mainItem.currentItem.width/2 : 0 x: mainItem.currentIndex >= 0 && mainItem.currentItem ? mainItem.currentItem.x - width / 2
Behavior on x { NumberAnimation {duration: 100}} + mainItem.currentItem.width / 2 : 0
Behavior on x {
NumberAnimation {
duration: 100
}
}
} }
RowLayout { RowLayout {
id: carouselButtonsLayout id: carouselButtonsLayout
@ -96,12 +104,13 @@ ColumnLayout {
anchors.fill: parent anchors.fill: parent
} }
onClicked: { onClicked: {
mainItem.goToSlide(modelData) mainItem.goToSlide(modelData);
} }
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
} }
} }
} }

View file

@ -19,7 +19,6 @@ GridLayout {
property real maxWidth: Utils.getSizeWithScreenRatio(3 * 105) property real maxWidth: Utils.getSizeWithScreenRatio(3 * 105)
columns: optimalColumns columns: optimalColumns
property int optimalColumns: { property int optimalColumns: {
let maxCols = Math.floor(maxWidth / itemWidth); let maxCols = Math.floor(maxWidth / itemWidth);
let bestCols = 1; let bestCols = 1;
@ -30,10 +29,7 @@ GridLayout {
let rows = Math.ceil(itemCount / cols); let rows = Math.ceil(itemCount / cols);
let emptySlots = cols * rows - itemCount; let emptySlots = cols * rows - itemCount;
if ( if (rows < minRows || (rows === minRows && emptySlots < minEmptySlots)) {
rows < minRows ||
(rows === minRows && emptySlots < minEmptySlots)
) {
bestCols = cols; bestCols = cols;
minRows = rows; minRows = rows;
minEmptySlots = emptySlots; minEmptySlots = emptySlots;

View file

@ -5,7 +5,7 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
@ -48,13 +48,25 @@ ColumnLayout {
radius: Utils.getSizeWithScreenRatio(15) radius: Utils.getSizeWithScreenRatio(15)
borderGradient: Gradient { borderGradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_100 } GradientStop {
GradientStop { position: 1.0; color: DefaultStyle.main2_200 } position: 0.0
color: DefaultStyle.grey_100
}
GradientStop {
position: 1.0
color: DefaultStyle.main2_200
}
} }
gradient: Gradient { gradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_0 } GradientStop {
GradientStop { position: 1.0; color: DefaultStyle.grey_100 } position: 0.0
color: DefaultStyle.grey_0
}
GradientStop {
position: 1.0
color: DefaultStyle.grey_100
}
} }
} }
contentItem: RowLayout { contentItem: RowLayout {
@ -90,7 +102,7 @@ ColumnLayout {
} }
} }
Rectangle { Rectangle {
Layout.fillWidth:true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(79) Layout.preferredHeight: Utils.getSizeWithScreenRatio(79)
color: 'transparent' color: 'transparent'
visible: contact && contact.core.presenceNote.length > 0 && !mainItem.useVerticalLayout visible: contact && contact.core.presenceNote.length > 0 && !mainItem.useVerticalLayout

View file

@ -5,7 +5,7 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Rectangle { Rectangle {

View file

@ -6,7 +6,7 @@ import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope { FocusScope {
id: mainItem id: mainItem
@ -16,7 +16,7 @@ FocusScope {
property string startGroupButtonText property string startGroupButtonText
property bool startGroupButtonVisible: true property bool startGroupButtonVisible: true
property NumericPadPopup numPadPopup property NumericPadPopup numPadPopup
signal groupCreationRequested() signal groupCreationRequested
signal contactClicked(FriendGui contact) signal contactClicked(FriendGui contact)
clip: true clip: true
property alias topContent: topLayout.data property alias topContent: topLayout.data
@ -33,7 +33,8 @@ FocusScope {
} }
ColumnLayout { ColumnLayout {
onVisibleChanged: if (!visible && mainItem.numPadPopup) mainItem.numPadPopup.close() onVisibleChanged: if (!visible && mainItem.numPadPopup)
mainItem.numPadPopup.close()
spacing: Utils.getSizeWithScreenRatio(38) spacing: Utils.getSizeWithScreenRatio(38)
SearchBar { SearchBar {
id: searchBar id: searchBar
@ -65,8 +66,14 @@ FocusScope {
radius: height / 2 radius: height / 2
gradient: Gradient { gradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.main2_100} GradientStop {
GradientStop { position: 1.0; color: DefaultStyle.grey_0} position: 0.0
color: DefaultStyle.main2_100
}
GradientStop {
position: 1.0
color: DefaultStyle.grey_0
}
} }
// Black border for keyboard navigation // Black border for keyboard navigation
border.color: DefaultStyle.main2_900 border.color: DefaultStyle.main2_900
@ -109,14 +116,14 @@ FocusScope {
} }
} }
} }
AllContactListView{ AllContactListView {
id: contactList id: contactList
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
showContactMenu: false showContactMenu: false
searchBarText: searchBar.text searchBarText: searchBar.text
onContactSelected: (contact) => { onContactSelected: contact => {
mainItem.contactClicked(contact) mainItem.contactClicked(contact);
} }
} }
} }

View file

@ -5,7 +5,7 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {

View file

@ -5,7 +5,7 @@ import Linphone
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope{ FocusScope {
id: mainItem id: mainItem
property alias contentItem: contentItem.data property alias contentItem: contentItem.data
property string label: "" property string label: ""
@ -21,24 +21,23 @@ FocusScope{
implicitHeight: layout.implicitHeight implicitHeight: layout.implicitHeight
function clearErrorText() { function clearErrorText() {
errorText.clear() errorText.clear();
} }
onErrorMessageChanged: if (errorMessage.length > 0) { onErrorMessageChanged: if (errorMessage.length > 0) {
var item = mainItem var item = mainItem;
do { do {
var parentItem = item.parent var parentItem = item.parent;
if (parentItem.contentItem) { if (parentItem.contentItem) {
var itemPosInParent = mainItem.mapToItem(parentItem.contentItem, mainItem.x, mainItem.y) var itemPosInParent = mainItem.mapToItem(parentItem.contentItem, mainItem.x, mainItem.y);
if (parentItem.contentY > itemPosInParent.y) { if (parentItem.contentY > itemPosInParent.y) {
parentItem.contentY = itemPosInParent.y; parentItem.contentY = itemPosInParent.y;
} } else if (parentItem.contentY + parentItem.height < itemPosInParent.y + mainItem.height) {
else if (parentItem.contentY+parentItem.height < itemPosInParent.y+mainItem.height) {
parentItem.contentY = itemPosInParent.y + mainItem.height - height; parentItem.contentY = itemPosInParent.y + mainItem.height - height;
} }
} }
item = parentItem item = parentItem;
} while(item.parent != undefined && parentItem.contentItem === undefined) } while (item.parent != undefined && parentItem.contentItem === undefined)
} }
ColumnLayout { ColumnLayout {
@ -63,7 +62,9 @@ FocusScope{
weight: Typography.p2.weight weight: Typography.p2.weight
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
PopupButton { PopupButton {
visible: mainItem.tooltip !== "" visible: mainItem.tooltip !== ""
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
@ -99,6 +100,5 @@ FocusScope{
color: DefaultStyle.danger_500_main color: DefaultStyle.danger_500_main
} }
} }
} }
} }

View file

@ -6,7 +6,7 @@ import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
FocusScope { FocusScope {
@ -17,8 +17,8 @@ FocusScope {
property string formTitle property string formTitle
property string createGroupButtonText property string createGroupButtonText
property int selectedParticipantsCount property int selectedParticipantsCount
signal returnRequested() signal returnRequested
signal groupCreationRequested() signal groupCreationRequested
ColumnLayout { ColumnLayout {
spacing: 0 spacing: 0
@ -39,7 +39,7 @@ FocusScope {
//: Return //: Return
Accessible.name: qsTr("return_accessible_name") Accessible.name: qsTr("return_accessible_name")
onClicked: { onClicked: {
mainItem.returnRequested() mainItem.returnRequested();
} }
} }
Text { Text {
@ -62,7 +62,7 @@ FocusScope {
KeyNavigation.left: backGroupCallButton KeyNavigation.left: backGroupCallButton
KeyNavigation.right: backGroupCallButton KeyNavigation.right: backGroupCallButton
onClicked: { onClicked: {
mainItem.groupCreationRequested() mainItem.groupCreationRequested();
} }
} }
} }
@ -93,7 +93,6 @@ FocusScope {
Layout.topMargin: Utils.getSizeWithScreenRatio(15) Layout.topMargin: Utils.getSizeWithScreenRatio(15)
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
focus: true focus: true
} }
} }
} }

View file

@ -49,7 +49,7 @@ ColumnLayout {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
rightPanelContent.forceActiveFocus() rightPanelContent.forceActiveFocus();
} }
} }
} }

View file

@ -4,14 +4,12 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import CustomControls 1.0 import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.TabBar { Control.TabBar {
id: mainItem id: mainItem
property var model property var model
readonly property int originX: count > 0 readonly property int originX: count > 0 ? itemAt(0).x : 0
? itemAt(0).x
: 0
property real pixelSize: Typography.h3.pixelSize property real pixelSize: Typography.h3.pixelSize
property real textWeight: Typography.h3.weight property real textWeight: Typography.h3.weight
property int capitalization: Font.Capitalize property int capitalization: Font.Capitalize
@ -61,9 +59,9 @@ Control.TabBar {
delay: 1000 delay: 1000
text: modelData text: modelData
} }
MouseArea{ MouseArea {
anchors.fill: parent anchors.fill: parent
cursorShape: tabButton.hovered ? Qt.PointingHandCursor: Qt.ArrowCursor cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
} }
@ -89,7 +87,7 @@ Control.TabBar {
shadowBlur: 0.1 shadowBlur: 0.1
shadowOpacity: tabButton.shadowEnabled ? 0.5 : 0.0 shadowOpacity: tabButton.shadowEnabled ? 0.5 : 0.0
} }
Rectangle{ Rectangle {
id: borderBackground id: borderBackground
visible: tabButton.keyboardFocus visible: tabButton.keyboardFocus
height: tabButton.height height: tabButton.height

View file

@ -5,7 +5,7 @@ import QtQuick.Effects
import Linphone import Linphone
import SettingsCpp import SettingsCpp
import CustomControls 1.0 import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.TabBar { Control.TabBar {
id: mainItem id: mainItem
@ -19,31 +19,33 @@ Control.TabBar {
property int visibleCount: 0 property int visibleCount: 0
signal enterPressed() signal enterPressed
signal spacePressed() signal spacePressed
// Call it after model is ready. If done before, Repeater will not be updated // Call it after model is ready. If done before, Repeater will not be updated
function initButtons(){ function initButtons() {
actionsRepeater.model = mainItem.model actionsRepeater.model = mainItem.model;
} }
function updateVisibleCount() { function updateVisibleCount() {
mainItem.visibleCount = 0 mainItem.visibleCount = 0;
contentChildren.forEach(child => { contentChildren.forEach(child => {
if (child.visible) mainItem.visibleCount = mainItem.visibleCount + 1 if (child.visible)
}) mainItem.visibleCount = mainItem.visibleCount + 1;
});
} }
onDefaultAccountChanged: { onDefaultAccountChanged: {
if (defaultAccount) defaultAccount.core?.lRefreshNotifications() if (defaultAccount)
defaultAccount.core?.lRefreshNotifications();
} }
Connections { Connections {
target: SettingsCpp target: SettingsCpp
function onDisableMeetingsFeatureChanged() { function onDisableMeetingsFeatureChanged() {
initButtons() initButtons();
} }
function onDisableChatFeatureChanged() { function onDisableChatFeatureChanged() {
initButtons() initButtons();
} }
} }
@ -76,14 +78,14 @@ Control.TabBar {
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
width: parent.width/2 width: parent.width / 2
height: parent.height/2 height: parent.height / 2
} }
Rectangle { Rectangle {
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
y: parent.y + parent.height/2 y: parent.y + parent.height / 2
width: parent.width width: parent.width
height: parent.height/2 height: parent.height / 2
} }
} }
@ -102,13 +104,8 @@ Control.TabBar {
focusPolicy: Qt.StrongFocus focusPolicy: Qt.StrongFocus
activeFocusOnTab: true activeFocusOnTab: true
UnreadNotification { UnreadNotification {
unread: !defaultAccount unread: !defaultAccount ? -1 : index === 0 ? defaultAccount.core?.unreadCallNotifications || -1 : index === 2
? -1 ? defaultAccount.core?.unreadMessageNotifications || -1 : 0
: index === 0
? defaultAccount.core?.unreadCallNotifications || -1
: index === 2
? defaultAccount.core?.unreadMessageNotifications || -1
: 0
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(15) anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
anchors.top: parent.top anchors.top: parent.top
@ -118,7 +115,7 @@ Control.TabBar {
cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
} }
background: Rectangle{ background: Rectangle {
// Black border for keyboard navigation // Black border for keyboard navigation
visible: tabButton.keyboardFocus visible: tabButton.keyboardFocus
color: "transparent" color: "transparent"
@ -130,7 +127,8 @@ Control.TabBar {
contentItem: ColumnLayout { contentItem: ColumnLayout {
EffectImage { EffectImage {
id: buttonIcon id: buttonIcon
property real buttonSize: Utils.getSizeWithScreenRatio(mainItem.currentIndex !== index && tabButton.hovered ? 26 : 24) property real buttonSize: Utils.getSizeWithScreenRatio(mainItem.currentIndex !== index && tabButton.hovered ? 26 :
24)
imageSource: mainItem.currentIndex === index ? modelData.selectedIcon : modelData.icon imageSource: mainItem.currentIndex === index ? modelData.selectedIcon : modelData.icon
Layout.preferredWidth: buttonSize Layout.preferredWidth: buttonSize
Layout.preferredHeight: buttonSize Layout.preferredHeight: buttonSize
@ -138,18 +136,16 @@ Control.TabBar {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.grey_0 colorizationColor: DefaultStyle.grey_0
useColor: !modelData.colored useColor: !modelData.colored
onStatusChanged: if (status === Image.Ready && !buttonText.visible) buttonText.visible = true onStatusChanged: if (status === Image.Ready && !buttonText.visible)
buttonText.visible = true
} }
Text { Text {
id: buttonText id: buttonText
text: modelData.label text: modelData.label
visible: false visible: false
font { font {
weight: mainItem.currentIndex === index weight: mainItem.currentIndex === index ? Utils.getSizeWithScreenRatio(800) : tabButton.hovered
? Utils.getSizeWithScreenRatio(800) ? Utils.getSizeWithScreenRatio(600) : Utils.getSizeWithScreenRatio(400)
: tabButton.hovered
? Utils.getSizeWithScreenRatio(600)
: Utils.getSizeWithScreenRatio(400)
pixelSize: Utils.getSizeWithScreenRatio(11) pixelSize: Utils.getSizeWithScreenRatio(11)
} }
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
@ -166,29 +162,29 @@ Control.TabBar {
text: modelData.label text: modelData.label
font: buttonText.font font: buttonText.font
Component.onCompleted: { Component.onCompleted: {
font.weight = Utils.getSizeWithScreenRatio(800) font.weight = Utils.getSizeWithScreenRatio(800);
mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize) mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize);
} }
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
mainItem.enterPressed() mainItem.enterPressed();
} else if(event.key === Qt.Key_Space){ } else if (event.key === Qt.Key_Space) {
mainItem.spacePressed() mainItem.spacePressed();
} else if(event.key === Qt.Key_Down){ } else if (event.key === Qt.Key_Down) {
event.accepted = true; event.accepted = true;
if(TabBar.index >= mainItem.visibleCount - 1) if (TabBar.index >= mainItem.visibleCount - 1)
return; return;
tabButton.nextItemInFocusChain(true).forceActiveFocus(Qt.TabFocusReason) tabButton.nextItemInFocusChain(true).forceActiveFocus(Qt.TabFocusReason);
} else if(event.key === Qt.Key_Up){ } else if (event.key === Qt.Key_Up) {
event.accepted = true; event.accepted = true;
if(TabBar.index <= 0) if (TabBar.index <= 0)
return; return;
tabButton.nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason) tabButton.nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason);
} }
} }
onClicked: { onClicked: {
mainItem.setCurrentIndex(TabBar.index) mainItem.setCurrentIndex(TabBar.index);
} }
} }
} }

View file

@ -25,7 +25,7 @@ ListView {
signal resultsReceived signal resultsReceived
onResultsReceived: { onResultsReceived: {
loading = false loading = false;
} }
model: CallHistoryProxy { model: CallHistoryProxy {
@ -37,7 +37,7 @@ ListView {
displayItemsStep: 3 * initialDisplayItems / 2 displayItemsStep: 3 * initialDisplayItems / 2
onModelAboutToBeReset: loading = true onModelAboutToBeReset: loading = true
onModelReset: { onModelReset: {
mainItem.resultsReceived() mainItem.resultsReceived();
} }
} }
flickDeceleration: 10000 flickDeceleration: 10000
@ -45,70 +45,73 @@ ListView {
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key == Qt.Key_Escape) { if (event.key == Qt.Key_Escape) {
console.log("Back") console.log("Back");
searchBar.forceActiveFocus(Qt.BacktabFocusReason) searchBar.forceActiveFocus(Qt.BacktabFocusReason);
event.accepted = true event.accepted = true;
} } else
// Re-implement key navigation to have Qt.TabFocusReason and Qt.BacktabFocusReason instead of Qt.OtherFocusReason when using arrows to navigate in listView // Re-implement key navigation to have Qt.TabFocusReason and Qt.BacktabFocusReason instead of Qt.OtherFocusReason when using arrows to navigate in listView
else if (event.key === Qt.Key_Up) { if (event.key === Qt.Key_Up) {
if(currentIndex === 0){ if (currentIndex === 0) {
searchBar.forceActiveFocus(Qt.BacktabFocusReason) searchBar.forceActiveFocus(Qt.BacktabFocusReason);
lastFocusByNavigationKeyboard = false lastFocusByNavigationKeyboard = false;
}else{ } else {
decrementCurrentIndex() decrementCurrentIndex();
currentItem.forceActiveFocus(Qt.BacktabFocusReason) // The focusReason is created by QT later, need to create a workaround currentItem.forceActiveFocus(
lastFocusByNavigationKeyboard = true Qt.BacktabFocusReason); // The focusReason is created by QT later, need to create a workaround
lastFocusByNavigationKeyboard = true;
} }
event.accepted = true event.accepted = true;
} } else if (event.key === Qt.Key_Down) {
else if(event.key === Qt.Key_Down){ incrementCurrentIndex();
incrementCurrentIndex() currentItem.forceActiveFocus(
currentItem.forceActiveFocus(Qt.TabFocusReason) // The focusReason is created by QT later, need to create a workaround Qt.TabFocusReason); // The focusReason is created by QT later, need to create a workaround
lastFocusByNavigationKeyboard = true lastFocusByNavigationKeyboard = true;
event.accepted = true event.accepted = true;
} }
} }
Component.onCompleted: cacheBuffer = Math.max(mainItem.height,0) //contentHeight>0 ? contentHeight : 0// cache all items Component.onCompleted: cacheBuffer = Math.max(mainItem.height,
0) //contentHeight>0 ? contentHeight : 0// cache all items
// remove binding loop // remove binding loop
// onContentHeightChanged: Qt.callLater(function () { // onContentHeightChanged: Qt.callLater(function () {
// if (mainItem) // if (mainItem)
// mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0 // mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0
// }) // })
onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0) currentIndex = 0 onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0)
currentIndex = 0
onCountChanged: { onCountChanged: {
if (currentIndex < 0 && count > 0) { if (currentIndex < 0 && count > 0) {
mainItem.currentIndex = 0 // Select first item after loading model mainItem.currentIndex = 0; // Select first item after loading model
} }
if (atYBeginning) if (atYBeginning)
positionViewAtBeginning() // Stay at beginning positionViewAtBeginning(); // Stay at beginning
} }
Connections { Connections {
target: deleteHistoryPopup target: deleteHistoryPopup
function onAccepted() { function onAccepted() {
mainItem.model.removeAllEntries() mainItem.model.removeAllEntries();
} }
} }
onAtYEndChanged: { onAtYEndChanged: {
if (atYEnd && count > 0) { if (atYEnd && count > 0) {
callHistoryProxy.displayMore() callHistoryProxy.displayMore();
} }
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
function moveToCurrentItem() { function moveToCurrentItem() {
if (mainItem.currentIndex >= 0) if (mainItem.currentIndex >= 0)
Utils.updatePosition(mainItem, mainItem) Utils.updatePosition(mainItem, mainItem);
} }
onCurrentItemChanged: { onCurrentItemChanged: {
moveToCurrentItem() moveToCurrentItem();
} }
// Update position only if we are moving to current item and its position is changing. // Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) { on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem() moveToCurrentItem();
} }
Behavior on contentY { Behavior on contentY {
NumberAnimation { NumberAnimation {
@ -173,29 +176,21 @@ ListView {
spacing: Utils.getSizeWithScreenRatio(6) spacing: Utils.getSizeWithScreenRatio(6)
EffectImage { EffectImage {
id: statusIcon id: statusIcon
imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted
=== LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow :
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow : modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status
colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status
=== LinphoneEnums.CallStatus.Declined === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted
|| modelData.core.status || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main :
=== LinphoneEnums.CallStatus.DeclinedElsewhere modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main
|| modelData.core.status
=== LinphoneEnums.CallStatus.Aborted
|| modelData.core.status
=== LinphoneEnums.CallStatus.EarlyAborted
|| modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main
Layout.preferredWidth: Utils.getSizeWithScreenRatio(12) Layout.preferredWidth: Utils.getSizeWithScreenRatio(12)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(12) Layout.preferredHeight: Utils.getSizeWithScreenRatio(12)
transform: Rotation { transform: Rotation {
angle: modelData.core.isOutgoing angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined
&& (modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status
=== LinphoneEnums.CallStatus.DeclinedElsewhere
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|| modelData.core.status
=== LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
origin { origin {
x: statusIcon.width / 2 x: statusIcon.width / 2
@ -226,25 +221,24 @@ ListView {
Accessible.name: qsTr("call_name_accessible_button").arg(historyAvatar.displayNameVal) Accessible.name: qsTr("call_name_accessible_button").arg(historyAvatar.displayNameVal)
onClicked: { onClicked: {
if (modelData.core.isConference) { if (modelData.core.isConference) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow() var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference( callsWindow.setupConference(modelData.core.conferenceInfo);
modelData.core.conferenceInfo) UtilsCpp.smartShowWindow(callsWindow);
UtilsCpp.smartShowWindow(callsWindow)
} else { } else {
UtilsCpp.createCall(modelData.core.remoteAddress) UtilsCpp.createCall(modelData.core.remoteAddress);
} }
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key === Qt.Key_Left){ if (event.key === Qt.Key_Left) {
backgroundMouseArea.forceActiveFocus(Qt.BacktabFocusReason) backgroundMouseArea.forceActiveFocus(Qt.BacktabFocusReason);
lastFocusByNavigationKeyboard = true; lastFocusByNavigationKeyboard = true;
} }
} }
onActiveFocusChanged: { onActiveFocusChanged: {
if (!activeFocus) { if (!activeFocus) {
console.log("Unfocus button"); console.log("Unfocus button");
callButton.focus = false // Make sure to be unfocusable (could be when called by forceActiveFocus) callButton.focus = false; // Make sure to be unfocusable (could be when called by forceActiveFocus)
backgroundMouseArea.focus = true backgroundMouseArea.focus = true;
} }
} }
} }
@ -259,38 +253,36 @@ ListView {
//: %1 - %2 - %3 - right arrow for call-back button //: %1 - %2 - %3 - right arrow for call-back button
Accessible.name: qsTr("call_history_entry_accessible_name").arg( Accessible.name: qsTr("call_history_entry_accessible_name").arg(
//: "Appel manqué" //: "Appel manqué"
modelData.core.status === LinphoneEnums.CallStatus.Missed ? qsTr("notification_missed_call_title") modelData.core.status === LinphoneEnums.CallStatus.Missed ? qsTr("notification_missed_call_title") :
//: "Appel sortant" //: "Appel sortant"
: modelData.core.isOutgoing ? qsTr("call_outgoing") modelData.core.isOutgoing ? qsTr("call_outgoing") :
//: "Appel entrant" //: "Appel entrant"
: qsTr("call_audio_incoming") qsTr("call_audio_incoming")).arg(historyAvatar.displayNameVal).arg(UtilsCpp.formatDate(
).arg(historyAvatar.displayNameVal).arg(UtilsCpp.formatDate(modelData.core.date)) modelData.core.date))
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) if (containsMouse)
mainItem.lastMouseContainsIndex = index mainItem.lastMouseContainsIndex = index;
else if (mainItem.lastMouseContainsIndex == index) else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1 mainItem.lastMouseContainsIndex = -1;
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
opacity: 0.7 opacity: 0.7
radius: Utils.getSizeWithScreenRatio(8) radius: Utils.getSizeWithScreenRatio(8)
color: mainItem.currentIndex color: mainItem.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
=== index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
border.color: backgroundMouseArea.keyboardFocus ? DefaultStyle.main2_900 : "transparent" border.color: backgroundMouseArea.keyboardFocus ? DefaultStyle.main2_900 : "transparent"
border.width: backgroundMouseArea.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0 border.width: backgroundMouseArea.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0
visible: mainItem.lastMouseContainsIndex === index visible: mainItem.lastMouseContainsIndex === index || mainItem.currentIndex === index
|| mainItem.currentIndex === index
} }
onPressed: { onPressed: {
mainItem.currentIndex = model.index mainItem.currentIndex = model.index;
mainItem.forceActiveFocus() mainItem.forceActiveFocus();
mainItem.lastFocusByNavigationKeyboard = false mainItem.lastFocusByNavigationKeyboard = false;
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if(event.key === Qt.Key_Right){ if (event.key === Qt.Key_Right) {
callButton.forceActiveFocus(Qt.TabFocusReason) callButton.forceActiveFocus(Qt.TabFocusReason);
} }
} }
} }

View file

@ -6,7 +6,7 @@ import Linphone
import QtQml import QtQml
import SettingsCpp import SettingsCpp
import UtilsCpp 1.0 import UtilsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView { ListView {
@ -33,11 +33,8 @@ ListView {
width: mainItem.width width: mainItem.width
height: Utils.getSizeWithScreenRatio(45) height: Utils.getSizeWithScreenRatio(45)
property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress) property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress)
property var callName : (modelData && !SettingsCpp.disableMeetingsFeature && modelData.core.isConference) property var callName: (modelData && !SettingsCpp.disableMeetingsFeature && modelData.core.isConference)
? modelData.core.conference.core.subject ? modelData.core.conference.core.subject : remoteNameObj ? remoteNameObj.value : ""
: remoteNameObj
? remoteNameObj.value
: ""
Avatar { Avatar {
id: delegateAvatar id: delegateAvatar
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
@ -59,41 +56,41 @@ ListView {
Text { Text {
id: callStateText id: callStateText
//: "Réunion //: "Réunion
property string type: modelData.core.isConference ? qsTr("meeting") property string type: modelData.core.isConference ? qsTr("meeting") :
//: "Appel" //: "Appel"
: qsTr("call") qsTr("call")
Layout.rightMargin: Utils.getSizeWithScreenRatio(2) Layout.rightMargin: Utils.getSizeWithScreenRatio(2)
text: modelData.core.state === LinphoneEnums.CallState.Paused text: modelData.core.state === LinphoneEnums.CallState.Paused || modelData.core.state
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote === LinphoneEnums.CallState.PausedByRemote ?
//: "%1 en pause" //: "%1 en pause"
? qsTr("paused_call_or_meeting").arg(type) qsTr("paused_call_or_meeting").arg(type) :
//: "%1 en cours" //: "%1 en cours"
: qsTr("ongoing_call_or_meeting").arg(type) qsTr("ongoing_call_or_meeting").arg(type)
font { font {
pixelSize: Utils.getSizeWithScreenRatio(12) pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
Button { Button {
id: transferButton id: transferButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
visible: mainItem.isTransferList visible: mainItem.isTransferList && (mainItem.currentRemoteAddress !== modelData.core.remoteAddress)
&& (mainItem.currentRemoteAddress !== modelData.core.remoteAddress) && modelData.core.state !== LinphoneEnums.CallState.IncomingReceived && modelData.core.state
&& modelData.core.state !== LinphoneEnums.CallState.IncomingReceived !== LinphoneEnums.CallState.PushIncomingReceived && modelData.core.state !== LinphoneEnums.CallState.OutgoingInit
&& modelData.core.state !== LinphoneEnums.CallState.PushIncomingReceived && modelData.core.state !== LinphoneEnums.CallState.OutgoingProgress && modelData.core.state
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingInit !== LinphoneEnums.CallState.OutgoingRinging && modelData.core.state
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingProgress !== LinphoneEnums.CallState.OutgoingEarlyMedia && modelData.core.state
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingRinging !== LinphoneEnums.CallState.IncomingEarlyMedia
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingEarlyMedia
&& modelData.core.state !== LinphoneEnums.CallState.IncomingEarlyMedia
icon.source: AppIcons.transferCall icon.source: AppIcons.transferCall
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
onClicked: { onClicked: {
mainItem.transferCallToAnotherRequested(modelData) mainItem.transferCallToAnotherRequested(modelData);
} }
//: Transfer call %1 //: Transfer call %1
Accessible.name: qsTr("transfer_call_name_accessible_name").arg(callInformationItem.callName) Accessible.name: qsTr("transfer_call_name_accessible_name").arg(callInformationItem.callName)
@ -126,8 +123,7 @@ ListView {
//: Resume %1 call //: Resume %1 call
qsTr("resume_call_name_accessible_name") : qsTr("resume_call_name_accessible_name") :
//: Pause %1 call //: Pause %1 call
qsTr("pause_call_name_accessible_name") qsTr("pause_call_name_accessible_name")).arg(callInformationItem.callName)
).arg(callInformationItem.callName)
} }
SmallButton { SmallButton {
id: endCallButton id: endCallButton
@ -140,8 +136,8 @@ ListView {
icon.width: Utils.getSizeWithScreenRatio(18) icon.width: Utils.getSizeWithScreenRatio(18)
icon.height: Utils.getSizeWithScreenRatio(18) icon.height: Utils.getSizeWithScreenRatio(18)
onClicked: { onClicked: {
mainWindow.callTerminatedByUser = true mainWindow.callTerminatedByUser = true;
mainWindow.endCall(modelData) mainWindow.endCall(modelData);
} }
TextMetrics { TextMetrics {
id: endMeter id: endMeter

View file

@ -142,5 +142,7 @@ ColumnLayout {
} }
} }
} }
Item{Layout.fillHeight: true} Item {
Layout.fillHeight: true
}
} }

View file

@ -4,11 +4,10 @@ import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// ============================================================================= // =============================================================================
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Separated file to show a single image bigger in chat message // Separated file to show a single image bigger in chat message
// The FileView file does not allow that as it is a Loader and the image // The FileView file does not allow that as it is a Loader and the image
@ -23,7 +22,7 @@ AnimatedImage {
mipmap: false//SettingsModel.mipmapEnabled mipmap: false//SettingsModel.mipmapEnabled
autoTransform: true autoTransform: true
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
source: contentGui && UtilsCpp.isAnimatedImage(contentGui.core.filePath) ? ('file:/'+ contentGui.core.filePath) : "" source: contentGui && UtilsCpp.isAnimatedImage(contentGui.core.filePath) ? ('file:/' + contentGui.core.filePath) : ""
// sourceSize.width: implicitWidth // sourceSize.width: implicitWidth
// sourceSize.height: implicitHeight // sourceSize.height: implicitHeight
states: State { states: State {
@ -38,19 +37,21 @@ AnimatedImage {
// Changing cursor in MouseArea seems not to work with the Loader // Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case // Use override cursor for this case
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor) if (containsMouse)
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
mainItem.state = containsMouse ? 'hovered' : '' else
UtilsCpp.restoreGlobalCursor();
mainItem.state = containsMouse ? 'hovered' : '';
} }
onPressed: (mouse) => { onPressed: mouse => {
mouse.accepted = true mouse.accepted = true;
// if(SettingsModel.isVfsEncrypted){ // if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), { // window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui, // contentGui: mainItem.contentGui,
// }, function (status) { // }, function (status) {
// }) // })
// }else // }else
mainItem.contentGui.core.lOpenFile() mainItem.contentGui.core.lOpenFile();
} }
} }
} }

View file

@ -13,72 +13,73 @@ Item {
// used for creating a voice recording message // used for creating a voice recording message
property var chatMessageObj property var chatMessageObj
property ChatMessageGui chatMessage: chatMessageObj && chatMessageObj.value || null property ChatMessageGui chatMessage: chatMessageObj && chatMessageObj.value || null
property bool isPlaying : soudPlayerLoader.item && soudPlayerLoader.item.core.playbackState === LinphoneEnums.PlaybackState.PlayingState property bool isPlaying: soudPlayerLoader.item && soudPlayerLoader.item.core.playbackState
=== LinphoneEnums.PlaybackState.PlayingState
onIsPlayingChanged: isPlaying ? mediaProgressBar.resume() : mediaProgressBar.stop() onIsPlayingChanged: isPlaying ? mediaProgressBar.resume() : mediaProgressBar.stop()
property bool recording: false property bool recording: false
property RecorderGui recorderGui: recorderLoader.item || null property RecorderGui recorderGui: recorderLoader.item || null
signal voiceRecordingMessageCreationRequested(RecorderGui recorderGui) signal voiceRecordingMessageCreationRequested(RecorderGui recorderGui)
signal stopRecording() signal stopRecording
signal endOfFileReached() signal endOfFileReached
// auto play if follows a voice recording // auto play if follows a voice recording
function requestPlaying() { function requestPlaying() {
if(soudPlayerLoader.item) { if (soudPlayerLoader.item) {
soudPlayerLoader.item.play(true) soudPlayerLoader.item.play(true);
} }
} }
function createVoiceMessageInChat(chat) { function createVoiceMessageInChat(chat) {
if (recorderLoader.item) { if (recorderLoader.item) {
mainItem.chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderLoader.item, chat) mainItem.chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderLoader.item, chat);
} else { } else {
//: Error //: Error
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: Failed to create voice message : error in recorder //: Failed to create voice message : error in recorder
qsTr("information_popup_voice_message_error_message"), false) qsTr("information_popup_voice_message_error_message"), false);
} }
} }
Loader { Loader {
id: soudPlayerLoader id: soudPlayerLoader
property int duration: mainItem.chatMessageContentGui property int duration: mainItem.chatMessageContentGui ? mainItem.chatMessageContentGui.core.fileDuration : item
? mainItem.chatMessageContentGui.core.fileDuration ? item.core.duration : 0
: item
? item.core.duration
: 0
property int position: item?.core.position || 0 property int position: item?.core.position || 0
active: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.isVoiceRecording active: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.isVoiceRecording
sourceComponent: SoundPlayerGui { sourceComponent: SoundPlayerGui {
id: soundPlayerGui id: soundPlayerGui
source: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.filePath source: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.filePath
function play(restartIfPlaying){ function play(restartIfPlaying) {
if(mainItem.isPlaying && (restartIfPlaying === undefined || !restartIfPlaying)){// Pause the play if (mainItem.isPlaying && (restartIfPlaying === undefined || !restartIfPlaying)) {
soundPlayerGui.core.lPause() // Pause the play
} else if (restartIfPlaying) { //Play from scratch soundPlayerGui.core.lPause();
soundPlayerGui.core.lRestart() } else if (restartIfPlaying) {
} else {// Play the audio //Play from scratch
soundPlayerGui.core.lPlay() soundPlayerGui.core.lRestart();
} else {
// Play the audio
soundPlayerGui.core.lPlay();
} }
} }
onStopped: { onStopped: {
mediaProgressBar.value = 101 mediaProgressBar.value = 101;
} }
onPositionChanged: { onPositionChanged: {
mediaProgressBar.progressPosition = soudPlayerLoader.position mediaProgressBar.progressPosition = soudPlayerLoader.position;
mediaProgressBar.value = 100 * ( mediaProgressBar.progressPosition / soudPlayerLoader.duration) mediaProgressBar.value = 100 * (mediaProgressBar.progressPosition / soudPlayerLoader.duration);
} }
onSourceChanged: if (source != "") { onSourceChanged: if (source != "") {
core.lOpen() // Open the file and allow seeking core.lOpen(); // Open the file and allow seeking
mediaProgressBar.value = 0 mediaProgressBar.value = 0;
mediaProgressBar.refresh() mediaProgressBar.refresh();
} }
onErrorChanged: (error) => { onErrorChanged: error => {
//: Error //: Error
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), error, false) UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), error, false);
} }
onEofReached: { onEofReached: {
mainItem.endOfFileReached() mainItem.endOfFileReached();
} }
} }
} }
@ -93,56 +94,54 @@ Item {
Connections { Connections {
target: mainItem target: mainItem
function onStopRecording() { function onStopRecording() {
recorderLoader.item.core.lStop() recorderLoader.item.core.lStop();
} }
} }
sourceComponent: RecorderGui { sourceComponent: RecorderGui {
id: recorderGui id: recorderGui
onReady: core.lStart() onReady: core.lStart()
onStateChanged: (state) => { onStateChanged: state => {
if (state === LinphoneEnums.RecorderState.Running) mediaProgressBar.start() if (state === LinphoneEnums.RecorderState.Running)
mediaProgressBar.start();
if (state === LinphoneEnums.RecorderState.Closed) { if (state === LinphoneEnums.RecorderState.Closed) {
mediaProgressBar.stop() mediaProgressBar.stop();
mainItem.voiceRecordingMessageCreationRequested(recorderGui) mainItem.voiceRecordingMessageCreationRequested(recorderGui);
} }
} }
} }
} }
MediaProgressBar{ MediaProgressBar {
id: mediaProgressBar id: mediaProgressBar
anchors.fill: parent anchors.fill: parent
progressDuration: soudPlayerLoader.active progressDuration: soudPlayerLoader.active ? soudPlayerLoader.duration : recorderLoader ? recorderLoader.duration :
? soudPlayerLoader.duration chatMessageContentGui.core.fileDuration
: recorderLoader
? recorderLoader.duration
: chatMessageContentGui.core.fileDuration
progressPosition: 0 progressPosition: 0
value: 0 value: 0
recording: recorderLoader.state === LinphoneEnums.RecorderState.Running recording: recorderLoader.state === LinphoneEnums.RecorderState.Running
function refresh(){ function refresh() {
if(soudPlayerLoader.item){ if (soudPlayerLoader.item) {
soudPlayerLoader.item.core.lRefreshPosition() soudPlayerLoader.item.core.lRefreshPosition();
} else if (recorderLoader.item) { } else if (recorderLoader.item) {
recorderLoader.item.core.lRefresh() recorderLoader.item.core.lRefresh();
} }
} }
onEndReached:{ onEndReached: {
if(soudPlayerLoader.item) if (soudPlayerLoader.item)
soudPlayerLoader.item.core.lStop() soudPlayerLoader.item.core.lStop();
} }
onPlayStopButtonToggled: { onPlayStopButtonToggled: {
if(soudPlayerLoader.item) { if (soudPlayerLoader.item) {
soudPlayerLoader.item.play() soudPlayerLoader.item.play();
} else if (recorderLoader.item) { } else if (recorderLoader.item) {
recorderLoader.item.core.lStop() recorderLoader.item.core.lStop();
} }
} }
onRefreshPositionRequested: refresh() onRefreshPositionRequested: refresh()
onSeekRequested: (ms) => { onSeekRequested: ms => {
if(soudPlayerLoader.active) { if (soudPlayerLoader.active) {
soudPlayerLoader.item.core.lSeek(ms) soudPlayerLoader.item.core.lSeek(ms);
} }
} }
} }

View file

@ -26,59 +26,58 @@ ListView {
if (chatToSelect) { if (chatToSelect) {
// first clear the chatToSelect property in case we need to // first clear the chatToSelect property in case we need to
// force adding the chat to the list and the layout changes // force adding the chat to the list and the layout changes
var toselect = chatToSelect var toselect = chatToSelect;
chatToSelect = null chatToSelect = null;
selectChat(toselect, true) selectChat(toselect, true);
} }
} }
onChatClicked: (chat) => {selectChat(chat)} onChatClicked: chat => {
selectChat(chat);
}
signal markAllAsRead() signal markAllAsRead
signal chatClicked(ChatGui chat) signal chatClicked(ChatGui chat)
model: ChatProxy { model: ChatProxy {
id: chatProxy id: chatProxy
filterText: mainItem.searchText filterText: mainItem.searchText
onFilterTextChanged: { onFilterTextChanged: {
chatToSelectLater = currentChatGui chatToSelectLater = currentChatGui;
} }
onModelAboutToBeReset: { onModelAboutToBeReset: {
loading = true loading = true;
} }
onModelReset: { onModelReset: {
loading = false loading = false;
if (mainItem.chatToSelectLater) { if (mainItem.chatToSelectLater) {
selectChat(mainItem.chatToSelectLater) selectChat(mainItem.chatToSelectLater);
mainItem.chatToSelectLater = null mainItem.chatToSelectLater = null;
} } else if (mainItem.chatToSelect) {
else if (mainItem.chatToSelect) { selectChat(mainItem.chatToSelect);
selectChat(mainItem.chatToSelect) mainItem.chatToSelect = null;
mainItem.chatToSelect = null
} else { } else {
selectChat(mainItem.currentChatGui) selectChat(mainItem.currentChatGui);
} }
} }
onChatAdded: (chat) => { onChatAdded: chat => {
mainItem.chatToSelect = chat mainItem.chatToSelect = chat;
} }
onRowsRemoved: { onRowsRemoved: {
var index = mainItem.currentIndex var index = mainItem.currentIndex;
mainItem.currentIndex = -1 mainItem.currentIndex = -1;
mainItem.currentIndex = index mainItem.currentIndex = index;
} }
onLayoutChanged: { onLayoutChanged: {
loading = false loading = false;
if (mainItem.chatToSelectLater) { if (mainItem.chatToSelectLater) {
selectChat(mainItem.chatToSelectLater) selectChat(mainItem.chatToSelectLater);
mainItem.chatToSelectLater = null mainItem.chatToSelectLater = null;
} } else if (mainItem.chatToSelect) {
else if (mainItem.chatToSelect) { selectChat(mainItem.chatToSelect);
selectChat(mainItem.chatToSelect) mainItem.chatToSelect = null;
mainItem.chatToSelect = null } else {
} selectChat(mainItem.currentChatGui);
else {
selectChat(mainItem.currentChatGui)
} }
} }
} }
@ -86,39 +85,39 @@ ListView {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
function selectChat(chatGui, force) { function selectChat(chatGui, force) {
var index = chatProxy.findChatIndex(chatGui) var index = chatProxy.findChatIndex(chatGui);
// force adding chat to list if it already exists // force adding chat to list if it already exists
// but has not been added to the list yet because // but has not been added to the list yet because
// it is empty and hide_empty_chatrooms is set // it is empty and hide_empty_chatrooms is set
if (index === -1 && force === true && chatGui) { if (index === -1 && force === true && chatGui) {
if (chatProxy.addChatInList(chatGui)) { if (chatProxy.addChatInList(chatGui)) {
var index = chatProxy.findChatIndex(chatGui) var index = chatProxy.findChatIndex(chatGui);
} }
} }
mainItem.currentIndex = index mainItem.currentIndex = index;
} }
// remove binding loop // remove binding loop
onContentHeightChanged: Qt.callLater(function () { onContentHeightChanged: Qt.callLater(function () {
if (mainItem) if (mainItem)
mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0 mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0;
}) })
onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0) onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0)
currentIndex = 0 currentIndex = 0
//---------------------------------------------------------------- //----------------------------------------------------------------
function moveToCurrentItem() { function moveToCurrentItem() {
if (mainItem.currentIndex >= 0) if (mainItem.currentIndex >= 0)
Utils.updatePosition(mainItem, mainItem) Utils.updatePosition(mainItem, mainItem);
} }
onCurrentItemChanged: { onCurrentItemChanged: {
moveToCurrentItem() moveToCurrentItem();
} }
// Update position only if we are moving to current item and its position is changing. // Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) { on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem() moveToCurrentItem();
} }
Behavior on contentY { Behavior on contentY {
NumberAnimation { NumberAnimation {
@ -129,7 +128,7 @@ ListView {
} }
} }
// //---------------------------------------------------------------- // //----------------------------------------------------------------
BusyIndicator { BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter anchors.horizontalCenter: mainItem.horizontalCenter
@ -151,7 +150,9 @@ ListView {
height: Utils.getSizeWithScreenRatio(63) height: Utils.getSizeWithScreenRatio(63)
Connections { Connections {
target: mainItem target: mainItem
function onMarkAllAsRead() {modelData.core.lMarkAsRead()} function onMarkAllAsRead() {
modelData.core.lMarkAsRead();
}
} }
RowLayout { RowLayout {
z: 1 z: 1
@ -194,7 +195,8 @@ ListView {
Layout.fillWidth: true Layout.fillWidth: true
EffectImage { EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isReply && !remoteComposingInfo.visible visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isReply &&
!remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: AppIcons.reply imageSource: AppIcons.reply
colorizationColor: DefaultStyle.main2_500 colorizationColor: DefaultStyle.main2_500
@ -203,7 +205,8 @@ ListView {
} }
EffectImage { EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isForward && !remoteComposingInfo.visible visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isForward &&
!remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: AppIcons.forward imageSource: AppIcons.forward
colorizationColor: DefaultStyle.main2_500 colorizationColor: DefaultStyle.main2_500
@ -212,7 +215,8 @@ ListView {
} }
EffectImage { EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.hasFileContent && !remoteComposingInfo.visible visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.hasFileContent
&& !remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: AppIcons.paperclip imageSource: AppIcons.paperclip
colorizationColor: DefaultStyle.main2_500 colorizationColor: DefaultStyle.main2_500
@ -221,7 +225,8 @@ ListView {
} }
EffectImage { EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isVoiceRecording && !remoteComposingInfo.visible visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isVoiceRecording
&& !remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: AppIcons.waveform imageSource: AppIcons.waveform
colorizationColor: DefaultStyle.main2_500 colorizationColor: DefaultStyle.main2_500
@ -230,7 +235,8 @@ ListView {
} }
EffectImage { EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isCalendarInvite && !remoteComposingInfo.visible visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isCalendarInvite
&& !remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: AppIcons.calendarBlank imageSource: AppIcons.calendarBlank
colorizationColor: DefaultStyle.main2_500 colorizationColor: DefaultStyle.main2_500
@ -261,20 +267,18 @@ ListView {
italic: modelData?.core.sendingText !== "" italic: modelData?.core.sendingText !== ""
} }
//: %1 is writing //: %1 is writing
text: modelData text: modelData ? modelData.core.composingName !== "" ? qsTr("chat_message_is_writing_info").arg(
? modelData.core.composingName !== "" modelData.core.composingName) : modelData.core.sendingText !== "" ? qsTr(
? qsTr("chat_message_is_writing_info").arg(modelData.core.composingName) "chat_message_draft_sending_text").arg(modelData.core.sendingText) : "" : ""
: modelData.core.sendingText !== ""
? qsTr("chat_message_draft_sending_text").arg(modelData.core.sendingText)
: ""
: ""
} }
} }
} }
ColumnLayout { ColumnLayout {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
RowLayout { RowLayout {
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
Text { Text {
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
property string format: modelData && UtilsCpp.isCurrentYear(modelData.core.lastUpdatedTime) ? "dd/MM" : "dd/MM/yy" property string format: modelData && UtilsCpp.isCurrentYear(modelData.core.lastUpdatedTime) ? "dd/MM" : "dd/MM/yy"
@ -289,7 +293,9 @@ ListView {
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
Item {Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
EffectImage { EffectImage {
visible: modelData?.core.ephemeralEnabled || false visible: modelData?.core.ephemeralEnabled || false
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0 Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
@ -298,7 +304,9 @@ ListView {
imageSource: AppIcons.clockCountDown imageSource: AppIcons.clockCountDown
} }
EffectImage { EffectImage {
visible: modelData != undefined && !modelData.core.isEncrypted && AppCpp.currentAccount && AppCpp.currentAccount.core.limeServerUrl !== "" && AppCpp.currentAccount.core.conferenceFactoryAddress !== "" visible: modelData != undefined && !modelData.core.isEncrypted && AppCpp.currentAccount
&& AppCpp.currentAccount.core.limeServerUrl !== "" && AppCpp.currentAccount.core.conferenceFactoryAddress
!== ""
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0 Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14) Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.warning_700 colorizationColor: DefaultStyle.warning_700
@ -318,22 +326,17 @@ ListView {
unread: modelData?.core.unreadMessagesCount || false unread: modelData?.core.unreadMessagesCount || false
} }
EffectImage { EffectImage {
visible: modelData?.core.lastMessage && modelData?.core.lastMessageState !== LinphoneEnums.ChatMessageState.StateIdle visible: modelData?.core.lastMessage && modelData?.core.lastMessageState
&& !modelData.core.lastMessage.core.isRemoteMessage || false !== LinphoneEnums.ChatMessageState.StateIdle && !modelData.core.lastMessage.core.isRemoteMessage || false
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0 Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14) Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.main1_500_main colorizationColor: DefaultStyle.main1_500_main
imageSource: modelData imageSource: modelData ? modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateDelivered
? modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateDelivered ? AppIcons.envelope : modelData.core.lastMessageState
? AppIcons.envelope === LinphoneEnums.ChatMessageState.StateDeliveredToUser ? AppIcons.check :
: modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateDeliveredToUser modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateNotDelivered
? AppIcons.check ? AppIcons.warningCircle : modelData.core.lastMessageState
: modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateNotDelivered === LinphoneEnums.ChatMessageState.StateDisplayed ? AppIcons.checks : "" : ""
? AppIcons.warningCircle
: modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateDisplayed
? AppIcons.checks
: ""
: ""
} }
} }
} }
@ -347,17 +350,13 @@ ListView {
popup.contentItem: ColumnLayout { popup.contentItem: ColumnLayout {
IconLabelButton { IconLabelButton {
//: "Mute" //: "Mute"
text: modelData text: modelData ? modelData.core.muted ? qsTr("chat_room_unmute") : qsTr("chat_room_mute") : ""
? modelData.core.muted
? qsTr("chat_room_unmute")
: qsTr("chat_room_mute")
: ""
icon.source: modelData ? modelData.core.muted ? AppIcons.bell : AppIcons.bellSlash : "" icon.source: modelData ? modelData.core.muted ? AppIcons.bell : AppIcons.bellSlash : ""
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true Layout.fillWidth: true
onClicked: { onClicked: {
modelData.core.muted = !modelData.core.muted modelData.core.muted = !modelData.core.muted;
chatroomPopup.close() chatroomPopup.close();
} }
} }
IconLabelButton { IconLabelButton {
@ -368,8 +367,8 @@ ListView {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true Layout.fillWidth: true
onClicked: { onClicked: {
modelData.core.lMarkAsRead() modelData.core.lMarkAsRead();
chatroomPopup.close() chatroomPopup.close();
} }
} }
ColumnLayout { ColumnLayout {
@ -390,14 +389,12 @@ ListView {
//: leave the conversation ? //: leave the conversation ?
mainWindow.showConfirmationLambdaPopup(qsTr("chat_list_leave_chat_popup_title"), mainWindow.showConfirmationLambdaPopup(qsTr("chat_list_leave_chat_popup_title"),
//: You will not be able to send or receive messages in this conversation anymore. Do You want to continue ? //: You will not be able to send or receive messages in this conversation anymore. Do You want to continue ?
qsTr("chat_list_leave_chat_popup_message"), qsTr("chat_list_leave_chat_popup_message"), "", function (confirmed) {
"",
function(confirmed) {
if (confirmed) { if (confirmed) {
modelData.core.lLeave() modelData.core.lLeave();
chatroomPopup.close() chatroomPopup.close();
} }
}) });
} }
style: ButtonStyle.hoveredBackground style: ButtonStyle.hoveredBackground
} }
@ -419,20 +416,17 @@ ListView {
//: Delete the conversation ? //: Delete the conversation ?
mainWindow.showConfirmationLambdaPopup(qsTr("chat_list_delete_chat_popup_title"), mainWindow.showConfirmationLambdaPopup(qsTr("chat_list_delete_chat_popup_title"),
//: This conversation and all its messages will be deleted. Do You want to continue ? //: This conversation and all its messages will be deleted. Do You want to continue ?
qsTr("chat_list_delete_chat_popup_message"), qsTr("chat_list_delete_chat_popup_message"), "", function (confirmed) {
"",
function(confirmed) {
if (confirmed) { if (confirmed) {
modelData.core.lDelete() modelData.core.lDelete();
chatroomPopup.close() chatroomPopup.close();
} }
}) });
} }
style: ButtonStyle.hoveredBackgroundRed style: ButtonStyle.hoveredBackgroundRed
} }
} }
} }
} }
MouseArea { MouseArea {
id: mouseArea id: mouseArea
@ -441,9 +435,9 @@ ListView {
acceptedButtons: Qt.RightButton | Qt.LeftButton acceptedButtons: Qt.RightButton | Qt.LeftButton
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) if (containsMouse)
mainItem.lastMouseContainsIndex = index mainItem.lastMouseContainsIndex = index;
else if (mainItem.lastMouseContainsIndex == index) else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1 mainItem.lastMouseContainsIndex = -1;
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
@ -454,9 +448,9 @@ ListView {
} }
onPressed: { onPressed: {
if (pressedButtons & Qt.RightButton) { if (pressedButtons & Qt.RightButton) {
chatroomPopup.open() chatroomPopup.open();
} else { } else {
mainItem.chatClicked(modelData) mainItem.chatClicked(modelData);
} }
} }
} }

View file

@ -17,14 +17,14 @@ Control.Control {
property ChatMessageGui chatMessage property ChatMessageGui chatMessage
property ChatGui chat property ChatGui chat
property string searchedTextPart property string searchedTextPart
property string ownReaction: chatMessage? chatMessage.core.ownReaction : "" property string ownReaction: chatMessage ? chatMessage.core.ownReaction : ""
property string fromAddress: chatMessage? chatMessage.core.fromAddress : "" property string fromAddress: chatMessage ? chatMessage.core.fromAddress : ""
property bool isRemoteMessage: chatMessage? chatMessage.core.isRemoteMessage : false property bool isRemoteMessage: chatMessage ? chatMessage.core.isRemoteMessage : false
property bool isFromChatGroup: chatMessage? chatMessage.core.isFromChatGroup : false property bool isFromChatGroup: chatMessage ? chatMessage.core.isFromChatGroup : false
property bool isReply: chatMessage? chatMessage.core.isReply : false property bool isReply: chatMessage ? chatMessage.core.isReply : false
property bool isForward: chatMessage? chatMessage.core.isForward : false property bool isForward: chatMessage ? chatMessage.core.isForward : false
property string replyText: chatMessage? chatMessage.core.replyText : "" property string replyText: chatMessage ? chatMessage.core.replyText : ""
property string replyMessageId: chatMessage? chatMessage.core.replyMessageId : "" property string replyMessageId: chatMessage ? chatMessage.core.replyMessageId : ""
property var msgState: chatMessage ? chatMessage.core.messageState : LinphoneEnums.ChatMessageState.StateIdle property var msgState: chatMessage ? chatMessage.core.messageState : LinphoneEnums.ChatMessageState.StateIdle
hoverEnabled: true hoverEnabled: true
property bool linkHovered: false property bool linkHovered: false
@ -32,15 +32,15 @@ Control.Control {
leftPadding: isRemoteMessage ? Utils.getSizeWithScreenRatio(5) : 0 leftPadding: isRemoteMessage ? Utils.getSizeWithScreenRatio(5) : 0
signal messageDeletionRequested() signal messageDeletionRequested
signal messageEditionRequested() signal messageEditionRequested
signal isFileHoveringChanged(bool isFileHovering) signal isFileHoveringChanged(bool isFileHovering)
signal showReactionsForMessageRequested() signal showReactionsForMessageRequested
signal showImdnStatusForMessageRequested() signal showImdnStatusForMessageRequested
signal replyToMessageRequested() signal replyToMessageRequested
signal forwardMessageRequested() signal forwardMessageRequested
signal endOfVoiceRecordingReached() signal endOfVoiceRecordingReached
signal requestAutoPlayVoiceRecording() signal requestAutoPlayVoiceRecording
signal searchMessageByIdRequested(string id) signal searchMessageByIdRequested(string id)
onRequestAutoPlayVoiceRecording: chatBubbleContent.requestAutoPlayVoiceRecording() onRequestAutoPlayVoiceRecording: chatBubbleContent.requestAutoPlayVoiceRecording()
@ -51,8 +51,8 @@ Control.Control {
onTriggered: highlightRectangle.opacity = 0 onTriggered: highlightRectangle.opacity = 0
} }
function requestHighlight() { function requestHighlight() {
highlightRectangle.opacity = 0.8 highlightRectangle.opacity = 0.8;
hightlightTimer.start() hightlightTimer.start();
} }
background: Item { background: Item {
@ -61,7 +61,7 @@ Control.Control {
function handleDefaultMouseEvent(event) { function handleDefaultMouseEvent(event) {
if (event.button === Qt.RightButton) { if (event.button === Qt.RightButton) {
optionsMenu.open() optionsMenu.open();
} }
} }
@ -87,7 +87,7 @@ Control.Control {
spacing: Utils.getSizeWithScreenRatio(8) spacing: Utils.getSizeWithScreenRatio(8)
visible: mainItem.isForward visible: mainItem.isForward
Layout.leftMargin: mainItem.isFromChatGroup ? Utils.getSizeWithScreenRatio(9) + avatar.width : 0 Layout.leftMargin: mainItem.isFromChatGroup ? Utils.getSizeWithScreenRatio(9) + avatar.width : 0
Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft: Qt.AlignRight Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft : Qt.AlignRight
EffectImage { EffectImage {
imageSource: AppIcons.forward imageSource: AppIcons.forward
colorizationColor: DefaultStyle.main2_500_main colorizationColor: DefaultStyle.main2_500_main
@ -123,18 +123,18 @@ Control.Control {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(12) Layout.preferredHeight: Utils.getSizeWithScreenRatio(12)
} }
Text { Text {
Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft: Qt.AlignRight Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft : Qt.AlignRight
text: mainItem.isRemoteMessage text: mainItem.isRemoteMessage ? mainItem.chatMessage.core.repliedToName !== "" ?
? mainItem.chatMessage.core.repliedToName !== ""
//: %1 replied to %2 //: %1 replied to %2
? qsTr("chat_message_remote_replied_to").arg(mainItem.chatMessage.core.fromName).arg(mainItem.chatMessage.core.repliedToName) qsTr("chat_message_remote_replied_to").arg(mainItem.chatMessage.core.fromName).arg(
mainItem.chatMessage.core.repliedToName) :
//: %1 replied //: %1 replied
: qsTr("chat_message_remote_replied").arg(mainItem.chatMessage.core.fromName) qsTr("chat_message_remote_replied").arg(mainItem.chatMessage.core.fromName) :
: mainItem.chatMessage.core.repliedToName !== "" mainItem.chatMessage.core.repliedToName !== "" ?
//: You replied to %1 //: You replied to %1
? qsTr("chat_message_user_replied_to").arg(mainItem.chatMessage.core.repliedToName) qsTr("chat_message_user_replied_to").arg(mainItem.chatMessage.core.repliedToName) :
//: You replied //: You replied
: qsTr("chat_message_user_replied") qsTr("chat_message_user_replied")
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font { font {
pixelSize: Typography.p4.pixelSize pixelSize: Typography.p4.pixelSize
@ -160,7 +160,7 @@ Control.Control {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
mainItem.searchMessageByIdRequested(mainItem.replyMessageId) mainItem.searchMessageByIdRequested(mainItem.replyMessageId);
} }
} }
} }
@ -175,7 +175,9 @@ Control.Control {
} }
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
} }
RowLayout { RowLayout {
id: bubbleLayout id: bubbleLayout
@ -213,7 +215,7 @@ Control.Control {
// visible: invitationLoader.status !== Loader.Ready // Add other bubbles here that could control the mouse themselves, then add in bubble a signal onMouseEvent // visible: invitationLoader.status !== Loader.Ready // Add other bubbles here that could control the mouse themselves, then add in bubble a signal onMouseEvent
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
onClicked: (mouse) => mainItem.handleDefaultMouseEvent(mouse) onClicked: mouse => mainItem.handleDefaultMouseEvent(mouse)
} }
background: Item { background: Item {
@ -275,8 +277,8 @@ Control.Control {
searchedTextPart: mainItem.searchedTextPart searchedTextPart: mainItem.searchedTextPart
chatMessageGui: mainItem.chatMessage chatMessageGui: mainItem.chatMessage
maxWidth: mainItem.maxWidth maxWidth: mainItem.maxWidth
onMouseEvent: (event) => { onMouseEvent: event => {
mainItem.handleDefaultMouseEvent(event) mainItem.handleDefaultMouseEvent(event);
} }
onEndOfVoiceRecordingReached: mainItem.endOfVoiceRecordingReached() onEndOfVoiceRecordingReached: mainItem.endOfVoiceRecordingReached()
} }
@ -336,24 +338,21 @@ Control.Control {
Layout.preferredHeight: visible ? 14 : 0 Layout.preferredHeight: visible ? 14 : 0
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
colorizationColor: DefaultStyle.main1_500_main colorizationColor: DefaultStyle.main1_500_main
imageSource: mainItem.msgState === LinphoneEnums.ChatMessageState.StateDelivered imageSource: mainItem.msgState === LinphoneEnums.ChatMessageState.StateDelivered ? AppIcons.envelope :
? AppIcons.envelope mainItem.msgState === LinphoneEnums.ChatMessageState.StateDeliveredToUser
: mainItem.msgState === LinphoneEnums.ChatMessageState.StateDeliveredToUser ? AppIcons.check : mainItem.msgState
? AppIcons.check === LinphoneEnums.ChatMessageState.StateNotDelivered ? AppIcons.warningCircle :
: mainItem.msgState === LinphoneEnums.ChatMessageState.StateNotDelivered mainItem.msgState === LinphoneEnums.ChatMessageState.StateDisplayed
? AppIcons.warningCircle ? AppIcons.checks : mainItem.msgState
: mainItem.msgState === LinphoneEnums.ChatMessageState.StateDisplayed === LinphoneEnums.ChatMessageState.StatePendingDelivery
? AppIcons.checks ? AppIcons.hourglass : ""
: mainItem.msgState === LinphoneEnums.ChatMessageState.StatePendingDelivery
? AppIcons.hourglass
: ""
BusyIndicator { BusyIndicator {
anchors.fill: parent anchors.fill: parent
Layout.preferredWidth: visible ? 14 : 0 Layout.preferredWidth: visible ? 14 : 0
Layout.preferredHeight: visible ? 14 : 0 Layout.preferredHeight: visible ? 14 : 0
visible: mainItem.msgState === LinphoneEnums.ChatMessageState.StateIdle visible: mainItem.msgState === LinphoneEnums.ChatMessageState.StateIdle || mainItem.msgState
|| mainItem.msgState === LinphoneEnums.ChatMessageState.StateInProgress === LinphoneEnums.ChatMessageState.StateInProgress || mainItem.msgState
|| mainItem.msgState === LinphoneEnums.ChatMessageState.StateFileTransferInProgress === LinphoneEnums.ChatMessageState.StateFileTransferInProgress
} }
} }
} }
@ -419,7 +418,8 @@ Control.Control {
} }
RowLayout { RowLayout {
id: actionsLayout id: actionsLayout
visible: mainItem.hovered || optionsMenu.hovered || optionsMenu.popup.opened || emojiButton.hovered || emojiButton.popup.opened visible: mainItem.hovered || optionsMenu.hovered || optionsMenu.popup.opened || emojiButton.hovered
|| emojiButton.popup.opened
Layout.leftMargin: Utils.getSizeWithScreenRatio(8) Layout.leftMargin: Utils.getSizeWithScreenRatio(8)
Layout.rightMargin: Utils.getSizeWithScreenRatio(8) Layout.rightMargin: Utils.getSizeWithScreenRatio(8)
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
@ -440,7 +440,7 @@ Control.Control {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: { onClicked: {
mainItem.chatMessage.lSend() mainItem.chatMessage.lSend();
} }
} }
IconLabelButton { IconLabelButton {
@ -451,8 +451,8 @@ Control.Control {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: { onClicked: {
mainItem.showImdnStatusForMessageRequested() mainItem.showImdnStatusForMessageRequested();
optionsMenu.close() optionsMenu.close();
} }
} }
IconLabelButton { IconLabelButton {
@ -464,8 +464,8 @@ Control.Control {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: { onClicked: {
mainItem.messageEditionRequested() mainItem.messageEditionRequested();
optionsMenu.close() optionsMenu.close();
} }
} }
IconLabelButton { IconLabelButton {
@ -477,29 +477,31 @@ Control.Control {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: { onClicked: {
mainItem.replyToMessageRequested() mainItem.replyToMessageRequested();
optionsMenu.close() optionsMenu.close();
} }
} }
IconLabelButton { IconLabelButton {
inverseLayout: true inverseLayout: true
visible: !mainItem.chatMessage.core.isRetracted visible: !mainItem.chatMessage.core.isRetracted
text: chatBubbleContent.selectedText != "" text: chatBubbleContent.selectedText != "" ?
//: "Copy selection" //: "Copy selection"
? qsTr("chat_message_copy_selection") qsTr("chat_message_copy_selection") :
//: "Copy" //: "Copy"
: qsTr("chat_message_copy") qsTr("chat_message_copy")
icon.source: AppIcons.copy icon.source: AppIcons.copy
// spacing: Utils.getSizeWithScreenRatio(10) // spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: { onClicked: {
var success = UtilsCpp.copyToClipboard(chatBubbleContent.selectedText != "" ? chatBubbleContent.selectedText : mainItem.chatMessage.core.text) var success = UtilsCpp.copyToClipboard(chatBubbleContent.selectedText != "" ? chatBubbleContent.selectedText :
mainItem.chatMessage.core.text);
//: Copied //: Copied
if (success) UtilsCpp.showInformationPopup(qsTr("chat_message_copied_to_clipboard_title"), if (success)
UtilsCpp.showInformationPopup(qsTr("chat_message_copied_to_clipboard_title"),
//: "to clipboard" //: "to clipboard"
qsTr("chat_message_copied_to_clipboard_toast")) qsTr("chat_message_copied_to_clipboard_toast"));
optionsMenu.close() optionsMenu.close();
} }
} }
IconLabelButton { IconLabelButton {
@ -511,8 +513,8 @@ Control.Control {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: { onClicked: {
mainItem.forwardMessageRequested() mainItem.forwardMessageRequested();
optionsMenu.close() optionsMenu.close();
} }
} }
Rectangle { Rectangle {
@ -529,8 +531,8 @@ Control.Control {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: { onClicked: {
mainItem.messageDeletionRequested() mainItem.messageDeletionRequested();
optionsMenu.close() optionsMenu.close();
} }
style: ButtonStyle.hoveredBackgroundRed style: ButtonStyle.hoveredBackgroundRed
} }
@ -553,11 +555,13 @@ Control.Control {
visible: mainItem.ownReaction === modelData visible: mainItem.ownReaction === modelData
} }
onClicked: { onClicked: {
if(modelData) { if (modelData) {
if (mainItem.ownReaction === modelData) mainItem.chatMessage.core.lRemoveReaction() if (mainItem.ownReaction === modelData)
else mainItem.chatMessage.core.lSendReaction(modelData) mainItem.chatMessage.core.lRemoveReaction();
else
mainItem.chatMessage.core.lSendReaction(modelData);
} }
emojiButton.close() emojiButton.close();
} }
} }
} }
@ -568,20 +572,24 @@ Control.Control {
popup.height: Utils.getSizeWithScreenRatio(291) popup.height: Utils.getSizeWithScreenRatio(291)
popup.contentItem: EmojiPicker { popup.contentItem: EmojiPicker {
id: emojiPicker id: emojiPicker
onEmojiClicked: (emoji) => { onEmojiClicked: emoji => {
if (mainItem.chatMessage) { if (mainItem.chatMessage) {
if (mainItem.ownReaction === emoji) mainItem.chatMessage.core.lRemoveReaction() if (mainItem.ownReaction === emoji)
else mainItem.chatMessage.core.lSendReaction(emoji) mainItem.chatMessage.core.lRemoveReaction();
else
mainItem.chatMessage.core.lSendReaction(emoji);
} }
emojiPickerButton.close() emojiPickerButton.close();
emojiButton.close() emojiButton.close();
} }
} }
} }
} }
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
} }
} }
} }

View file

@ -14,21 +14,21 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
property ChatMessageGui chatMessageGui: null property ChatMessageGui chatMessageGui: null
property bool isRemoteMessage: chatMessageGui? chatMessageGui.core.isRemoteMessage : false property bool isRemoteMessage: chatMessageGui ? chatMessageGui.core.isRemoteMessage : false
property ChatGui chatGui: null property ChatGui chatGui: null
signal isFileHoveringChanged(bool isFileHovering) signal isFileHoveringChanged(bool isFileHovering)
signal lastSelectedTextChanged(string selectedText) signal lastSelectedTextChanged(string selectedText)
// signal conferenceIcsCopied() // signal conferenceIcsCopied()
signal mouseEvent(MouseEvent event) signal mouseEvent(MouseEvent event)
signal endOfVoiceRecordingReached() signal endOfVoiceRecordingReached
signal requestAutoPlayVoiceRecording() signal requestAutoPlayVoiceRecording
property string selectedText property string selectedText
property color textColor property color textColor
property string searchedTextPart property string searchedTextPart
property int fileBorderWidth : 0 property int fileBorderWidth: 0
property int maxWidth property int maxWidth
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
@ -57,7 +57,7 @@ ColumnLayout {
Connections { Connections {
target: mainItem target: mainItem
function onRequestAutoPlayVoiceRecording() { function onRequestAutoPlayVoiceRecording() {
audioContent.requestPlaying() audioContent.requestPlaying();
} }
} }
// width: conferenceList.width // width: conferenceList.width
@ -68,14 +68,14 @@ ColumnLayout {
Repeater { Repeater {
id: conferenceList id: conferenceList
visible: count > 0 visible: count > 0
model: ChatMessageContentProxy{ model: ChatMessageContentProxy {
filterType: ChatMessageContentProxy.FilterContentType.Conference filterType: ChatMessageContentProxy.FilterContentType.Conference
chatMessageGui: mainItem.chatMessageGui chatMessageGui: mainItem.chatMessageGui
} }
delegate: ChatMessageInvitationBubble { delegate: ChatMessageInvitationBubble {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(490) Layout.preferredWidth: Utils.getSizeWithScreenRatio(490)
conferenceInfoGui: modelData.core.conferenceInfo conferenceInfoGui: modelData.core.conferenceInfo
onMouseEvent: (event) => mainItem.mouseEvent(event) onMouseEvent: event => mainItem.mouseEvent(event)
} }
} }
// SINGLE FILE // SINGLE FILE
@ -83,9 +83,7 @@ ColumnLayout {
id: singleImageFile id: singleImageFile
cache: false cache: false
visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isImage(contentGui.core.filePath) visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isImage(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1 contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
@ -93,9 +91,7 @@ ColumnLayout {
AnimatedImageFileView { AnimatedImageFileView {
id: singleAnimatedImageFile id: singleAnimatedImageFile
visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isAnimatedImage(contentGui.core.filePath) visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isAnimatedImage(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1 contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: paintedHeight Layout.preferredHeight: paintedHeight
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@ -107,22 +103,20 @@ ColumnLayout {
onStatusChanged: { onStatusChanged: {
if (status == Image.Ready) { if (status == Image.Ready) {
if (singleAnimatedImageFile.initialization) { if (singleAnimatedImageFile.initialization) {
initialSourceWidth = sourceSize.width initialSourceWidth = sourceSize.width;
initialSourceHeight = sourceSize.height initialSourceHeight = sourceSize.height;
singleAnimatedImageFile.initialization = false singleAnimatedImageFile.initialization = false;
} }
var sourceW = Math.min(initialSourceWidth, mainItem.maxWidth) var sourceW = Math.min(initialSourceWidth, mainItem.maxWidth);
sourceSize.height = Math.round((sourceW/initialSourceWidth) * initialSourceHeight) sourceSize.height = Math.round((sourceW / initialSourceWidth) * initialSourceHeight);
sourceSize.width = sourceW sourceSize.width = sourceW;
} }
} }
} }
VideoFileView { VideoFileView {
id: singleVideoFile id: singleVideoFile
visible: mainItem.filescontentProxy.count === 1 && UtilsCpp.isVideo(contentGui.core.filePath) visible: mainItem.filescontentProxy.count === 1 && UtilsCpp.isVideo(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1 contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
Layout.fillWidth: true Layout.fillWidth: true
width: Math.min(Utils.getSizeWithScreenRatio(285), mainItem.maxWidth) width: Math.min(Utils.getSizeWithScreenRatio(285), mainItem.maxWidth)
height: Math.min(Utils.getSizeWithScreenRatio(285), mainItem.maxWidth) height: Math.min(Utils.getSizeWithScreenRatio(285), mainItem.maxWidth)
@ -135,13 +129,11 @@ ColumnLayout {
// FILES // FILES
ChatFilesGridLayout { ChatFilesGridLayout {
id: messageFilesList id: messageFilesList
visible: mainItem.filescontentProxy.count > 0 visible: mainItem.filescontentProxy.count > 0 && !singleImageFile.visible && !singleAnimatedImageFile.visible &&
&& !singleImageFile.visible !singleVideoFile.visible
&& !singleAnimatedImageFile.visible
&& !singleVideoFile.visible
Layout.fillWidth: visible Layout.fillWidth: visible
Layout.fillHeight: visible Layout.fillHeight: visible
maxWidth: Utils.getSizeWithScreenRatio(115*3) maxWidth: Utils.getSizeWithScreenRatio(115 * 3)
// Layout.fillHeight: true // Layout.fillHeight: true
proxyModel: visible ? mainItem.filescontentProxy : null proxyModel: visible ? mainItem.filescontentProxy : null
// onIsHoveringFileChanged: mainItem.isFileHoveringChanged(isHoveringFile) // onIsHoveringFileChanged: mainItem.isFileHoveringChanged(isHoveringFile)

View file

@ -9,9 +9,8 @@ import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
spacing: 0
id: mainItem id: mainItem
spacing: 0
width: Utils.getSizeWithScreenRatio(490) width: Utils.getSizeWithScreenRatio(490)
property ConferenceInfoGui conferenceInfoGui property ConferenceInfoGui conferenceInfoGui
@ -36,9 +35,8 @@ ColumnLayout {
let offsetHours = Math.floor(offsetMinutes / 60); let offsetHours = Math.floor(offsetMinutes / 60);
let timeZone = "UTC" + (offsetHours >= 0 ? "+" : "") + offsetHours; let timeZone = "UTC" + (offsetHours >= 0 ? "+" : "") + offsetHours;
timeRangeText = timeRangeText = qsTr("ics_bubble_meeting_from") + startTime + qsTr("ics_bubble_meeting_to") + endTime + " ("
qsTr("ics_bubble_meeting_from") + startTime + + timeZone + ")";
qsTr("ics_bubble_meeting_to") + endTime + " (" + timeZone + ")";
} }
Control.Control { Control.Control {
@ -56,22 +54,18 @@ ColumnLayout {
} }
contentItem: ColumnLayout { contentItem: ColumnLayout {
Text { Text {
visible: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated visible: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated || conferenceInfo.state
|| conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled == LinphoneEnums.ConferenceInfoState.Cancelled
text: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated text: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ?
//: Meeting has been updated //: Meeting has been updated
? qsTr("ics_bubble_meeting_modified") + " :" qsTr("ics_bubble_meeting_modified") + " :" : conferenceInfo.state
: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled == LinphoneEnums.ConferenceInfoState.Cancelled ?
//: Meeting has been canceled //: Meeting has been canceled
? qsTr("ics_bubble_meeting_cancelled") + " :" qsTr("ics_bubble_meeting_cancelled") + " :" : ""
: ""
font: Typography.p2 font: Typography.p2
color: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.New ? color: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.New ? DefaultStyle.main2_600 : conferenceInfo.state
DefaultStyle.main2_600 : == LinphoneEnums.ConferenceInfoState.Updated ? DefaultStyle.warning_600 : conferenceInfo.state
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ? == LinphoneEnums.ConferenceInfoState.Cancelled ? DefaultStyle.danger_500_main :
DefaultStyle.warning_600 :
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled ?
DefaultStyle.danger_500_main :
DefaultStyle.main2_600 DefaultStyle.main2_600
} }
@ -170,18 +164,16 @@ ColumnLayout {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.calendarPlus icon.source: AppIcons.calendarPlus
onClicked: { onClicked: {
conferenceInfo.exportConferenceToICS() conferenceInfo.exportConferenceToICS();
} }
} }
} }
Text { Text {
//: from %1 to %2 (UTC%3) //: from %1 to %2 (UTC%3)
property string offsetFromUtc: conferenceInfo.timeZoneModel.offsetFromUtc > 0 property string offsetFromUtc: conferenceInfo.timeZoneModel.offsetFromUtc > 0 ? "+" + conferenceInfo.timeZoneModel.offsetFromUtc
? "+" + conferenceInfo.timeZoneModel.offsetFromUtc/3600 / 3600 : conferenceInfo.timeZoneModel.offsetFromUtc / 3600
: conferenceInfo.timeZoneModel.offsetFromUtc/3600 text: qsTr("").arg(conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(conferenceInfo.endDateTime.toLocaleString(
text: qsTr("").arg( Qt.locale(), "hh:mm")).arg(offsetFromUtc)
conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(
conferenceInfo.endDateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(offsetFromUtc)
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
font: Typography.p4 font: Typography.p4
} }
@ -196,7 +188,6 @@ ColumnLayout {
} }
} }
Rectangle { Rectangle {
visible: conferenceInfo.description.length > 0 || conferenceInfo.participantCount > 0 visible: conferenceInfo.description.length > 0 || conferenceInfo.participantCount > 0
Layout.fillWidth: true Layout.fillWidth: true
@ -225,7 +216,7 @@ ColumnLayout {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
cursorShape: mainItem.linkHovered ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: mainItem.linkHovered ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: (mouse) => mouseEvent(mouse) onClicked: mouse => mouseEvent(mouse)
acceptedButtons: Qt.AllButtons // Send all to parent acceptedButtons: Qt.AllButtons // Send all to parent
} }
@ -259,14 +250,14 @@ ColumnLayout {
maximumLineCount: 3 maximumLineCount: 3
elide: Text.ElideRight elide: Text.ElideRight
visible: conferenceInfo.description.length > 0 visible: conferenceInfo.description.length > 0
onLinkActivated: (link) => { onLinkActivated: link => {
if (link.startsWith('sip')) if (link.startsWith('sip'))
UtilsCpp.createCall(link) UtilsCpp.createCall(link);
else else
Qt.openUrlExternally(link) Qt.openUrlExternally(link);
} }
onHoveredLinkChanged: { onHoveredLinkChanged: {
mainItem.linkHovered = hoveredLink !== "" mainItem.linkHovered = hoveredLink !== "";
} }
} }
} }
@ -297,9 +288,9 @@ ColumnLayout {
text: qsTr("ics_bubble_join") text: qsTr("ics_bubble_join")
visible: !SettingsCpp.disableMeetingsFeature && conferenceInfo.state != LinphoneEnums.ConferenceInfoState.Cancelled visible: !SettingsCpp.disableMeetingsFeature && conferenceInfo.state != LinphoneEnums.ConferenceInfoState.Cancelled
onClicked: { onClicked: {
var callsWindow = UtilsCpp.getOrCreateCallsWindow() var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfoGui) callsWindow.setupConference(mainItem.conferenceInfoGui);
UtilsCpp.smartShowWindow(callsWindow) UtilsCpp.smartShowWindow(callsWindow);
} }
} }
} }

View file

@ -5,7 +5,7 @@ import QtQuick.Controls.Basic as Control
import Qt.labs.qmlmodels import Qt.labs.qmlmodels
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView { ListView {
@ -18,7 +18,8 @@ ListView {
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60) property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool loading: false property bool loading: false
property bool isEncrypted: chat && chat.core.isEncrypted property bool isEncrypted: chat && chat.core.isEncrypted
property bool showEncryptedInfo: AppCpp.currentAccount !== null && AppCpp.currentAccount.core.limeServerUrl !== "" && AppCpp.currentAccount.core.conferenceFactoryAddress !== "" property bool showEncryptedInfo: AppCpp.currentAccount !== null && AppCpp.currentAccount.core.limeServerUrl !== ""
&& AppCpp.currentAccount.core.conferenceFactoryAddress !== ""
highlightFollowsCurrentItem: true highlightFollowsCurrentItem: true
verticalLayoutDirection: ListView.BottomToTop verticalLayoutDirection: ListView.BottomToTop
@ -34,20 +35,21 @@ ListView {
property string filterText property string filterText
onFilterTextChanged: { onFilterTextChanged: {
lastIndexFoundWithFilter = -1 lastIndexFoundWithFilter = -1;
if (filterText === "") return if (filterText === "")
eventLogProxy.filterText = filterText return;
var indexVisible = indexAt(contentX, contentY) eventLogProxy.filterText = filterText;
eventLogProxy.findIndexCorrespondingToFilter(indexVisible, true, true) var indexVisible = indexAt(contentX, contentY);
eventLogProxy.findIndexCorrespondingToFilter(indexVisible, true, true);
} }
signal findIndexWithFilter(bool forward) signal findIndexWithFilter(bool forward)
property bool searchForward: true property bool searchForward: true
onFindIndexWithFilter: (forward) => { onFindIndexWithFilter: forward => {
searchForward = forward searchForward = forward;
eventLogProxy.findIndexCorrespondingToFilter(currentIndex, searchForward, false) eventLogProxy.findIndexCorrespondingToFilter(currentIndex, searchForward, false);
} }
onSearchMessageByIdRequested: (id) => { onSearchMessageByIdRequested: id => {
eventLogProxy.findChatMessageById(id) eventLogProxy.findChatMessageById(id);
} }
Button { Button {
@ -63,9 +65,9 @@ ListView {
anchors.bottomMargin: Utils.getSizeWithScreenRatio(18) anchors.bottomMargin: Utils.getSizeWithScreenRatio(18)
anchors.rightMargin: Utils.getSizeWithScreenRatio(18) anchors.rightMargin: Utils.getSizeWithScreenRatio(18)
onClicked: { onClicked: {
var index = eventLogProxy.findFirstUnreadIndex() var index = eventLogProxy.findFirstUnreadIndex();
mainItem.positionViewAtIndex(index, ListView.Contain) mainItem.positionViewAtIndex(index, ListView.Contain);
eventLogProxy.markIndexAsRead(index) eventLogProxy.markIndexAsRead(index);
} }
UnreadNotification { UnreadNotification {
anchors.top: parent.top anchors.top: parent.top
@ -77,10 +79,10 @@ ListView {
} }
onAtYBeginningChanged: if (atYBeginning && count !== 0) { onAtYBeginningChanged: if (atYBeginning && count !== 0) {
eventLogProxy.displayMore() eventLogProxy.displayMore();
} }
onAtYEndChanged: if (atYEnd && chat && count !== 0) { onAtYEndChanged: if (atYEnd && chat && count !== 0) {
chat.core.lMarkAsRead() chat.core.lMarkAsRead();
} }
model: EventLogProxy { model: EventLogProxy {
@ -90,59 +92,59 @@ ListView {
initialDisplayItems: 20 initialDisplayItems: 20
displayItemsStep: 20 displayItemsStep: 20
onModelAboutToBeReset: { onModelAboutToBeReset: {
loading = true loading = true;
} }
onModelReset: loading = false onModelReset: loading = false
onModelUpdated: { onModelUpdated: {
loading = false loading = false;
var index = eventLogProxy.findFirstUnreadIndex() var index = eventLogProxy.findFirstUnreadIndex();
var itemToSelect = mainItem.itemAtIndex(index) var itemToSelect = mainItem.itemAtIndex(index);
mainItem.positionViewAtIndex(index, ListView.Beginning) mainItem.positionViewAtIndex(index, ListView.Beginning);
var lastMessage = itemAtIndex(0) var lastMessage = itemAtIndex(0);
mainItem.lastItemVisible = lastMessage.isFullyVisible mainItem.lastItemVisible = lastMessage.isFullyVisible;
eventLogProxy.markIndexAsRead(index) eventLogProxy.markIndexAsRead(index);
} }
onEventInsertedByUser: (index) => { onEventInsertedByUser: index => {
mainItem.positionViewAtIndex(index, ListView.Beginning) mainItem.positionViewAtIndex(index, ListView.Beginning);
} }
onIndexWithFilterFound: (index) => { onIndexWithFilterFound: index => {
if (index !== -1) { if (index !== -1) {
currentIndex = index currentIndex = index;
mainItem.positionViewAtIndex(index, ListView.Center) mainItem.positionViewAtIndex(index, ListView.Center);
mainItem.requestHighlight(index) mainItem.requestHighlight(index);
mainItem.lastIndexFoundWithFilter = index mainItem.lastIndexFoundWithFilter = index;
} else { } else {
if (mainItem.lastIndexFoundWithFilter !== index) { if (mainItem.lastIndexFoundWithFilter !== index) {
//: Find message //: Find message
UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"), UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"), mainItem.searchForward ?
mainItem.searchForward
//: Last result reached //: Last result reached
? qsTr("info_popup_last_result_message") qsTr("info_popup_last_result_message") :
//: First result reached //: First result reached
: qsTr("info_popup_first_result_message"), false) qsTr("info_popup_first_result_message"), false);
mainItem.positionViewAtIndex(mainItem.lastIndexFoundWithFilter, ListView.Center) mainItem.positionViewAtIndex(mainItem.lastIndexFoundWithFilter, ListView.Center);
mainItem.requestHighlight(mainItem.lastIndexFoundWithFilter) mainItem.requestHighlight(mainItem.lastIndexFoundWithFilter);
} } else {
else {
//: Find message //: Find message
UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"), UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"),
//: No result found //: No result found
qsTr("info_popup_no_result_message"), false) qsTr("info_popup_no_result_message"), false);
} }
} }
} }
onFoundMessagById: (index) => { onFoundMessagById: index => {
if (index !== -1) { if (index !== -1) {
currentIndex = index currentIndex = index;
mainItem.positionViewAtIndex(index, ListView.Center) mainItem.positionViewAtIndex(index, ListView.Center);
mainItem.requestHighlight(index) mainItem.requestHighlight(index);
} }
} }
} }
footer: Item { footer: Item {
visible: mainItem.chat && !mainItem.loading visible: mainItem.chat && !mainItem.loading
height: visible ? (headerMessage.height + headerMessage.topMargin + headerMessage.bottomMargin) : Utils.getSizeWithScreenRatio(30) height: visible ? (headerMessage.height + headerMessage.topMargin + headerMessage.bottomMargin) : Utils.getSizeWithScreenRatio(
30)
width: headerMessage.width width: headerMessage.width
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
Control.Control { Control.Control {
@ -170,11 +172,11 @@ ListView {
ColumnLayout { ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(2) spacing: Utils.getSizeWithScreenRatio(2)
Text { Text {
text: mainItem.isEncrypted text: mainItem.isEncrypted ?
//: End to end encrypted chat //: End to end encrypted chat
? qsTr("chat_message_list_encrypted_header_title") qsTr("chat_message_list_encrypted_header_title") :
//: This conversation is not encrypted ! //: This conversation is not encrypted !
: qsTr("unencrypted_conversation_warning") qsTr("unencrypted_conversation_warning")
Layout.fillWidth: true Layout.fillWidth: true
color: mainItem.isEncrypted ? DefaultStyle.info_500_main : DefaultStyle.warning_700 color: mainItem.isEncrypted ? DefaultStyle.info_500_main : DefaultStyle.warning_700
font { font {
@ -183,11 +185,11 @@ ListView {
} }
} }
Text { Text {
text: mainItem.isEncrypted text: mainItem.isEncrypted ?
//: Messages in this conversation are e2e encrypted. \n Only your correspondent can decrypt them. //: Messages in this conversation are e2e encrypted. \n Only your correspondent can decrypt them.
? qsTr("chat_message_list_encrypted_header_message") qsTr("chat_message_list_encrypted_header_message") :
//: Messages are not end to end encrypted, \n may sure you don't share any sensitive information ! //: Messages are not end to end encrypted, \n may sure you don't share any sensitive information !
: qsTr("chat_message_list_not_encrypted_header_message") qsTr("chat_message_list_not_encrypted_header_message")
Layout.fillWidth: true Layout.fillWidth: true
color: DefaultStyle.grey_400 color: DefaultStyle.grey_400
font { font {
@ -243,7 +245,6 @@ ListView {
indicatorColor: DefaultStyle.main1_500_main indicatorColor: DefaultStyle.main1_500_main
} }
Dialog { Dialog {
id: messageDeletionDialog id: messageDeletionDialog
width: Utils.getSizeWithScreenRatio(637) width: Utils.getSizeWithScreenRatio(637)
@ -259,8 +260,8 @@ ListView {
text: qsTr("conversation_dialog_delete_locally_label") text: qsTr("conversation_dialog_delete_locally_label")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
messageDeletionDialog.chatMessage.core.lDelete() messageDeletionDialog.chatMessage.core.lDelete();
messageDeletionDialog.close() messageDeletionDialog.close();
} }
KeyNavigation.left: thirdButtonId KeyNavigation.left: thirdButtonId
KeyNavigation.right: secondButtonId KeyNavigation.right: secondButtonId
@ -270,8 +271,8 @@ ListView {
text: qsTr("conversation_dialog_delete_for_everyone_label") text: qsTr("conversation_dialog_delete_for_everyone_label")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
messageDeletionDialog.chatMessage.core.lRetract() messageDeletionDialog.chatMessage.core.lRetract();
messageDeletionDialog.close() messageDeletionDialog.close();
} }
KeyNavigation.left: firstButtonId KeyNavigation.left: firstButtonId
KeyNavigation.right: thirdButtonId KeyNavigation.right: thirdButtonId
@ -281,7 +282,7 @@ ListView {
text: qsTr("dialog_cancel") text: qsTr("dialog_cancel")
style: ButtonStyle.secondary style: ButtonStyle.secondary
onClicked: { onClicked: {
messageDeletionDialog.close() messageDeletionDialog.close();
} }
KeyNavigation.left: secondButtonId KeyNavigation.left: secondButtonId
KeyNavigation.right: firstButtonId KeyNavigation.right: firstButtonId
@ -301,58 +302,54 @@ ListView {
chatMessage: modelData.core.chatMessageGui chatMessage: modelData.core.chatMessageGui
onIsFullyVisibleChanged: { onIsFullyVisibleChanged: {
if (index === 0) { if (index === 0) {
mainItem.lastItemVisible = isFullyVisible mainItem.lastItemVisible = isFullyVisible;
} }
} }
Component.onCompleted: { Component.onCompleted: {
if (index === 0) { if (index === 0) {
mainItem.lastItemVisible = isFullyVisible mainItem.lastItemVisible = isFullyVisible;
} }
} }
chat: mainItem.chat chat: mainItem.chat
searchedTextPart: mainItem.filterText searchedTextPart: mainItem.filterText
maxWidth: Math.round(mainItem.width * (3/4)) maxWidth: Math.round(mainItem.width * (3 / 4))
width: mainItem.width width: mainItem.width
property var previousIndex: index - 1 property var previousIndex: index - 1
property ChatMessageGui nextChatMessage: index <= 0 property ChatMessageGui nextChatMessage: index <= 0 ? null : eventLogProxy.getEventAtIndex(index - 1)
? null ? eventLogProxy.getEventAtIndex(index - 1).core.chatMessageGui : null
: eventLogProxy.getEventAtIndex(index-1) property var previousFromAddress: eventLogProxy.getEventAtIndex(index + 1)?.core.chatMessage?.fromAddress
? eventLogProxy.getEventAtIndex(index-1).core.chatMessageGui
: null
property var previousFromAddress: eventLogProxy.getEventAtIndex(index+1)?.core.chatMessage?.fromAddress
backgroundColor: isRemoteMessage ? DefaultStyle.main2_100 : DefaultStyle.main1_100 backgroundColor: isRemoteMessage ? DefaultStyle.main2_100 : DefaultStyle.main1_100
isFirstMessage: !previousFromAddress || previousFromAddress !== chatMessage.core.fromAddress isFirstMessage: !previousFromAddress || previousFromAddress !== chatMessage.core.fromAddress
anchors.right: !isRemoteMessage && parent anchors.right: !isRemoteMessage && parent ? parent.right : undefined
? parent.right
: undefined
onMessageDeletionRequested: { onMessageDeletionRequested: {
if (chatMessage.core.isOutgoing && chatMessage.core.isRetractable && !chatMessage.core.isRetracted) { if (chatMessage.core.isOutgoing && chatMessage.core.isRetractable && !chatMessage.core.isRetracted) {
messageDeletionDialog.chatMessage = chatMessage messageDeletionDialog.chatMessage = chatMessage;
messageDeletionDialog.open() messageDeletionDialog.open();
} else { } else {
chatMessage.core.lDelete() chatMessage.core.lDelete();
} }
} }
onMessageEditionRequested: mainItem.editMessageRequested(chatMessage) onMessageEditionRequested: mainItem.editMessageRequested(chatMessage)
onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage) onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage)
onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage) onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage)
onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage) onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage)
onSearchMessageByIdRequested: (id) => mainItem.searchMessageByIdRequested(id) onSearchMessageByIdRequested: id => mainItem.searchMessageByIdRequested(id)
onForwardMessageRequested: mainItem.forwardMessageRequested(chatMessage) onForwardMessageRequested: mainItem.forwardMessageRequested(chatMessage)
onEndOfVoiceRecordingReached: { onEndOfVoiceRecordingReached: {
if (nextChatMessage && nextChatMessage.core.isVoiceRecording) mainItem.requestAutoPlayVoiceRecording(index - 1) if (nextChatMessage && nextChatMessage.core.isVoiceRecording)
mainItem.requestAutoPlayVoiceRecording(index - 1);
} }
Connections { Connections {
target: mainItem target: mainItem
function onRequestHighlight(indexToHighlight) { function onRequestHighlight(indexToHighlight) {
if (indexToHighlight === index) { if (indexToHighlight === index) {
requestHighlight() requestHighlight();
} }
} }
function onRequestAutoPlayVoiceRecording(indexToPlay) { function onRequestAutoPlayVoiceRecording(indexToPlay) {
if (indexToPlay === index) { if (indexToPlay === index) {
chatMessageDelegate.requestAutoPlayVoiceRecording() chatMessageDelegate.requestAutoPlayVoiceRecording();
} }
} }
} }
@ -362,7 +359,7 @@ ListView {
if (chatMessage.core.isRetracted && chatMessage.core.isOutgoing) { if (chatMessage.core.isRetracted && chatMessage.core.isOutgoing) {
UtilsCpp.showInformationPopup(qsTr("info_toast_deleted_title"), UtilsCpp.showInformationPopup(qsTr("info_toast_deleted_title"),
//: The message has been deleted //: The message has been deleted
qsTr("info_toast_deleted_message"), true) qsTr("info_toast_deleted_message"), true);
} }
} }
} }
@ -378,7 +375,7 @@ ListView {
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height) property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
onIsFullyVisibleChanged: { onIsFullyVisibleChanged: {
if (index === 0) { if (index === 0) {
mainItem.lastItemVisible = isFullyVisible mainItem.lastItemVisible = isFullyVisible;
} }
} }
property bool showTopMargin: !header.visible && index == 0 property bool showTopMargin: !header.visible && index == 0
@ -403,7 +400,7 @@ ListView {
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height) property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
onIsFullyVisibleChanged: { onIsFullyVisibleChanged: {
if (index === 0) { if (index === 0) {
mainItem.lastItemVisible = isFullyVisible mainItem.lastItemVisible = isFullyVisible;
} }
} }
property bool showTopMargin: !header.visible && index == 0 property bool showTopMargin: !header.visible && index == 0

View file

@ -5,21 +5,22 @@ import Linphone
import UtilsCpp import UtilsCpp
// TODO : into Loader // TODO : into Loader
// ============================================================================= // =============================================================================
TextEdit { TextEdit {
id: mainItem id: mainItem
property ChatMessageContentGui contentGui property ChatMessageContentGui contentGui
property ChatGui chatGui: null property ChatGui chatGui: null
property string lastTextSelected : '' property string lastTextSelected: ''
property string searchedTextPart property string searchedTextPart
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
// force restoring cursor in case we click on a mention, otherwise // force restoring cursor in case we click on a mention, otherwise
// the cursor stays IBeam // the cursor stays IBeam
onVisibleChanged: if (!visible) UtilsCpp.restoreGlobalCursor() onVisibleChanged: if (!visible)
UtilsCpp.restoreGlobalCursor()
font { font {
pixelSize: (contentGui && UtilsCpp.isOnlyEmojis(contentGui.core.text)) ? Typography.h1.pixelSize : Typography.p1.pixelSize pixelSize: (contentGui && UtilsCpp.isOnlyEmojis(contentGui.core.text)) ? Typography.h1.pixelSize :
Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
} }
// property int removeWarningFromBindingLoop : implicitWidth // Just a dummy variable to remove meaningless binding loop on implicitWidth // property int removeWarningFromBindingLoop : implicitWidth // Just a dummy variable to remove meaningless binding loop on implicitWidth
@ -31,58 +32,62 @@ TextEdit {
text: contentGui.core.richFormatText text: contentGui.core.richFormatText
onSearchedTextPartChanged: { onSearchedTextPartChanged: {
contentGui.core.setSearchedTextPart(searchedTextPart) contentGui.core.setSearchedTextPart(searchedTextPart);
} }
textFormat: Text.RichText // To supports links and imgs. textFormat: Text.RichText // To supports links and imgs.
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap
onLinkActivated: (link) => { onLinkActivated: link => {
if (link.startsWith('sip')) if (link.startsWith('sip'))
UtilsCpp.createCall(link) UtilsCpp.createCall(link);
else if (link.startsWith('mention:')) { else if (link.startsWith('mention:')) {
var mentionAddress = link.substring(8) // remove "mention:" var mentionAddress = link.substring(8); // remove "mention:"
UtilsCpp.openContactAtAddress(mentionAddress); UtilsCpp.openContactAtAddress(mentionAddress);
} else
Qt.openUrlExternally(link);
} }
else onSelectedTextChanged: {
Qt.openUrlExternally(link) if (selectedText != '')
} lastTextSelected = selectedText;
onSelectedTextChanged:{
if(selectedText != '') lastTextSelected = selectedText
} }
onLinkHovered: { onLinkHovered: {
if (hoveredLink !== "") UtilsCpp.setGlobalCursor(Qt.PointingHandCursor) if (hoveredLink !== "")
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
} }
onActiveFocusChanged: { onActiveFocusChanged: {
if(activeFocus) { if (activeFocus) {
lastTextSelected = '' lastTextSelected = '';
} } else
else mouseArea.keepLastSelection = false mouseArea.keepLastSelection = false;
// deselect() // deselect()
} }
MouseArea { MouseArea {
id: mouseArea id: mouseArea
property bool keepLastSelection: false property bool keepLastSelection: false
property int lastStartSelection:0 property int lastStartSelection: 0
property int lastEndSelection:0 property int lastEndSelection: 0
anchors.fill: parent anchors.fill: parent
propagateComposedEvents: true propagateComposedEvents: true
hoverEnabled: true hoverEnabled: true
scrollGestureEnabled: false scrollGestureEnabled: false
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.IBeamCursor) if (containsMouse)
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.IBeamCursor);
else
UtilsCpp.restoreGlobalCursor();
} }
cursorShape: mainItem.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor cursorShape: mainItem.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
onPressed: (mouse) => { onPressed: mouse => {
// if(!keepLastSelection) { // if(!keepLastSelection) {
// lastStartSelection = parent.selectionStart // lastStartSelection = parent.selectionStart
// lastEndSelection = parent.selectionEnd // lastEndSelection = parent.selectionEnd
// } // }
keepLastSelection = true keepLastSelection = true;
mouse.accepted = false mouse.accepted = false;
} }
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* MIT License * MIT License
Copyright (c) 2023 AmirHosseinCH Copyright (c) 2023 AmirHosseinCH
@ -27,7 +27,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// import EmojiModel // import EmojiModel
@ -39,8 +39,8 @@ ColumnLayout {
iconsPath: "image://emoji/emojiSvgs/" iconsPath: "image://emoji/emojiSvgs/"
iconsType: '.svg' iconsType: '.svg'
} }
property var categories: ['Smileys & Emotion', 'People & Body', 'Animals & Nature', property var categories: ['Smileys & Emotion', 'People & Body', 'Animals & Nature', 'Food & Drink', 'Activities',
'Food & Drink', 'Activities', 'Travel & Places', 'Objects', 'Symbols', 'Flags'] 'Travel & Places', 'Objects', 'Symbols', 'Flags']
property var searchModel: ListModel {} property var searchModel: ListModel {}
property bool searchMode: false property bool searchMode: false
property int skinColor: -1 property int skinColor: -1
@ -49,17 +49,19 @@ ColumnLayout {
function changeSkinColor(index) { function changeSkinColor(index) {
if (index !== skinColors.current) { if (index !== skinColors.current) {
skinColors.itemAt(skinColors.current + 1).scale = 0.6 skinColors.itemAt(skinColors.current + 1).scale = 0.6;
skinColors.itemAt(index + 1).scale = 1 skinColors.itemAt(index + 1).scale = 1;
skinColors.current = index skinColors.current = index;
mainItem.skinColor = index mainItem.skinColor = index;
} }
} }
function refreshSearchModel() { function refreshSearchModel() {
searchModel.clear() searchModel.clear();
var searchResult = model.search(searchField.text, skinColor) var searchResult = model.search(searchField.text, skinColor);
for (var i = 0; i < searchResult.length; ++i) { for (var i = 0; i < searchResult.length; ++i) {
searchModel.append({path: searchResult[i]}) searchModel.append({
path: searchResult[i]
});
} }
} }
RowLayout { RowLayout {
@ -73,32 +75,32 @@ ColumnLayout {
Image { Image {
id: searchIcon id: searchIcon
source: "image://emoji/icons/search.svg" source: "image://emoji/icons/search.svg"
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(21),Utils.getSizeWithScreenRatio(21)) sourceSize: Qt.size(Utils.getSizeWithScreenRatio(21), Utils.getSizeWithScreenRatio(21))
visible: !mainItem.searchMode visible: !mainItem.searchMode
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
mainItem.searchMode = true mainItem.searchMode = true;
searchField.widthSize = categoriesRow.width - Utils.getSizeWithScreenRatio(25) searchField.widthSize = categoriesRow.width - Utils.getSizeWithScreenRatio(25);
list.model = 1 list.model = 1;
searchField.focus = true searchField.focus = true;
} }
} }
} }
Image { Image {
id: closeIcon id: closeIcon
source: "image://emoji/icons/close.svg" source: "image://emoji/icons/close.svg"
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(21),Utils.getSizeWithScreenRatio(21)) sourceSize: Qt.size(Utils.getSizeWithScreenRatio(21), Utils.getSizeWithScreenRatio(21))
visible: mainItem.searchMode visible: mainItem.searchMode
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
mainItem.searchMode = false mainItem.searchMode = false;
searchField.widthSize = 0 searchField.widthSize = 0;
list.model = mainItem.categories list.model = mainItem.categories;
searchField.clear() searchField.clear();
} }
} }
} }
@ -119,7 +121,7 @@ ColumnLayout {
border.color: DefaultStyle.main1_500_main border.color: DefaultStyle.main1_500_main
} }
onTextChanged: { onTextChanged: {
text.length > 0 ? mainItem.refreshSearchModel() : mainItem.searchModel.clear() text.length > 0 ? mainItem.refreshSearchModel() : mainItem.searchModel.clear();
} }
} }
Repeater { Repeater {
@ -134,22 +136,22 @@ ColumnLayout {
delegate: Image { delegate: Image {
id: icon id: icon
source: "image://emoji/icons/" + cateIcons.blackSvg[index] source: "image://emoji/icons/" + cateIcons.blackSvg[index]
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(20),Utils.getSizeWithScreenRatio(20)) sourceSize: Qt.size(Utils.getSizeWithScreenRatio(20), Utils.getSizeWithScreenRatio(20))
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
if (cateIcons.current !== index) { if (cateIcons.current !== index) {
icon.source = "image://emoji/icons/" + cateIcons.blueSvg[index] icon.source = "image://emoji/icons/" + cateIcons.blueSvg[index];
cateIcons.itemAt(cateIcons.current).source = "image://emoji/icons/" + cateIcons.blackSvg[cateIcons.current] cateIcons.itemAt(cateIcons.current).source = "image://emoji/icons/" + cateIcons.blackSvg[cateIcons.current];
cateIcons.current = index cateIcons.current = index;
} }
list.positionViewAtIndex(index, ListView.Beginning) list.positionViewAtIndex(index, ListView.Beginning);
} }
} }
} }
Component.onCompleted: { Component.onCompleted: {
itemAt(0).source = "image://emoji/icons/" + cateIcons.blueSvg[0] itemAt(0).source = "image://emoji/icons/" + cateIcons.blueSvg[0];
} }
} }
} }
@ -195,7 +197,7 @@ ColumnLayout {
Image { Image {
id: emojiSvg id: emojiSvg
source: mainItem.searchMode ? path : mainItem.model.path(grid.category, index, grid.sc) source: mainItem.searchMode ? path : mainItem.model.path(grid.category, index, grid.sc)
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(30),Utils.getSizeWithScreenRatio(30)) sourceSize: Qt.size(Utils.getSizeWithScreenRatio(30), Utils.getSizeWithScreenRatio(30))
anchors.centerIn: parent anchors.centerIn: parent
asynchronous: true asynchronous: true
} }
@ -206,20 +208,21 @@ ColumnLayout {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
property string imageUrl: emojiSvg.source property string imageUrl: emojiSvg.source
onClicked: { onClicked: {
var emojiInFont = Utils.codepointFromFilename(UtilsCpp.getFilename(emojiSvg.source)) var emojiInFont = Utils.codepointFromFilename(UtilsCpp.getFilename(emojiSvg.source));
if (mainItem.editor) mainItem.editor.insert(mainItem.editor.cursorPosition, emojiInFont) if (mainItem.editor)
mainItem.emojiClicked(emojiInFont) mainItem.editor.insert(mainItem.editor.cursorPosition, emojiInFont);
mainItem.emojiClicked(emojiInFont);
} }
} }
} }
} }
} }
onContentYChanged: { onContentYChanged: {
var index = list.indexAt(0, contentY + 15) var index = list.indexAt(0, contentY + 15);
if (index !== -1 && index !== cateIcons.current) { if (index !== -1 && index !== cateIcons.current) {
cateIcons.itemAt(index).source = "image://emoji/icons/" + cateIcons.blueSvg[index] cateIcons.itemAt(index).source = "image://emoji/icons/" + cateIcons.blueSvg[index];
cateIcons.itemAt(cateIcons.current).source = "image://emoji/icons/" + cateIcons.blackSvg[cateIcons.current] cateIcons.itemAt(cateIcons.current).source = "image://emoji/icons/" + cateIcons.blackSvg[cateIcons.current];
cateIcons.current = index cateIcons.current = index;
} }
} }
} }
@ -249,7 +252,7 @@ ColumnLayout {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
mainItem.changeSkinColor(index - 1) mainItem.changeSkinColor(index - 1);
if (mainItem.searchMode) { if (mainItem.searchMode) {
mainItem.refreshSearchModel(); mainItem.refreshSearchModel();
} }
@ -257,7 +260,7 @@ ColumnLayout {
} }
} }
Component.onCompleted: { Component.onCompleted: {
itemAt(0).scale = 1 itemAt(0).scale = 1;
} }
} }
} }

View file

@ -45,4 +45,3 @@ RowLayout {
color: DefaultStyle.main2_200 color: DefaultStyle.main2_200
} }
} }

View file

@ -4,12 +4,11 @@ import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// ============================================================================= // =============================================================================
Item { Item {
id: mainItem id: mainItem
property ChatMessageContentGui contentGui property ChatMessageContentGui contentGui
@ -17,7 +16,7 @@ Item {
property string name: contentGui && contentGui.core.name property string name: contentGui && contentGui.core.name
property string filePath: contentGui && contentGui.core.filePath property string filePath: contentGui && contentGui.core.filePath
property bool wasDownloaded: contentGui && contentGui.core.wasDownloaded property bool wasDownloaded: contentGui && contentGui.core.wasDownloaded
property bool isAnimatedImage : contentGui && contentGui.core.wasDownloaded && UtilsCpp.isAnimatedImage(filePath) property bool isAnimatedImage: contentGui && contentGui.core.wasDownloaded && UtilsCpp.isAnimatedImage(filePath)
property bool haveThumbnail: contentGui && UtilsCpp.canHaveThumbnail(filePath) && UtilsCpp.fileExists(filePath) property bool haveThumbnail: contentGui && UtilsCpp.canHaveThumbnail(filePath) && UtilsCpp.fileExists(filePath)
property int fileSize: contentGui ? contentGui.core.fileSize : 0 property int fileSize: contentGui ? contentGui.core.fileSize : 0
property bool isTransferring property bool isTransferring
@ -28,23 +27,17 @@ Item {
// property to change default view display // property to change default view display
property bool showAsSquare: true property bool showAsSquare: true
// default image // default image
property var imageSource: mainItem.contentGui property var imageSource: mainItem.contentGui ? UtilsCpp.isImage(mainItem.filePath) ? AppIcons.fileImage :
? UtilsCpp.isImage(mainItem.filePath) UtilsCpp.isPdf(mainItem.filePath) ? AppIcons.filePdf : UtilsCpp.isText(mainItem.filePath)
? AppIcons.fileImage ? AppIcons.fileText : AppIcons.file : ''
: UtilsCpp.isPdf(mainItem.filePath)
? AppIcons.filePdf
: UtilsCpp.isText(mainItem.filePath)
? AppIcons.fileText
: AppIcons.file
: ''
property var thumbnailFillMode: Image.PreserveAspectCrop property var thumbnailFillMode: Image.PreserveAspectCrop
Connections { Connections {
enabled: contentGui enabled: contentGui
target: contentGui ? contentGui.core : null target: contentGui ? contentGui.core : null
function onMsgStateChanged(state) { function onMsgStateChanged(state) {
mainItem.isTransferring = state === LinphoneEnums.ChatMessageState.StateFileTransferInProgress mainItem.isTransferring = state === LinphoneEnums.ChatMessageState.StateFileTransferInProgress || state
|| state === LinphoneEnums.ChatMessageState.StateInProgress === LinphoneEnums.ChatMessageState.StateInProgress;
} }
} }
@ -143,7 +136,7 @@ Item {
AnimatedImage { AnimatedImage {
id: animatedImageSource id: animatedImageSource
mipmap: false//SettingsModel.mipmapEnabled mipmap: false//SettingsModel.mipmapEnabled
source: 'file:/'+ mainItem.filePath source: 'file:/' + mainItem.filePath
autoTransform: true autoTransform: true
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
} }
@ -211,7 +204,8 @@ Item {
id: progressBar id: progressBar
anchors.centerIn: parent anchors.centerIn: parent
to: 100 to: 100
value: mainItem.contentGui ? (mainItem.fileSize>0 ? Math.floor(100 * mainItem.contentGui.core.fileOffset / mainItem.fileSize) : 0) : to value: mainItem.contentGui ? (mainItem.fileSize > 0 ? Math.floor(100 * mainItem.contentGui.core.fileOffset
/ mainItem.fileSize) : 0) : to
visible: mainItem.isTransferring && value != 0 visible: mainItem.isTransferring && value != 0
/* Change format? Current is % /* Change format? Current is %
text: if(mainRow.contentGui){ text: if(mainRow.contentGui){
@ -224,13 +218,15 @@ Item {
*/ */
} }
Rectangle { Rectangle {
visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/ !mainItem.contentGui.core.wasDownloaded) visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/
!mainItem.contentGui.core.wasDownloaded)
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
opacity: 0.5 opacity: 0.5
anchors.fill: parent anchors.fill: parent
} }
EffectImage { EffectImage {
visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/ !mainItem.contentGui.core.wasDownloaded) visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/
!mainItem.contentGui.core.wasDownloaded)
anchors.centerIn: parent anchors.centerIn: parent
imageSource: AppIcons.download imageSource: AppIcons.download
width: Utils.getSizeWithScreenRatio(24) width: Utils.getSizeWithScreenRatio(24)
@ -265,7 +261,6 @@ Item {
width: parent.width / 2 width: parent.width / 2
height: parent.height height: parent.height
radius: parent.radius radius: parent.radius
} }
EffectImage { EffectImage {
z: parent.z + 1 z: parent.z + 1
@ -302,15 +297,8 @@ Item {
Loader { Loader {
id: thumbnailProvider id: thumbnailProvider
anchors.fill: parent anchors.fill: parent
sourceComponent: mainItem.contentGui sourceComponent: mainItem.contentGui ? mainItem.isAnimatedImage ? animatedImage : mainItem.haveThumbnail
? mainItem.isAnimatedImage ? thumbnailImage : mainItem.showAsSquare ? defaultSquareView : defaultView : undefined
? animatedImage
: mainItem.haveThumbnail
? thumbnailImage
: mainItem.showAsSquare
? defaultSquareView
: defaultView
: undefined
states: State { states: State {
name: 'hovered' name: 'hovered'
@ -324,31 +312,32 @@ Item {
// Changing cursor in MouseArea seems not to work with the Loader // Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case // Use override cursor for this case
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor) if (containsMouse)
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
thumbnailProvider.state = containsMouse ? 'hovered' : '' else
UtilsCpp.restoreGlobalCursor();
thumbnailProvider.state = containsMouse ? 'hovered' : '';
} }
onPressed: (mouse) => { onPressed: mouse => {
mouse.accepted = false mouse.accepted = false;
if(mainItem.isTransferring) { if (mainItem.isTransferring) {
mainItem.contentGui.core.lCancelDownloadFile() mainItem.contentGui.core.lCancelDownloadFile();
mouse.accepted = true mouse.accepted = true;
} } else if (!mainItem.contentGui.core.wasDownloaded) {
else if(!mainItem.contentGui.core.wasDownloaded) { mouse.accepted = true;
mouse.accepted = true mainItem.contentGui.core.lDownloadFile();
mainItem.contentGui.core.lDownloadFile()
} else if (Utils.pointIsInItem(this, thumbnailProvider, mouse)) { } else if (Utils.pointIsInItem(this, thumbnailProvider, mouse)) {
mouse.accepted = true mouse.accepted = true;
// if(SettingsModel.isVfsEncrypted){ // if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), { // window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui, // contentGui: mainItem.contentGui,
// }, function (status) { // }, function (status) {
// }) // })
// }else // }else
mainItem.contentGui.core.lOpenFile() mainItem.contentGui.core.lOpenFile();
} else if (mainItem.contentGui) { } else if (mainItem.contentGui) {
mouse.accepted = true mouse.accepted = true;
mainItem.contentGui.core.lOpenFile(true)// Show directory mainItem.contentGui.core.lOpenFile(true);// Show directory
} }
} }
} }

View file

@ -4,11 +4,10 @@ import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// ============================================================================= // =============================================================================
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Separated file to show a single image bigger in chat message // Separated file to show a single image bigger in chat message
// The FileView file does not allow that as it is a Loader and the image // The FileView file does not allow that as it is a Loader and the image
@ -33,18 +32,20 @@ Image {
// Changing cursor in MouseArea seems not to work with the Loader // Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case // Use override cursor for this case
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor) if (containsMouse)
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
} }
onPressed: (mouse) => { onPressed: mouse => {
mouse.accepted = true mouse.accepted = true;
// if(SettingsModel.isVfsEncrypted){ // if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), { // window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui, // contentGui: mainItem.contentGui,
// }, function (status) { // }, function (status) {
// }) // })
// }else // }else
mainItem.contentGui.core.lOpenFile() mainItem.contentGui.core.lOpenFile();
} }
} }
} }

View file

@ -5,7 +5,7 @@ import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// ============================================================================= // =============================================================================
Rectangle { Rectangle {
@ -60,12 +60,14 @@ Rectangle {
// Changing cursor in MouseArea seems not to work with the Loader // Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case // Use override cursor for this case
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor) if (containsMouse)
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
} }
onPressed: (mouse) => { onPressed: mouse => {
mouse.accepted = true mouse.accepted = true;
mainItem.contentGui.core.lOpenFile() mainItem.contentGui.core.lOpenFile();
} }
} }
EffectImage { EffectImage {

View file

@ -63,130 +63,128 @@ Flickable {
signal contactSelected(FriendGui contact) signal contactSelected(FriendGui contact)
function selectContact(address) { function selectContact(address) {
var index = contactsProxy.loadUntil(address) // Be sure to have this address in proxy if it exists var index = contactsProxy.loadUntil(address); // Be sure to have this address in proxy if it exists
if (index != -1) { if (index != -1) {
contactsList.selectIndex(index) contactsList.selectIndex(index);
} }
return index return index;
} }
function addContactToSelection(address) { function addContactToSelection(address) {
if (multiSelectionEnabled) { if (multiSelectionEnabled) {
var indexInSelection = selectedContacts.indexOf(address) var indexInSelection = selectedContacts.indexOf(address);
if (indexInSelection == -1) { if (indexInSelection == -1) {
selectedContacts.push(address) selectedContacts.push(address);
contactAddedToSelection(address) contactAddedToSelection(address);
} }
} }
} }
function removeContactFromSelection(indexInSelection) { function removeContactFromSelection(indexInSelection) {
var addressToRemove = selectedContacts[indexInSelection] var addressToRemove = selectedContacts[indexInSelection];
if (indexInSelection != -1) { if (indexInSelection != -1) {
selectedContacts.splice(indexInSelection, 1) selectedContacts.splice(indexInSelection, 1);
contactRemovedFromSelection(addressToRemove) contactRemovedFromSelection(addressToRemove);
} }
} }
function removeSelectedContactByAddress(address) { function removeSelectedContactByAddress(address) {
var index = selectedContacts.indexOf(address) var index = selectedContacts.indexOf(address);
if (index != -1) { if (index != -1) {
selectedContacts.splice(index, 1) selectedContacts.splice(index, 1);
contactRemovedFromSelection(address) contactRemovedFromSelection(address);
} }
} }
function haveAddress(address) { function haveAddress(address) {
var index = magicSearchProxy.findFriendIndexByAddress(address) var index = magicSearchProxy.findFriendIndexByAddress(address);
return index != -1 return index != -1;
} }
function getFirstContact() { function getFirstContact() {
if (mainItem.showFavorites) { if (mainItem.showFavorites) {
var firstContact = favoritesList.itemAtIndex(0) var firstContact = favoritesList.itemAtIndex(0);
if (firstContact !== null) return firstContact if (firstContact !== null)
return firstContact;
} }
var firstContact = contactsList.itemAtIndex(0) var firstContact = contactsList.itemAtIndex(0);
if (firstContact !== null) return firstContact if (firstContact !== null)
return firstContact;
if (!mainItem.hideSuggestions) { if (!mainItem.hideSuggestions) {
var firstContact = suggestionsList.itemAtIndex(0) var firstContact = suggestionsList.itemAtIndex(0);
if (firstContact !== null) return firstContact if (firstContact !== null)
return firstContact;
} }
return null return null;
} }
function resetSelections() { function resetSelections() {
mainItem.highlightedContact = null mainItem.highlightedContact = null;
favoritesList.currentIndex = -1 favoritesList.currentIndex = -1;
contactsList.currentIndex = -1 contactsList.currentIndex = -1;
suggestionsList.currentIndex = -1 suggestionsList.currentIndex = -1;
} }
function findNextList(item, count, direction) { function findNextList(item, count, direction) {
if (count == 3) if (count == 3)
return null return null;
var nextItem var nextItem;
switch (item) { switch (item) {
case suggestionsList: case suggestionsList:
nextItem = (direction > 0 ? favoritesList : contactsList) nextItem = (direction > 0 ? favoritesList : contactsList);
break break;
case contactsList: case contactsList:
nextItem = (direction > 0 ? suggestionsList : favoritesList) nextItem = (direction > 0 ? suggestionsList : favoritesList);
break break;
case favoritesList: case favoritesList:
nextItem = (direction > 0 ? contactsList : suggestionsList) nextItem = (direction > 0 ? contactsList : suggestionsList);
break break;
default: default:
return null return null;
} }
if (nextItem.model.count > 0) if (nextItem.model.count > 0)
return nextItem return nextItem;
else else
return findNextList(nextItem, count + 1, direction) return findNextList(nextItem, count + 1, direction);
} }
function updatePosition(list) { function updatePosition(list) {
Utils.updatePosition(mainItem, list) Utils.updatePosition(mainItem, list);
} }
onHighlightedContactChanged: { onHighlightedContactChanged: {
favoritesList.highlightedContact = highlightedContact favoritesList.highlightedContact = highlightedContact;
contactsList.highlightedContact = highlightedContact contactsList.highlightedContact = highlightedContact;
suggestionsList.highlightedContact = highlightedContact suggestionsList.highlightedContact = highlightedContact;
} }
onSearchBarTextChanged: { onSearchBarTextChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) { if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText searchText = searchBarText.length === 0 ? "*" : searchBarText;
} }
} }
onPauseSearchChanged: { onPauseSearchChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) { if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText searchText = searchBarText.length === 0 ? "*" : searchBarText;
} }
} }
onSearchTextChanged: { onSearchTextChanged: {
loading = true loading = true;
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (!event.accepted) { if (!event.accepted) {
if (event.key == Qt.Key_Up if (event.key == Qt.Key_Up || event.key == Qt.Key_Down) {
|| event.key == Qt.Key_Down) { var newItem;
var newItem var direction = (event.key == Qt.Key_Up ? -1 : 1);
var direction = (event.key == Qt.Key_Up ? -1 : 1)
if (suggestionsList.activeFocus) if (suggestionsList.activeFocus)
newItem = findNextList(suggestionsList, 0, newItem = findNextList(suggestionsList, 0, direction);
direction)
else if (contactsList.activeFocus) else if (contactsList.activeFocus)
newItem = findNextList(contactsList, 0, newItem = findNextList(contactsList, 0, direction);
direction)
else if (favoritesList.activeFocus) else if (favoritesList.activeFocus)
newItem = findNextList(favoritesList, 0, newItem = findNextList(favoritesList, 0, direction);
direction)
else else
newItem = findNextList(suggestionsList, 0, newItem = findNextList(suggestionsList, 0, direction);
direction)
if (newItem) { if (newItem) {
newItem.selectIndex( newItem.selectIndex(direction > 0 ? -1 : newItem.model.count - 1, direction > 0 ? Qt.BacktabFocusReason :
direction > 0 ? -1 : newItem.model.count - 1, direction > 0 ? Qt.BacktabFocusReason : Qt.TabFocusReason) Qt.TabFocusReason);
event.accepted = true event.accepted = true;
} }
} }
} }
@ -194,8 +192,7 @@ Flickable {
Component.onCompleted: { Component.onCompleted: {
if (confInfoGui) { if (confInfoGui) {
for (var i = 0; i < confInfoGui.core.participants.length; ++i) { for (var i = 0; i < confInfoGui.core.participants.length; ++i) {
selectedContacts.push( selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i));
confInfoGui.core.getParticipantAddressAt(i))
} }
} }
} }
@ -204,7 +201,7 @@ Flickable {
target: SettingsCpp target: SettingsCpp
onLdapConfigChanged: { onLdapConfigChanged: {
if (SettingsCpp.syncLdapContacts) if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate() magicSearchProxy.forceUpdate();
} }
} }
@ -214,29 +211,28 @@ Flickable {
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
sourceFlags: mainItem.sourceFlags sourceFlags: mainItem.sourceFlags
onModelReset: { onModelReset: {
mainItem.resetSelections() mainItem.resetSelections();
} }
onResultsProcessed: { onResultsProcessed: {
mainItem.loading = false mainItem.loading = false;
mainItem.contentY = 0 mainItem.contentY = 0;
} }
onInitialized: { onInitialized: {
if (mainItem.searchOnEmpty || searchText != '') { if (mainItem.searchOnEmpty || searchText != '') {
mainItem.loading = true mainItem.loading = true;
forceUpdate() forceUpdate();
} }
} }
} }
onAtYEndChanged: if (atYEnd) { onAtYEndChanged: if (atYEnd) {
if (favoritesProxy.haveMore && favoritesList.expanded && mainItem.showFavorites) if (favoritesProxy.haveMore && favoritesList.expanded && mainItem.showFavorites)
favoritesProxy.displayMore() favoritesProxy.displayMore();
else if (contactsProxy.haveMore && contactsList.expanded) { else if (contactsProxy.haveMore && contactsList.expanded) {
contactsProxy.displayMore() contactsProxy.displayMore();
} } else
else suggestionsProxy.displayMore();
suggestionsProxy.displayMore()
} }
Behavior on contentY { Behavior on contentY {
NumberAnimation { NumberAnimation {
@ -292,19 +288,17 @@ Flickable {
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => { onContactSelected: contactGui => {
mainItem.contactSelected(contactGui) mainItem.contactSelected(contactGui);
} }
onUpdatePosition: mainItem.updatePosition(favoritesList) onUpdatePosition: mainItem.updatePosition(favoritesList)
onContactDeletionRequested: contact => { onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested( mainItem.contactDeletionRequested(contact);
contact)
} }
onAddContactToSelection: address => { onAddContactToSelection: address => {
mainItem.addContactToSelection(address) mainItem.addContactToSelection(address);
} }
onRemoveContactFromSelection: index => { onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection( mainItem.removeContactFromSelection(index);
index)
} }
property MagicSearchProxy proxy: MagicSearchProxy { property MagicSearchProxy proxy: MagicSearchProxy {
@ -313,9 +307,7 @@ Flickable {
showMe: mainItem.showMe showMe: mainItem.showMe
filterType: MagicSearchProxy.FilteringTypes.Favorites filterType: MagicSearchProxy.FilteringTypes.Favorites
} }
model: mainItem.showFavorites model: mainItem.showFavorites && (mainItem.searchBarText == '' || mainItem.searchBarText == '*') ? proxy : []
&& (mainItem.searchBarText == ''
|| mainItem.searchBarText == '*') ? proxy : []
} }
ContactListView { ContactListView {
@ -339,32 +331,29 @@ Flickable {
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => { onContactSelected: contactGui => {
mainItem.contactSelected(contactGui) mainItem.contactSelected(contactGui);
} }
onUpdatePosition: mainItem.updatePosition(contactsList) onUpdatePosition: mainItem.updatePosition(contactsList)
onContactDeletionRequested: contact => { onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested( mainItem.contactDeletionRequested(contact);
contact)
} }
onAddContactToSelection: address => { onAddContactToSelection: address => {
mainItem.addContactToSelection(address) mainItem.addContactToSelection(address);
} }
onRemoveContactFromSelection: index => { onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection( mainItem.removeContactFromSelection(index);
index)
} }
model: MagicSearchProxy { model: MagicSearchProxy {
id: contactsProxy id: contactsProxy
parentProxy: mainItem.mainModel parentProxy: mainItem.mainModel
filterType: MagicSearchProxy.FilteringTypes.App filterType: MagicSearchProxy.FilteringTypes.App | (mainItem.searchText != '*' && mainItem.searchText != ''
| (mainItem.searchText != '*' || SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap
&& mainItem.searchText != '' | MagicSearchProxy.FilteringTypes.CardDAV : 0)
|| SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap | MagicSearchProxy.FilteringTypes.CardDAV : 0)
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63))) initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
displayItemsStep: 3 * initialDisplayItems / 2 displayItemsStep: 3 * initialDisplayItems / 2
onLocalFriendCreated: (index) => { onLocalFriendCreated: index => {
contactsList.selectIndex(index) contactsList.selectIndex(index);
} }
} }
} }
@ -390,27 +379,24 @@ Flickable {
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => { onContactSelected: contactGui => {
mainItem.contactSelected(contactGui) mainItem.contactSelected(contactGui);
} }
onUpdatePosition: mainItem.updatePosition(suggestionsList) onUpdatePosition: mainItem.updatePosition(suggestionsList)
onContactDeletionRequested: contact => { onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested( mainItem.contactDeletionRequested(contact);
contact)
} }
onAddContactToSelection: address => { onAddContactToSelection: address => {
mainItem.addContactToSelection(address) mainItem.addContactToSelection(address);
} }
onRemoveContactFromSelection: index => { onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection( mainItem.removeContactFromSelection(index);
index)
} }
model: MagicSearchProxy { model: MagicSearchProxy {
id: suggestionsProxy id: suggestionsProxy
parentProxy: mainItem.mainModel parentProxy: mainItem.mainModel
filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other
initialDisplayItems: contactsProxy.haveMore && contactsList.expanded initialDisplayItems: contactsProxy.haveMore && contactsList.expanded ? 0 : Math.max(20, Math.round(2
? 0 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
onInitialDisplayItemsChanged: maxDisplayItems = initialDisplayItems onInitialDisplayItemsChanged: maxDisplayItems = initialDisplayItems
displayItemsStep: 3 * initialDisplayItems / 2 displayItemsStep: 3 * initialDisplayItems / 2
onModelReset: maxDisplayItems = initialDisplayItems onModelReset: maxDisplayItems = initialDisplayItems

View file

@ -11,34 +11,21 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// Fill contact, account or call // Fill contact, account or call
// Initials will be displayed if there isn't any avatar. // Initials will be displayed if there isn't any avatar.
// TODO : get FriendGui from Call. // TODO : get FriendGui from Call.
Loader{ Loader {
id: mainItem id: mainItem
property AccountGui account: null property AccountGui account: null
property FriendGui contact: null property FriendGui contact: null
property CallGui call: null property CallGui call: null
property bool isConference: false property bool isConference: false
property bool shadowEnabled: true property bool shadowEnabled: true
property var _address: account property var _address: account ? account.core?.identityAddress || "" : call ? call.core.remoteAddress : contact
? account.core?.identityAddress || "" ? contact.core.defaultAddress : ''
: call
? call.core.remoteAddress
: contact
? contact.core.defaultAddress
: ''
readonly property var address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_address) : _address readonly property var address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_address) : _address
property var displayNameObj: UtilsCpp.getDisplayName(_address) property var displayNameObj: UtilsCpp.getDisplayName(_address)
property var displayNameVal: account && account.core.displayName property var displayNameVal: account && account.core.displayName ? account.core.displayName : contact && contact.core.fullName
? account.core.displayName ? contact.core.fullName : displayNameObj ? displayNameObj.value : ""
: contact && contact.core.fullName property bool haveAvatar: account ? account.core.pictureUri : contact ? contact.core.pictureUri :
? contact.core.fullName computedAvatarUri.length != 0
: displayNameObj
? displayNameObj.value
: ""
property bool haveAvatar: account
? account.core.pictureUri
: contact
? contact.core.pictureUri
: computedAvatarUri.length != 0
property var avatarObj: UtilsCpp.findAvatarByAddress(_address) property var avatarObj: UtilsCpp.findAvatarByAddress(_address)
property string computedAvatarUri: avatarObj ? avatarObj.value : '' property string computedAvatarUri: avatarObj ? avatarObj.value : ''
@ -51,17 +38,15 @@ Loader{
// override it as secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified // override it as secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address) property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address)
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp ? call.core.tokenVerified :
? call.core.tokenVerified contact ? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount
: contact === contact.core.devices.length : false
? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount === contact.core.devices.length
: false
property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe
property bool displayPresence: true property bool displayPresence: true
asynchronous: true asynchronous: true
sourceComponent: Component{ sourceComponent: Component {
Item { Item {
anchors.fill: parent anchors.fill: parent
@ -81,10 +66,11 @@ Loader{
initialItem: mainItem.haveAvatar ? avatar : initials initialItem: mainItem.haveAvatar ? avatar : initials
anchors.fill: parent anchors.fill: parent
Connections{ Connections {
target: mainItem target: mainItem
onHaveAvatarChanged: { onHaveAvatarChanged: {
stackView.replace(mainItem.haveAvatar ? avatar : initials, StackView.Immediate)} stackView.replace(mainItem.haveAvatar ? avatar : initials, StackView.Immediate);
}
} }
Rectangle { Rectangle {
@ -104,13 +90,12 @@ Loader{
height: width height: width
imageSource: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted imageSource: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
} }
} }
Image { Image {
visible: mainItem.displayPresence visible: mainItem.displayPresence
width: stackView.width/4.5 width: stackView.width / 4.5
height: width height: width
sourceSize.width: width sourceSize.width: width
sourceSize.height: width sourceSize.height: width
@ -119,13 +104,8 @@ Loader{
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: stackView.width / 15 anchors.rightMargin: stackView.width / 15
z: 1 z: 1
source: account source: account ? (account.core?.registrationState !== LinphoneEnums.RegistrationState.Ok ? account.core?.registrationIcon :
? (account.core?.registrationState !== LinphoneEnums.RegistrationState.Ok account.core?.presenceIcon) : (contact ? contact.core?.presenceIcon : "")
? account.core?.registrationIcon
: account.core?.presenceIcon)
: (contact
? contact.core?.presenceIcon
: "")
RotationAnimator on rotation { RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
direction: RotationAnimator.Clockwise direction: RotationAnimator.Clockwise
@ -135,10 +115,9 @@ Loader{
duration: 10000 duration: 10000
} }
} }
} }
Component{ Component {
id: initials id: initials
Item { Item {
id: avatarItem id: avatarItem
@ -146,7 +125,8 @@ Loader{
width: height width: height
Rectangle { Rectangle {
id: initialItem id: initialItem
property string initials: mainItem.isConference || (mainItem.displayNameVal && mainItem.displayNameVal[0] === "+") ? "" : UtilsCpp.getInitials(mainItem.displayNameVal) property string initials: mainItem.isConference || (mainItem.displayNameVal && mainItem.displayNameVal[0]
=== "+") ? "" : UtilsCpp.getInitials(mainItem.displayNameVal)
radius: width / 2 radius: width / 2
color: DefaultStyle.main2_200 color: DefaultStyle.main2_200
height: stackView.height height: stackView.height
@ -167,7 +147,7 @@ Loader{
EffectImage { EffectImage {
id: initialImg id: initialImg
visible: initialItem.initials === "" || initialItem.initials[0] === "+" visible: initialItem.initials === "" || initialItem.initials[0] === "+"
width: stackView.width/2 width: stackView.width / 2
height: width height: width
colorizationColor: DefaultStyle.main2_600 colorizationColor: DefaultStyle.main2_600
imageSource: mainItem.isConference ? AppIcons.videoconference : AppIcons.profile imageSource: mainItem.isConference ? AppIcons.videoconference : AppIcons.profile
@ -188,7 +168,7 @@ Loader{
} }
} }
} }
Component{ Component {
id: avatar id: avatar
Item { Item {
id: avatarItem id: avatarItem
@ -204,11 +184,8 @@ Loader{
sourceSize.height: avatarItem.height sourceSize.height: avatarItem.height
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
anchors.centerIn: parent anchors.centerIn: parent
source: mainItem.account source: mainItem.account ? mainItem.account.core.pictureUri : mainItem.contact ? mainItem.contact.core.pictureUri :
? mainItem.account.core.pictureUri computedAvatarUri
: mainItem.contact
? mainItem.contact.core.pictureUri
: computedAvatarUri
mipmap: true mipmap: true
layer.enabled: true layer.enabled: true
} }

View file

@ -4,15 +4,14 @@ import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import CustomControls 1.0 import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.Control{ Control.Control {
id: mainItem id: mainItem
activeFocusOnTab: true activeFocusOnTab: true
padding: Utils.getSizeWithScreenRatio(10) padding: Utils.getSizeWithScreenRatio(10)
@ -37,22 +36,25 @@ Control.Control{
property real borderWidth: Utils.getSizeWithScreenRatio(1) property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
signal avatarClicked() signal avatarClicked
signal backgroundClicked() signal backgroundClicked
signal edit() signal edit
background: Rectangle { background: Rectangle {
radius: Utils.getSizeWithScreenRatio(10) radius: Utils.getSizeWithScreenRatio(10)
color: mainItem.isSelected ? mainItem.selectedBackgroundColor : hovered ? mainItem.hoveredBackgroundColor : mainItem.defaultBackgroundColor color: mainItem.isSelected ? mainItem.selectedBackgroundColor : hovered ? mainItem.hoveredBackgroundColor :
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.isSelected ? mainItem.selectedBorderColor : hovered ? mainItem.hoveredBorderColor : mainItem.defaultBorderColor mainItem.defaultBackgroundColor
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.isSelected
? mainItem.selectedBorderColor : hovered ? mainItem.hoveredBorderColor : mainItem.defaultBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
MouseArea{ MouseArea {
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
onClicked: mainItem.backgroundClicked() onClicked: mainItem.backgroundClicked()
} }
} }
contentItem: RowLayout{ contentItem: RowLayout {
spacing: 0 spacing: 0
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
@ -62,17 +64,17 @@ Control.Control{
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
color: "transparent" color: "transparent"
contentItem: Item{ contentItem: Item {
anchors.fill: parent anchors.fill: parent
width: avatarButton.width width: avatarButton.width
height: avatarButton.height height: avatarButton.height
Avatar{ Avatar {
id: avatar id: avatar
height: avatarButton.height height: avatarButton.height
width: avatarButton.width width: avatarButton.width
account: mainItem.account account: mainItem.account
} }
Rectangle{ Rectangle {
// Black border for keyboard navigation // Black border for keyboard navigation
visible: avatarButton.keyboardFocus visible: avatarButton.keyboardFocus
width: avatarButton.width width: avatarButton.width
@ -88,7 +90,7 @@ Control.Control{
Layout.preferredWidth: Utils.getSizeWithScreenRatio(200) Layout.preferredWidth: Utils.getSizeWithScreenRatio(200)
Layout.fillHeight: true Layout.fillHeight: true
Layout.rightMargin: Utils.getSizeWithScreenRatio(10) Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
ContactDescription{ ContactDescription {
id: description id: description
anchors.fill: parent anchors.fill: parent
account: mainItem.account account: mainItem.account
@ -100,7 +102,7 @@ Control.Control{
Layout.maximumWidth: Utils.getSizeWithScreenRatio(150) Layout.maximumWidth: Utils.getSizeWithScreenRatio(150)
width: contactStatusPopup.width width: contactStatusPopup.width
height: contactStatusPopup.height height: contactStatusPopup.height
ContactStatusPopup{ ContactStatusPopup {
id: contactStatusPopup id: contactStatusPopup
visible: mainItem.account.core.publishEnabled visible: mainItem.account.core.publishEnabled
} }
@ -111,22 +113,22 @@ Control.Control{
onClicked: mainItem.account.core.lSetRegisterEnabled(true) onClicked: mainItem.account.core.lSetRegisterEnabled(true)
} }
} }
Item{ Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(26) Layout.preferredWidth: Utils.getSizeWithScreenRatio(26)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(26) Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
Layout.fillHeight: true Layout.fillHeight: true
Layout.leftMargin: Utils.getSizeWithScreenRatio(40) Layout.leftMargin: Utils.getSizeWithScreenRatio(40)
visible: mainItem.account.core.unreadNotifications > 0 visible: mainItem.account.core.unreadNotifications > 0
Rectangle{ Rectangle {
id: unreadNotifications id: unreadNotifications
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: Utils.getSizeWithScreenRatio(26) width: Utils.getSizeWithScreenRatio(26)
height: Utils.getSizeWithScreenRatio(26) height: Utils.getSizeWithScreenRatio(26)
radius: width/2 radius: width / 2
color: DefaultStyle.danger_500_main color: DefaultStyle.danger_500_main
border.color: DefaultStyle.grey_0 border.color: DefaultStyle.grey_0
border.width: Utils.getSizeWithScreenRatio(2) border.width: Utils.getSizeWithScreenRatio(2)
Text{ Text {
id: unreadCount id: unreadCount
anchors.fill: parent anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(2) anchors.margins: Utils.getSizeWithScreenRatio(2)
@ -159,15 +161,17 @@ Control.Control{
voicemailCount: mainItem.account.core.voicemailCount voicemailCount: mainItem.account.core.voicemailCount
onClicked: { onClicked: {
if (mainItem.account.core.voicemailAddress.length > 0) if (mainItem.account.core.voicemailAddress.length > 0)
UtilsCpp.createCall(mainItem.account.core.voicemailAddress) UtilsCpp.createCall(mainItem.account.core.voicemailAddress);
else else
//: Erreur //: Erreur
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: L'URI de messagerie vocale n'est pas définie. //: L'URI de messagerie vocale n'est pas définie.
qsTr("information_popup_voicemail_address_undefined_message"), false) qsTr("information_popup_voicemail_address_undefined_message"), false);
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
Button { Button {
id: manageAccount id: manageAccount
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
@ -180,7 +184,7 @@ Control.Control{
//: Account settings of %1 //: Account settings of %1
Accessible.name: qsTr("account_settings_name_accessible_name") Accessible.name: qsTr("account_settings_name_accessible_name")
onClicked: { onClicked: {
mainItem.edit() mainItem.edit();
} }
} }
} }

View file

@ -20,7 +20,8 @@ FocusScope {
property bool showActions: false // Display actions layout (call buttons) property bool showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts. property bool showContactMenu: true // Display the dot menu for contacts.
property string highlightText property string highlightText
property string addressFromFilter: UtilsCpp.getAddressToDisplay(searchResultItem.core.addresses, highlightText, searchResultItem.core.defaultAddress) property string addressFromFilter: UtilsCpp.getAddressToDisplay(searchResultItem.core.addresses, highlightText,
searchResultItem.core.defaultAddress)
// Bold characters in Display name. // Bold characters in Display name.
property bool displayNameCapitalization: true // Capitalize display name. property bool displayNameCapitalization: true // Capitalize display name.
@ -36,8 +37,9 @@ FocusScope {
// Use directly previous initial // Use directly previous initial
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39) property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property var displayName: searchResultItem? searchResultItem.core.fullName : "" property var displayName: searchResultItem ? searchResultItem.core.fullName : ""
property var initial: displayName.length > 0 ? UtilsCpp.getInitials(displayName, 1).toLocaleLowerCase(AppCpp.localeAsString) : '' property var initial: displayName.length > 0 ? UtilsCpp.getInitials(displayName, 1).toLocaleLowerCase(AppCpp.localeAsString) :
''
signal clicked(var mouse) signal clicked(var mouse)
signal contactDeletionRequested(FriendGui contact) signal contactDeletionRequested(FriendGui contact)
@ -45,6 +47,7 @@ FocusScope {
Accessible.name: displayName Accessible.name: displayName
MouseArea { MouseArea {
id: contactArea
Text { Text {
id: initialText id: initialText
anchors.left: parent.left anchors.left: parent.left
@ -85,9 +88,8 @@ FocusScope {
id: displayNameText id: displayNameText
visible: mainItem.showDisplayName visible: mainItem.showDisplayName
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: visible ? implicitHeight: 0 Layout.preferredHeight: visible ? implicitHeight : 0
text: UtilsCpp.boldTextPart(UtilsCpp.encodeEmojiToQmlRichFormat((mainItem.displayName)), text: UtilsCpp.boldTextPart(UtilsCpp.encodeEmojiToQmlRichFormat((mainItem.displayName)), mainItem.highlightText)
mainItem.highlightText)
textFormat: Text.RichText textFormat: Text.RichText
font { font {
pixelSize: mainItem.showDefaultAddress ? Typography.h4.pixelSize : Typography.p1.pixelSize pixelSize: mainItem.showDefaultAddress ? Typography.h4.pixelSize : Typography.p1.pixelSize
@ -99,11 +101,10 @@ FocusScope {
Text { Text {
Layout.topMargin: Utils.getSizeWithScreenRatio(2) Layout.topMargin: Utils.getSizeWithScreenRatio(2)
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: visible ? implicitHeight: 0 Layout.preferredHeight: visible ? implicitHeight : 0
visible: mainItem.showDefaultAddress visible: mainItem.showDefaultAddress
property string address: SettingsCpp.hideSipAddresses property string address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(mainItem.addressFromFilter) :
? UtilsCpp.getUsername(mainItem.addressFromFilter) mainItem.addressFromFilter
: mainItem.addressFromFilter
text: UtilsCpp.boldTextPart(address, mainItem.highlightText) text: UtilsCpp.boldTextPart(address, mainItem.highlightText)
textFormat: Text.AutoText textFormat: Text.AutoText
maximumLineCount: 1 maximumLineCount: 1
@ -126,8 +127,7 @@ FocusScope {
Layout.rightMargin: Utils.getSizeWithScreenRatio(5) Layout.rightMargin: Utils.getSizeWithScreenRatio(5)
EffectImage { EffectImage {
id: isSelectedCheck id: isSelectedCheck
visible: mainItem.multiSelectionEnabled visible: mainItem.multiSelectionEnabled && (mainItem.selectedContacts.indexOf(mainItem.addressFromFilter) != -1)
&& (mainItem.selectedContacts.indexOf(mainItem.addressFromFilter) != -1)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageSource: AppIcons.check imageSource: AppIcons.check
@ -165,7 +165,9 @@ FocusScope {
focus: visible && !callButton.visible focus: visible && !callButton.visible
radius: Utils.getSizeWithScreenRatio(40) radius: Utils.getSizeWithScreenRatio(40)
style: ButtonStyle.grey style: ButtonStyle.grey
onClicked: UtilsCpp.createCall(mainItem.addressFromFilter, {"localVideoEnabled": true}) onClicked: UtilsCpp.createCall(mainItem.addressFromFilter, {
"localVideoEnabled": true
})
KeyNavigation.left: callButton KeyNavigation.left: callButton
KeyNavigation.right: chatButton KeyNavigation.right: chatButton
//: "Video call %1" //: "Video call %1"
@ -174,22 +176,20 @@ FocusScope {
} }
IconButton { IconButton {
id: chatButton id: chatButton
visible: actionButtons.visible visible: actionButtons.visible && !SettingsCpp.disableChatFeature
&& !SettingsCpp.disableChatFeature
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
icon.width: Utils.getSizeWithScreenRatio(24) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24) icon.height: Utils.getSizeWithScreenRatio(24)
icon.source: AppIcons.chatTeardropText icon.source: AppIcons.chatTeardropText
focus: visible && !callButton.visible focus: visible && !callButton.visible && !videoCallButton.visible
&& !videoCallButton.visible
radius: Utils.getSizeWithScreenRatio(40) radius: Utils.getSizeWithScreenRatio(40)
style: ButtonStyle.grey style: ButtonStyle.grey
KeyNavigation.left: videoCallButton KeyNavigation.left: videoCallButton
KeyNavigation.right: callButton KeyNavigation.right: callButton
onClicked: { onClicked: {
console.debug("[ContactListItem.qml] Open conversation") console.debug("[ContactListItem.qml] Open conversation");
mainWindow.displayChatPage(mainItem.addressFromFilter) mainWindow.displayChatPage(mainItem.addressFromFilter);
} }
//: "Message %1" //: "Message %1"
Accessible.name: qsTr("message_with_contact_name_accessible_button").arg(mainItem.displayName) Accessible.name: qsTr("message_with_contact_name_accessible_button").arg(mainItem.displayName)
@ -201,27 +201,26 @@ FocusScope {
z: contactArea.z + 1 z: contactArea.z + 1
popup.x: 0 popup.x: 0
popup.padding: Utils.getSizeWithScreenRatio(10) popup.padding: Utils.getSizeWithScreenRatio(10)
visible: mainItem.showContactMenu && (contactArea.containsMouse || mainItem.isLastHovered || hovered || popup.opened) visible: mainItem.showContactMenu && (contactArea.containsMouse || mainItem.isLastHovered || hovered
|| popup.opened)
enabled: visible enabled: visible
popup.contentItem: ColumnLayout { popup.contentItem: ColumnLayout {
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
visible: searchResultItem && searchResultItem.core.isStored visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly
&& !searchResultItem.core.readOnly
//: "Enlever des favoris" //: "Enlever des favoris"
text: searchResultItem.core.starred ? qsTr("contact_details_remove_from_favourites") text: searchResultItem.core.starred ? qsTr("contact_details_remove_from_favourites") :
//: "Ajouter aux favoris" //: "Ajouter aux favoris"
: qsTr("contact_details_add_to_favourites") qsTr("contact_details_add_to_favourites")
icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
textColor: DefaultStyle.main2_500_main textColor: DefaultStyle.main2_500_main
hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700 hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700
contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500_main : DefaultStyle.main2_600 contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
onClicked: { onClicked: {
searchResultItem.core.lSetStarred( searchResultItem.core.lSetStarred(!searchResultItem.core.starred);
!searchResultItem.core.starred) friendPopup.close();
friendPopup.close()
} }
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
} }
@ -232,24 +231,20 @@ FocusScope {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
textColor: DefaultStyle.main2_500_main textColor: DefaultStyle.main2_500_main
onClicked: { onClicked: {
var vcard = searchResultItem.core.getVCard() var vcard = searchResultItem.core.getVCard();
var username = searchResultItem.core.givenName var username = searchResultItem.core.givenName + searchResultItem.core.familyName;
+ searchResultItem.core.familyName var filepath = UtilsCpp.createVCardFile(username, vcard);
var filepath = UtilsCpp.createVCardFile(
username, vcard)
if (filepath == "") if (filepath == "")
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
qsTr("information_popup_error_title"),
//: La création du fichier vcard a échoué //: La création du fichier vcard a échoué
qsTr("information_popup_vcard_creation_error"), qsTr("information_popup_vcard_creation_error"), false);
false)
else else
//: VCard créée //: VCard créée
mainWindow.showInformationPopup(qsTr("information_popup_vcard_creation_title"), mainWindow.showInformationPopup(qsTr("information_popup_vcard_creation_title"),
//: "VCard du contact enregistrée dans %1" //: "VCard du contact enregistrée dans %1"
qsTr("information_popup_vcard_creation_success").arg(filepath)) qsTr("information_popup_vcard_creation_success").arg(filepath));
//: Partage de contact //: Partage de contact
UtilsCpp.shareByEmail(qsTr("contact_sharing_email_title"),vcard, filepath) UtilsCpp.shareByEmail(qsTr("contact_sharing_email_title"), vcard, filepath);
} }
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
} }
@ -261,8 +256,8 @@ FocusScope {
visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly
Layout.fillWidth: true Layout.fillWidth: true
onClicked: { onClicked: {
mainItem.contactDeletionRequested(searchResultItem) mainItem.contactDeletionRequested(searchResultItem);
friendPopup.close() friendPopup.close();
} }
style: ButtonStyle.noBackgroundRed style: ButtonStyle.noBackgroundRed
} }
@ -270,8 +265,6 @@ FocusScope {
} }
} }
} }
id: contactArea
enabled: mainItem.selectionEnabled enabled: mainItem.selectionEnabled
anchors.fill: parent anchors.fill: parent
//height: mainItem.height //height: mainItem.height
@ -279,7 +272,7 @@ FocusScope {
acceptedButtons: Qt.AllButtons acceptedButtons: Qt.AllButtons
focus: !actionButtons.visible focus: !actionButtons.visible
onContainsMouseChanged: { onContainsMouseChanged: {
mainItem.containsMouseChanged(containsMouse) mainItem.containsMouseChanged(containsMouse);
} }
Rectangle { Rectangle {
anchors.fill: contactArea anchors.fill: contactArea
@ -289,20 +282,18 @@ FocusScope {
visible: mainItem.isLastHovered || mainItem.isSelected || friendPopup.hovered visible: mainItem.isLastHovered || mainItem.isSelected || friendPopup.hovered
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key == Qt.Key_Space if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
|| event.key == Qt.Key_Enter contactArea.clicked(undefined);
|| event.key == Qt.Key_Return) { event.accepted = true;
contactArea.clicked(undefined)
event.accepted = true
} }
} }
onClicked: mouse => { onClicked: mouse => {
forceActiveFocus() forceActiveFocus();
if (mouse && mouse.button == Qt.RightButton if (mouse && mouse.button == Qt.RightButton && mainItem.showContactMenu) {
&& mainItem.showContactMenu) { if (friendPopup)
if (friendPopup) friendPopup.open() friendPopup.open();
} else { } else {
mainItem.clicked(mouse) mainItem.clicked(mouse);
} }
} }
} }

View file

@ -6,8 +6,8 @@ import Linphone
import UtilsCpp 1.0 import UtilsCpp 1.0
import ConstantsCpp 1.0 import ConstantsCpp 1.0
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ListView { ListView {
id: mainItem id: mainItem
@ -50,7 +50,7 @@ ListView {
signal contactSelected(FriendGui contact) // Click/Space/Enter signal contactSelected(FriendGui contact) // Click/Space/Enter
signal addContactToSelection(var address) signal addContactToSelection(var address)
signal removeContactFromSelection(var indexInSelection) signal removeContactFromSelection(var indexInSelection)
signal updatePosition() signal updatePosition
clip: true clip: true
highlightFollowsCurrentItem: false highlightFollowsCurrentItem: false
@ -58,7 +58,8 @@ ListView {
implicitHeight: contentHeight implicitHeight: contentHeight
spacing: expanded ? Utils.getSizeWithScreenRatio(4) : 0 spacing: expanded ? Utils.getSizeWithScreenRatio(4) : 0
onVisibleChanged: if (visible && !expanded) expanded = true onVisibleChanged: if (visible && !expanded)
expanded = true
onYChanged: updatePosition() onYChanged: updatePosition()
@ -68,41 +69,44 @@ ListView {
property bool _moveToIndex: false property bool _moveToIndex: false
function selectIndex(index, focusReason = Qt.OtherFocusReason){ function selectIndex(index, focusReason = Qt.OtherFocusReason) {
if(mainItem.expanded && index >= 0){ if (mainItem.expanded && index >= 0) {
mainItem.currentIndex = index mainItem.currentIndex = index;
var item = itemAtIndex(mainItem.currentIndex) var item = itemAtIndex(mainItem.currentIndex);
if(item){// Item is ready and available if (item) {
mainItem.highlightedContact = item.searchResultItem // Item is ready and available
item.forceActiveFocus(focusReason) mainItem.highlightedContact = item.searchResultItem;
updatePosition() item.forceActiveFocus(focusReason);
_moveToIndex = false updatePosition();
}else{// Move on the next items load. _moveToIndex = false;
} else {
// Move on the next items load.
// If visible, try to wait loading // If visible, try to wait loading
_moveToIndex = visible _moveToIndex = visible;
} }
}else{ } else {
mainItem.currentIndex = -1 mainItem.currentIndex = -1;
mainItem.highlightedContact = null mainItem.highlightedContact = null;
if(headerItem) { if (headerItem) {
headerItem.forceActiveFocus(focusReason) headerItem.forceActiveFocus(focusReason);
} }
_moveToIndex = false _moveToIndex = false;
} }
} }
onContactSelected: updatePosition() onContactSelected: updatePosition()
onExpandedChanged: if(!expanded) updatePosition() onExpandedChanged: if (!expanded)
updatePosition()
keyNavigationEnabled: false keyNavigationEnabled: false
Keys.onPressed: (event)=> { Keys.onPressed: event => {
if(event.key == Qt.Key_Up || event.key == Qt.Key_Down){ if (event.key == Qt.Key_Up || event.key == Qt.Key_Down) {
if(event.key == Qt.Key_Up && !headerItem.activeFocus) { if (event.key == Qt.Key_Up && !headerItem.activeFocus) {
if(currentIndex >= 0 ) { if (currentIndex >= 0) {
selectIndex(mainItem.currentIndex-1, Qt.BacktabFocusReason) selectIndex(mainItem.currentIndex - 1, Qt.BacktabFocusReason);
event.accepted = true; event.accepted = true;
} }
}else if(event.key == Qt.Key_Down && mainItem.expanded){ } else if (event.key == Qt.Key_Down && mainItem.expanded) {
if(currentIndex < model.count - 1) { if (currentIndex < model.count - 1) {
selectIndex(mainItem.currentIndex+1, Qt.TabFocusReason) selectIndex(mainItem.currentIndex + 1, Qt.TabFocusReason);
event.accepted = true; event.accepted = true;
} }
} }
@ -110,7 +114,7 @@ ListView {
} }
Component.onCompleted: { Component.onCompleted: {
if (confInfoGui) { if (confInfoGui) {
for(var i = 0; i < confInfoGui.core.participants.length; ++i) { for (var i = 0; i < confInfoGui.core.participants.length; ++i) {
selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i)); selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i));
} }
} }
@ -120,29 +124,30 @@ ListView {
target: SettingsCpp target: SettingsCpp
function onLdapConfigChanged() { function onLdapConfigChanged() {
if (SettingsCpp.syncLdapContacts) if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate() magicSearchProxy.forceUpdate();
} }
function onCardDAVAddressBookSynchronized() { function onCardDAVAddressBookSynchronized() {
console.log("card dav synchro update") console.log("card dav synchro update");
magicSearchProxy.forceUpdate() magicSearchProxy.forceUpdate();
} }
} }
// Workaround: itemAtIndex and count are decorellated and are not enough to know when the ListView has load all its children. // Workaround: itemAtIndex and count are decorellated and are not enough to know when the ListView has load all its children.
// So when itemAtIndex is not available, start this timer along count changed signal. // So when itemAtIndex is not available, start this timer along count changed signal.
Timer{ Timer {
id: delaySelection id: delaySelection
interval: 100 interval: 100
running: _moveToIndex running: _moveToIndex
onTriggered: { onTriggered: {
_moveToIndex = false _moveToIndex = false;
if(count > mainItem.currentIndex) selectIndex(mainItem.currentIndex) if (count > mainItem.currentIndex)
else{ selectIndex(mainItem.currentIndex);
_moveToIndex = true else {
_moveToIndex = true;
} }
} }
} }
header: FocusScope{ header: FocusScope {
id: headerItem id: headerItem
width: mainItem.width width: mainItem.width
height: headerContents.implicitHeight height: headerContents.implicitHeight
@ -151,7 +156,8 @@ ListView {
id: headerContents id: headerContents
width: parent.width width: parent.width
spacing: 0 spacing: 0
Item{// Do not use directly RowLayout : there is an issue where the layout doesn't update on visible Item// Do not use directly RowLayout : there is an issue where the layout doesn't update on visible
{
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0 Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0
Layout.bottomMargin: Utils.getSizeWithScreenRatio(4) Layout.bottomMargin: Utils.getSizeWithScreenRatio(4)
@ -180,7 +186,7 @@ ListView {
onClicked: mainItem.expanded = !mainItem.expanded onClicked: mainItem.expanded = !mainItem.expanded
Rectangle { Rectangle {
anchors.fill: headerExpandButton anchors.fill: headerExpandButton
radius: headerExpandButton.width/2 radius: headerExpandButton.width / 2
visible: headerExpandButton.activeFocus visible: headerExpandButton.activeFocus
opacity: 0.5 opacity: 0.5
color: DefaultStyle.main2_200 color: DefaultStyle.main2_200
@ -196,7 +202,7 @@ ListView {
} }
} }
delegate: ContactListItem{ delegate: ContactListItem {
id: contactItem id: contactItem
width: mainItem.width width: mainItem.width
focus: true focus: true
@ -215,35 +221,35 @@ ListView {
selectedContacts: mainItem.selectedContacts selectedContacts: mainItem.selectedContacts
isSelected: mainItem.highlightedContact && mainItem.highlightedContact.core == searchResultItem.core isSelected: mainItem.highlightedContact && mainItem.highlightedContact.core == searchResultItem.core
isLastHovered: mainItem.lastMouseContainsIndex == index isLastHovered: mainItem.lastMouseContainsIndex == index
previousInitial: mainItem.itemAtIndex(index-1)?.initial previousInitial: mainItem.itemAtIndex(index - 1)?.initial
itemsRightMargin: mainItem.itemsRightMargin itemsRightMargin: mainItem.itemsRightMargin
onIsSelectedChanged: if(isSelected) mainItem.currentIndex = index onIsSelectedChanged: if (isSelected)
onContactDeletionRequested: (contact) => mainItem.contactDeletionRequested(contact) mainItem.currentIndex = index
onContactDeletionRequested: contact => mainItem.contactDeletionRequested(contact)
onClicked: (mouse) => { onClicked: mouse => {
if (mouse && mouse.button == Qt.RightButton) { if (mouse && mouse.button == Qt.RightButton) {
friendPopup.open() friendPopup.open();
} else { } else {
forceActiveFocus() forceActiveFocus();
mainItem.highlightedContact = contactItem.searchResultItem mainItem.highlightedContact = contactItem.searchResultItem;
if (mainItem.multiSelectionEnabled) { if (mainItem.multiSelectionEnabled) {
var indexInSelection = mainItem.selectedContacts.indexOf(searchResultItem.core.defaultAddress) var indexInSelection = mainItem.selectedContacts.indexOf(searchResultItem.core.defaultAddress);
if (indexInSelection == -1) { if (indexInSelection == -1) {
mainItem.addContactToSelection(searchResultItem.core.defaultAddress) mainItem.addContactToSelection(searchResultItem.core.defaultAddress);
} } else {
else { mainItem.removeContactFromSelection(indexInSelection);
mainItem.removeContactFromSelection(indexInSelection)
} }
} }
mainItem.contactSelected(searchResultItem) mainItem.contactSelected(searchResultItem);
} }
} }
onContainsMouseChanged: (containsMouse) => { onContainsMouseChanged: containsMouse => {
if(containsMouse) if (containsMouse)
mainItem.lastMouseContainsIndex = index mainItem.lastMouseContainsIndex = index;
else if( mainItem.lastMouseContainsIndex == index) else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1 mainItem.lastMouseContainsIndex = -1;
} }
} }
} }

View file

@ -4,20 +4,20 @@ import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
PopupButton { PopupButton {
id: presenceAndRegistrationItem id: presenceAndRegistrationItem
width: presenceOrRegistrationText.implicitWidth + Utils.getSizeWithScreenRatio(50) width: presenceOrRegistrationText.implicitWidth + Utils.getSizeWithScreenRatio(50)
height: Utils.getSizeWithScreenRatio(24) height: Utils.getSizeWithScreenRatio(24)
enabled: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Ok enabled: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Ok
onEnabledChanged: if(!enabled) close() onEnabledChanged: if (!enabled)
property bool editCustomStatus : false close()
property bool editCustomStatus: false
contentItem: Rectangle { contentItem: Rectangle {
id: presenceBar id: presenceBar
property bool isRegistered: mainItem.account?.core.registrationState === LinphoneEnums.RegistrationState.Ok property bool isRegistered: mainItem.account?.core.registrationState === LinphoneEnums.RegistrationState.Ok
@ -32,9 +32,8 @@ PopupButton {
smooth: false smooth: false
Layout.preferredWidth: Utils.getSizeWithScreenRatio(11) Layout.preferredWidth: Utils.getSizeWithScreenRatio(11)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(11) Layout.preferredHeight: Utils.getSizeWithScreenRatio(11)
source: presenceBar.isRegistered source: presenceBar.isRegistered ? mainItem.account.core.presenceIcon : mainItem.account?.core.registrationIcon
? mainItem.account.core.presenceIcon || ""
: mainItem.account?.core.registrationIcon || ""
Layout.leftMargin: Utils.getSizeWithScreenRatio(8) Layout.leftMargin: Utils.getSizeWithScreenRatio(8)
RotationAnimator on rotation { RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
@ -53,7 +52,8 @@ PopupButton {
font.weight: Utils.getSizeWithScreenRatio(300) font.weight: Utils.getSizeWithScreenRatio(300)
font.pixelSize: Utils.getSizeWithScreenRatio(12) font.pixelSize: Utils.getSizeWithScreenRatio(12)
color: presenceBar.isRegistered ? mainItem.account.core.presenceColor : mainItem.account?.core.registrationColor color: presenceBar.isRegistered ? mainItem.account.core.presenceColor : mainItem.account?.core.registrationColor
text: presenceBar.isRegistered ? mainItem.account.core.presenceStatus : mainItem.account?.core.humaneReadableRegistrationState text: presenceBar.isRegistered ? mainItem.account.core.presenceStatus : mainItem.account
?.core.humaneReadableRegistrationState
} }
EffectImage { EffectImage {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
@ -67,7 +67,8 @@ PopupButton {
} }
popup.contentItem: Rectangle { popup.contentItem: Rectangle {
implicitWidth: Utils.getSizeWithScreenRatio(280) implicitWidth: Utils.getSizeWithScreenRatio(280)
implicitHeight: Utils.getSizeWithScreenRatio(20) + (setCustomStatus.visible ? Utils.getSizeWithScreenRatio(240) : setPresence.implicitHeight) implicitHeight: Utils.getSizeWithScreenRatio(20) + (setCustomStatus.visible ? Utils.getSizeWithScreenRatio(240) :
setPresence.implicitHeight)
Presence { Presence {
id: setPresence id: setPresence
visible: !presenceAndRegistrationItem.editCustomStatus visible: !presenceAndRegistrationItem.editCustomStatus
@ -75,7 +76,7 @@ PopupButton {
anchors.margins: Utils.getSizeWithScreenRatio(20) anchors.margins: Utils.getSizeWithScreenRatio(20)
accountGui: mainItem.account accountGui: mainItem.account
onSetCustomStatusClicked: { onSetCustomStatusClicked: {
presenceAndRegistrationItem.editCustomStatus = true presenceAndRegistrationItem.editCustomStatus = true;
} }
onIsSet: presenceAndRegistrationItem.popup.close() onIsSet: presenceAndRegistrationItem.popup.close()
} }
@ -87,7 +88,7 @@ PopupButton {
accountGui: mainItem.account accountGui: mainItem.account
onVisibleChanged: { onVisibleChanged: {
if (!visible) { if (!visible) {
presenceAndRegistrationItem.editCustomStatus = false presenceAndRegistrationItem.editCustomStatus = false;
} }
} }
onIsSet: presenceAndRegistrationItem.popup.close() onIsSet: presenceAndRegistrationItem.popup.close()

View file

@ -2,8 +2,8 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
@ -13,11 +13,31 @@ ColumnLayout {
signal isSet signal isSet
spacing: Utils.getSizeWithScreenRatio(8) spacing: Utils.getSizeWithScreenRatio(8)
PresenceStatusItem { presence: LinphoneEnums.Presence.Online; accountGui: mainItem.accountGui; onClick: mainItem.isSet()} PresenceStatusItem {
PresenceStatusItem { presence: LinphoneEnums.Presence.Away; accountGui: mainItem.accountGui; onClick: mainItem.isSet()} presence: LinphoneEnums.Presence.Online
PresenceStatusItem { presence: LinphoneEnums.Presence.Busy; accountGui: mainItem.accountGui; onClick: mainItem.isSet()} accountGui: mainItem.accountGui
PresenceStatusItem { presence: LinphoneEnums.Presence.DoNotDisturb; accountGui: mainItem.accountGui; onClick: mainItem.isSet()} onClick: mainItem.isSet()
PresenceStatusItem { presence: LinphoneEnums.Presence.Offline; accountGui: mainItem.accountGui; onClick: mainItem.isSet()} }
PresenceStatusItem {
presence: LinphoneEnums.Presence.Away
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
PresenceStatusItem {
presence: LinphoneEnums.Presence.Busy
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
PresenceStatusItem {
presence: LinphoneEnums.Presence.DoNotDisturb
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
PresenceStatusItem {
presence: LinphoneEnums.Presence.Offline
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
RowLayout { RowLayout {
spacing: 0 spacing: 0
@ -53,7 +73,8 @@ ColumnLayout {
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Text { Text {
font: Typography.p1 font: Typography.p1
text: accountGui.core.presenceNote.length > 0 ? accountGui.core.presenceNote : qsTr("contact_presence_custom_status") text: accountGui.core.presenceNote.length > 0 ? accountGui.core.presenceNote : qsTr(
"contact_presence_custom_status")
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
Layout.preferredWidth: Utils.getSizeWithScreenRatio(accountGui.core.presenceNote.length == 0 ? 175 : 230) Layout.preferredWidth: Utils.getSizeWithScreenRatio(accountGui.core.presenceNote.length == 0 ? 175 : 230)
@ -66,7 +87,7 @@ ColumnLayout {
style: ButtonStyle.secondary style: ButtonStyle.secondary
text: qsTr("contact_presence_button_set_custom_status") text: qsTr("contact_presence_button_set_custom_status")
onClicked: { onClicked: {
mainItem.setCustomStatusClicked() mainItem.setCustomStatusClicked();
} }
} }
} }
@ -80,7 +101,7 @@ ColumnLayout {
style: ButtonStyle.secondary style: ButtonStyle.secondary
text: qsTr("contact_presence_button_edit_custom_status") text: qsTr("contact_presence_button_edit_custom_status")
onClicked: { onClicked: {
mainItem.setCustomStatusClicked() mainItem.setCustomStatusClicked();
} }
} }
SmallButton { SmallButton {
@ -88,7 +109,7 @@ ColumnLayout {
visible: accountGui.core.presenceNote.length > 0 visible: accountGui.core.presenceNote.length > 0
text: qsTr("contact_presence_button_delete_custom_status") text: qsTr("contact_presence_button_delete_custom_status")
onClicked: { onClicked: {
mainItem.accountGui.core.presenceNote = "" mainItem.accountGui.core.presenceNote = "";
} }
} }
} }

View file

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Column { Column {
@ -42,10 +42,10 @@ Column {
text: mainItem.accountGui.core.presenceNote text: mainItem.accountGui.core.presenceNote
onTextChanged: { onTextChanged: {
if (statusMessage.text.length > accountGui.core.maxPresenceNoteSize) { if (statusMessage.text.length > accountGui.core.maxPresenceNoteSize) {
statusMessage.text = previoustext statusMessage.text = previoustext;
statusMessage.cursorPosition = statusMessage.text.length statusMessage.cursorPosition = statusMessage.text.length;
} else { } else {
previoustext = statusMessage.text previoustext = statusMessage.text;
} }
} }
} }
@ -71,8 +71,8 @@ Column {
text: qsTr("contact_presence_button_save_custom_status") text: qsTr("contact_presence_button_save_custom_status")
enabled: statusMessage.text.length > 0 enabled: statusMessage.text.length > 0
onClicked: { onClicked: {
mainItem.accountGui.core.presenceNote = statusMessage.text mainItem.accountGui.core.presenceNote = statusMessage.text;
mainItem.isSet() mainItem.isSet();
} }
} }
} }

View file

@ -3,16 +3,15 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
IconLabelButton { IconLabelButton {
id: mainItem id: mainItem
property var accountGui property var accountGui
property var presence property var presence
signal click() signal click
style: ButtonStyle.hoveredBackgroundBis style: ButtonStyle.hoveredBackgroundBis
height: Utils.getSizeWithScreenRatio(22) height: Utils.getSizeWithScreenRatio(22)
@ -29,7 +28,7 @@ IconLabelButton {
padding: 0 padding: 0
onClicked: { onClicked: {
mainItem.accountGui.core.presence = mainItem.presence mainItem.accountGui.core.presence = mainItem.presence;
mainItem.click() mainItem.click();
} }
} }

View file

@ -7,14 +7,14 @@ import UtilsCpp
import SettingsCpp import SettingsCpp
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Rectangle{ Rectangle {
id: mainItem id: mainItem
property int voicemailCount: 0 property int voicemailCount: 0
property bool showMwi: false property bool showMwi: false
width: Utils.getSizeWithScreenRatio(42 * scaleFactor) width: Utils.getSizeWithScreenRatio(42 * scaleFactor)
height: Utils.getSizeWithScreenRatio(36 * scaleFactor) height: Utils.getSizeWithScreenRatio(36 * scaleFactor)
property real scaleFactor: 1.0 property real scaleFactor: 1.0
signal clicked() signal clicked
color: 'transparent' color: 'transparent'
Button { Button {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -30,7 +30,7 @@ Rectangle{
anchors.fill: parent anchors.fill: parent
} }
onClicked: { onClicked: {
mainItem.clicked() mainItem.clicked();
} }
} }
Text { Text {
@ -62,5 +62,4 @@ Rectangle{
colorizationColor: DefaultStyle.grey_0 colorizationColor: DefaultStyle.grey_0
} }
} }
} }

View file

@ -52,7 +52,7 @@ Item {
source: effect source: effect
maskSource: effect maskSource: effect
colorizationColor: effectEnabled && mainItem.colorizationColor ? mainItem.colorizationColor : 'black' colorizationColor: effectEnabled && mainItem.colorizationColor ? mainItem.colorizationColor : 'black'
colorization: effectEnabled ? 1.0: 0.0 colorization: effectEnabled ? 1.0 : 0.0
} }
/* Alernative to shadow for no blackcolors /* Alernative to shadow for no blackcolors
MultiEffect { MultiEffect {

View file

@ -15,8 +15,14 @@ Item {
anchors.fill: parent anchors.fill: parent
gradient: Gradient { gradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_0 } GradientStop {
GradientStop { position: 1.0; color: DefaultStyle.grey_100 } position: 0.0
color: DefaultStyle.grey_0
}
GradientStop {
position: 1.0
color: DefaultStyle.grey_100
}
} }
Rectangle { Rectangle {
id: fill id: fill

View file

@ -2,9 +2,9 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Rectangle{ Rectangle {
height: 1 height: 1
Layout.fillWidth: true Layout.fillWidth: true
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main

View file

@ -7,7 +7,7 @@ import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// ============================================================================= // =============================================================================
@ -25,21 +25,21 @@ ProgressBar {
padding: 0 padding: 0
clip: true clip: true
function start(){ function start() {
mainItem.value = 0 mainItem.value = 0;
animationTest.start() animationTest.start();
} }
function resume(){ function resume() {
if (mainItem.value >= 100) if (mainItem.value >= 100)
mainItem.value = 0 mainItem.value = 0;
animationTest.start() animationTest.start();
} }
function stop(){ function stop() {
animationTest.stop() animationTest.stop();
} }
signal playStopButtonToggled() signal playStopButtonToggled
signal endReached() signal endReached
signal refreshPositionRequested() signal refreshPositionRequested
signal seekRequested(int ms) signal seekRequested(int ms)
Timer { Timer {
id: animationTest id: animationTest
@ -49,18 +49,18 @@ ProgressBar {
} }
to: 101 to: 101
value: progressPosition * to / progressDuration value: progressPosition * to / progressDuration
onValueChanged:{ onValueChanged: {
if(value > 100) { if (value > 100) {
if( mainItem.stopAtEnd) if (mainItem.stopAtEnd)
stop() stop();
if(mainItem.resetAtEnd) { if (mainItem.resetAtEnd) {
mainItem.value = 0 mainItem.value = 0;
progressPosition = 0 progressPosition = 0;
} else if(mainItem.blockValueAtEnd){ } else if (mainItem.blockValueAtEnd) {
mainItem.value = 100// Stay at 100 mainItem.value = 100;// Stay at 100
progressPosition = progressDuration progressPosition = progressDuration;
} }
mainItem.endReached() mainItem.endReached();
} }
} }
@ -71,8 +71,14 @@ ProgressBar {
anchors.fill: parent anchors.fill: parent
gradient: Gradient { gradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: "#FF9E79" } GradientStop {
GradientStop { position: 1.0; color: "#FE5E00" } position: 0.0
color: "#FF9E79"
}
GradientStop {
position: 1.0
color: "#FE5E00"
}
} }
radius: Utils.getSizeWithScreenRatio(70) radius: Utils.getSizeWithScreenRatio(70)
} }
@ -83,8 +89,8 @@ ProgressBar {
radius: backgroundArea.radius radius: backgroundArea.radius
} }
Item { Item {
anchors.fill: parent
id: progressRectangle id: progressRectangle
anchors.fill: parent
visible: false visible: false
Rectangle { Rectangle {
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
@ -96,12 +102,10 @@ ProgressBar {
ShaderEffect { ShaderEffect {
id: opacityEffect id: opacityEffect
anchors.fill: progressRectangle anchors.fill: progressRectangle
property var source: ShaderEffectSource property var source: ShaderEffectSource {
{
sourceItem: progressRectangle sourceItem: progressRectangle
} }
property var maskSource: ShaderEffectSource property var maskSource: ShaderEffectSource {
{
sourceItem: mask sourceItem: mask
} }
fragmentShader: 'qrc:/data/shaders/opacityMask.frag.qsb' fragmentShader: 'qrc:/data/shaders/opacityMask.frag.qsb'
@ -109,13 +113,12 @@ ProgressBar {
MouseArea { MouseArea {
id: progression id: progression
anchors.fill: parent anchors.fill: parent
onClicked: (mouse) => { onClicked: mouse => {
mainItem.seekRequested(mouse.x * mainItem.progressDuration/width) mainItem.seekRequested(mouse.x * mainItem.progressDuration / width);
} }
} }
} }
contentItem: Item { contentItem: Item {
id: contentRect id: contentRect
@ -126,13 +129,9 @@ ProgressBar {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
icon.width: Utils.getSizeWithScreenRatio(14) icon.width: Utils.getSizeWithScreenRatio(14)
icon.height: Utils.getSizeWithScreenRatio(14) icon.height: Utils.getSizeWithScreenRatio(14)
icon.source: animationTest.running icon.source: animationTest.running ? mainItem.recording ? AppIcons.stopFill : AppIcons.pauseFill : AppIcons.playFill
? mainItem.recording
? AppIcons.stopFill
: AppIcons.pauseFill
: AppIcons.playFill
onClicked: { onClicked: {
mainItem.playStopButtonToggled() mainItem.playStopButtonToggled();
} }
style: ButtonStyle.player style: ButtonStyle.player
} }
@ -160,7 +159,8 @@ ProgressBar {
} }
Text { Text {
id: durationText id: durationText
text: mainItem.progressPosition > 0 ? UtilsCpp.formatElapsedTime(mainItem.progressPosition / 1000 ) : UtilsCpp.formatElapsedTime(mainItem.progressDuration/1000) text: mainItem.progressPosition > 0 ? UtilsCpp.formatElapsedTime(mainItem.progressPosition / 1000) : UtilsCpp.formatElapsedTime(
mainItem.progressDuration / 1000)
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight

View file

@ -7,8 +7,8 @@ import Linphone
import QtQml import QtQml
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ListView { ListView {
id: mainItem id: mainItem
@ -22,49 +22,49 @@ ListView {
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60) property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
clip: true clip: true
cacheBuffer: height/2 cacheBuffer: height / 2
spacing: Utils.getSizeWithScreenRatio(8) spacing: Utils.getSizeWithScreenRatio(8)
highlightFollowsCurrentItem: false highlightFollowsCurrentItem: false
onCurrentIndexChanged: if(currentIndex === -1) { onCurrentIndexChanged: if (currentIndex === -1) {
resetSelections() resetSelections();
} }
signal meetingDeletionRequested(ConferenceInfoGui confInfo, bool canCancel) signal meetingDeletionRequested(ConferenceInfoGui confInfo, bool canCancel)
function selectIndex(index){ function selectIndex(index) {
mainItem.currentIndex = index mainItem.currentIndex = index;
} }
function resetSelections(){ function resetSelections() {
mainItem.selectedConference = null mainItem.selectedConference = null;
mainItem.currentIndex = -1 mainItem.currentIndex = -1;
} }
function scrollToCurrentDate() { function scrollToCurrentDate() {
currentIndex = -1 currentIndex = -1;
confInfoProxy.selectData(confInfoProxy.getCurrentDateConfInfo()) confInfoProxy.selectData(confInfoProxy.getCurrentDateConfInfo());
moveToCurrentItem() moveToCurrentItem();
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
function moveToCurrentItem(){ function moveToCurrentItem() {
if(mainItem.currentIndex >= 0) if (mainItem.currentIndex >= 0)
mainItem.positionViewAtIndex(mainItem.currentIndex, ListView.Contain) mainItem.positionViewAtIndex(mainItem.currentIndex, ListView.Contain);
} }
onCurrentItemChanged: { onCurrentItemChanged: {
moveToCurrentItem() moveToCurrentItem();
if(currentItem) { if (currentItem) {
mainItem.selectedConference = currentItem.itemGui mainItem.selectedConference = currentItem.itemGui;
} }
} }
// Update position only if we are moving to current item and its position is changing. // Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if(_currentItemY && moveAnimation.running){ on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem() moveToCurrentItem();
} }
Behavior on contentY{ Behavior on contentY {
NumberAnimation { NumberAnimation {
id: moveAnimation id: moveAnimation
duration: 500 duration: 500
@ -72,59 +72,64 @@ ListView {
alwaysRunToEnd: true alwaysRunToEnd: true
} }
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
onAtYEndChanged: if(atYEnd) confInfoProxy.displayMore() onAtYEndChanged: if (atYEnd)
confInfoProxy.displayMore()
Component.onCompleted: { Component.onCompleted: {
confInfoProxy.invalidate() confInfoProxy.invalidate();
} }
Keys.onPressed: (event)=> { Keys.onPressed: event => {
if(event.key == Qt.Key_Up) { if (event.key == Qt.Key_Up) {
if(currentIndex > 0 ) { if (currentIndex > 0) {
selectIndex(mainItem.currentIndex-1) selectIndex(mainItem.currentIndex - 1);
event.accepted = true event.accepted = true;
} else { } else {
selectIndex(model.count - 1) selectIndex(model.count - 1);
event.accepted = true event.accepted = true;
} }
}else if(event.key == Qt.Key_Down){ } else if (event.key == Qt.Key_Down) {
if(currentIndex < model.count - 1) { if (currentIndex < model.count - 1) {
selectIndex(currentIndex+1) selectIndex(currentIndex + 1);
event.accepted = true event.accepted = true;
} else { } else {
selectIndex(0) selectIndex(0);
event.accepted = true event.accepted = true;
} }
} }
} }
// Let some space for better UI // Let some space for better UI
footer: Item{height: Utils.getSizeWithScreenRatio(38)} footer: Item {
height: Utils.getSizeWithScreenRatio(38)
}
model: ConferenceInfoProxy { model: ConferenceInfoProxy {
id: confInfoProxy id: confInfoProxy
filterText: searchBarText filterText: searchBarText
filterType: ConferenceInfoProxy.None filterType: ConferenceInfoProxy.None
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63))) initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
displayItemsStep: initialDisplayItems/2 displayItemsStep: initialDisplayItems / 2
onModelAboutToBeReset: { onModelAboutToBeReset: {
mainItem.confToBeSelected = mainItem.selectedConference mainItem.confToBeSelected = mainItem.selectedConference;
mainItem.loading = true mainItem.loading = true;
} }
onModelReset: { onModelReset: {
mainItem.loading = false mainItem.loading = false;
if (mainItem.confToBeSelected) selectData(mainItem.confToBeSelected) if (mainItem.confToBeSelected)
else selectData(getCurrentDateConfInfo()) selectData(mainItem.confToBeSelected);
else
selectData(getCurrentDateConfInfo());
} }
function selectData(confInfoGui){ function selectData(confInfoGui) {
mainItem.currentIndex = loadUntil(confInfoGui) mainItem.currentIndex = loadUntil(confInfoGui);
} }
onConferenceInfoCreated: (confInfoGui) => { onConferenceInfoCreated: confInfoGui => {
selectData(confInfoGui) selectData(confInfoGui);
} }
onConferenceInfoUpdated: (confInfoGui) => { onConferenceInfoUpdated: confInfoGui => {
selectData(confInfoGui) selectData(confInfoGui);
} }
} }
@ -173,24 +178,25 @@ ListView {
property var itemGui: $modelData property var itemGui: $modelData
// Do not use itemAtIndex because of caching items. Using getAt ensure to have a GUI // Do not use itemAtIndex because of caching items. Using getAt ensure to have a GUI
property var previousConfInfoGui : mainItem.model.getAt(index-1) property var previousConfInfoGui: mainItem.model.getAt(index - 1)
property var dateTime: itemGui.core ? itemGui.core.dateTime : UtilsCpp.getCurrentDateTime() property var dateTime: itemGui.core ? itemGui.core.dateTime : UtilsCpp.getCurrentDateTime()
property string day : UtilsCpp.toDateDayNameString(dateTime) property string day: UtilsCpp.toDateDayNameString(dateTime)
property string dateString: UtilsCpp.toDateString(dateTime) property string dateString: UtilsCpp.toDateString(dateTime)
property string previousDateString: previousConfInfoGui ? UtilsCpp.toDateString(previousConfInfoGui.core ? previousConfInfoGui.core.dateTime : UtilsCpp.getCurrentDateTime()) : '' property string previousDateString: previousConfInfoGui ? UtilsCpp.toDateString(previousConfInfoGui.core
property bool isFirst : ListView.previousSection !== ListView.section ? previousConfInfoGui.core.dateTime : UtilsCpp.getCurrentDateTime()) : ''
property bool isFirst: ListView.previousSection !== ListView.section
property real topOffset: (dateDay.visible && !isFirst) ? Utils.getSizeWithScreenRatio(8) : 0 property real topOffset: (dateDay.visible && !isFirst) ? Utils.getSizeWithScreenRatio(8) : 0
property var endDateTime: itemGui.core ? itemGui.core.endDateTime : UtilsCpp.getCurrentDateTime() property var endDateTime: itemGui.core ? itemGui.core.endDateTime : UtilsCpp.getCurrentDateTime()
property bool haveModel: itemGui.core ? itemGui.core.haveModel : false property bool haveModel: itemGui.core ? itemGui.core.haveModel : false
property bool isCanceled: itemGui.core ? itemGui.core.state === LinphoneEnums.ConferenceInfoState.Cancelled : false property bool isCanceled: itemGui.core ? itemGui.core.state === LinphoneEnums.ConferenceInfoState.Cancelled : false
property bool isSelected: itemGui.core == mainItem.selectedConference?.core property bool isSelected: itemGui.core == mainItem.selectedConference?.core
RowLayout{ RowLayout {
id: delegateIn id: delegateIn
anchors.fill: parent anchors.fill: parent
anchors.topMargin: !itemDelegate.isFirst && dateDay.visible ? itemDelegate.topOffset : 0 anchors.topMargin: !itemDelegate.isFirst && dateDay.visible ? itemDelegate.topOffset : 0
spacing: 0 spacing: 0
Item{ Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32) Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
visible: !dateDay.visible visible: !dateDay.visible
} }
@ -205,7 +211,7 @@ ListView {
Text { Text {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(19) Layout.preferredHeight: Utils.getSizeWithScreenRatio(19)
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
text: day.substring(0,3) + '.' text: day.substring(0, 3) + '.'
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
elide: Text.ElideNone elide: Text.ElideNone
@ -220,7 +226,7 @@ ListView {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32) Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(32) Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
radius: height/2 radius: height / 2
property var isCurrentDay: UtilsCpp.isCurrentDay(dateTime) property var isCurrentDay: UtilsCpp.isCurrentDay(dateTime)
color: isCurrentDay ? DefaultStyle.main1_500_main : "transparent" color: isCurrentDay ? DefaultStyle.main1_500_main : "transparent"
@ -238,7 +244,10 @@ ListView {
} }
} }
} }
Item{Layout.fillHeight:true;Layout.fillWidth: true} Item {
Layout.fillHeight: true
Layout.fillWidth: true
}
} }
Item { Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(265) Layout.preferredWidth: Utils.getSizeWithScreenRatio(265)
@ -269,7 +278,7 @@ ListView {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
} }
Text { Text {
text: itemGui.core? itemGui.core.subject : "" text: itemGui.core ? itemGui.core.subject : ""
Layout.fillWidth: true Layout.fillWidth: true
maximumLineCount: 1 maximumLineCount: 1
font { font {
@ -280,7 +289,8 @@ ListView {
} }
Text { Text {
//: "Réunion annulée" //: "Réunion annulée"
text: itemDelegate.isCanceled ? qsTr("meeting_info_cancelled") : UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime) text: itemDelegate.isCanceled ? qsTr("meeting_info_cancelled") : UtilsCpp.toDateHourString(dateTime) + " - "
+ UtilsCpp.toDateHourString(endDateTime)
color: itemDelegate.isCanceled ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main color: itemDelegate.isCanceled ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
@ -319,13 +329,13 @@ ListView {
cursorShape: itemDelegate.isCanceled ? Qt.ArrowCursor : Qt.PointingHandCursor cursorShape: itemDelegate.isCanceled ? Qt.ArrowCursor : Qt.PointingHandCursor
visible: itemDelegate.haveModel visible: itemDelegate.haveModel
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: (mouse) => { onClicked: mouse => {
if (mouse.button === Qt.RightButton) { if (mouse.button === Qt.RightButton) {
deletePopup.x = mouse.x deletePopup.x = mouse.x;
deletePopup.y = mouse.y deletePopup.y = mouse.y;
deletePopup.open() deletePopup.open();
} } else if (!itemDelegate.isCanceled)
else if (!itemDelegate.isCanceled) mainItem.selectIndex(index) mainItem.selectIndex(index);
} }
Popup { Popup {
id: deletePopup id: deletePopup
@ -335,17 +345,17 @@ ListView {
contentItem: IconLabelButton { contentItem: IconLabelButton {
style: ButtonStyle.hoveredBackgroundRed style: ButtonStyle.hoveredBackgroundRed
property var isMeObj: UtilsCpp.isMe(itemDelegate.itemGui?.core?.organizerAddress) property var isMeObj: UtilsCpp.isMe(itemDelegate.itemGui?.core?.organizerAddress)
property bool canCancel: isMeObj && isMeObj.value property bool canCancel: isMeObj && isMeObj.value && itemDelegate.itemGui?.core?.state
&& itemDelegate.itemGui?.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled !== LinphoneEnums.ConferenceInfoState.Cancelled && UtilsCpp.daysOffset(new Date(), itemDelegate.itemGui
&& UtilsCpp.daysOffset(new Date(), itemDelegate.itemGui?.core?.endDateTime) >= 0 ?.core?.endDateTime) >= 0
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
//: "Supprimer la réunion" //: "Supprimer la réunion"
text: qsTr("meeting_info_delete") text: qsTr("meeting_info_delete")
onClicked: { onClicked: {
if (itemDelegate.itemGui) { if (itemDelegate.itemGui) {
mainItem.meetingDeletionRequested(itemDelegate.itemGui, canCancel) mainItem.meetingDeletionRequested(itemDelegate.itemGui, canCancel);
deletePopup.close() deletePopup.close();
} }
} }
} }

View file

@ -48,7 +48,9 @@ ListView {
maximumLineCount: 1 maximumLineCount: 1
Layout.fillWidth: true Layout.fillWidth: true
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
} }
MouseArea { MouseArea {
id: mousearea id: mousearea

View file

@ -4,7 +4,7 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView { ListView {
@ -26,7 +26,7 @@ ListView {
property ConferenceInfoGui confInfoGui property ConferenceInfoGui confInfoGui
signal addParticipantRequested() signal addParticipantRequested
Control.ScrollBar.vertical: ScrollBar { Control.ScrollBar.vertical: ScrollBar {
id: scrollbar id: scrollbar
@ -67,11 +67,14 @@ ListView {
maximumLineCount: 1 maximumLineCount: 1
Layout.fillWidth: true Layout.fillWidth: true
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
RowLayout { RowLayout {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
property bool isMe: modelData.core.isMe property bool isMe: modelData.core.isMe
onIsMeChanged: if (isMe) mainItem.me = modelData onIsMeChanged: if (isMe)
mainItem.me = modelData
spacing: Utils.getSizeWithScreenRatio(26) spacing: Utils.getSizeWithScreenRatio(26)
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
@ -88,7 +91,8 @@ ListView {
} }
Switch { Switch {
opacity: mainItem.isMeAdmin && !modelData.core.isMe ? 1 : 0 opacity: mainItem.isMeAdmin && !modelData.core.isMe ? 1 : 0
Component.onCompleted: if (modelData.core.isAdmin) toggle() Component.onCompleted: if (modelData.core.isAdmin)
toggle()
//TODO : Utilser checked et onToggled (pas compris) //TODO : Utilser checked et onToggled (pas compris)
onToggled: participantModel.setParticipantAdminStatus(modelData.core, position === 1) onToggled: participantModel.setParticipantAdminStatus(modelData.core, position === 1)
} }

View file

@ -12,11 +12,11 @@ Control.ProgressBar {
property color innerColor: DefaultStyle.info_500_main property color innerColor: DefaultStyle.info_500_main
property color innerTextColor: centeredText ? DefaultStyle.info_500_main : DefaultStyle.grey_0 property color innerTextColor: centeredText ? DefaultStyle.info_500_main : DefaultStyle.grey_0
property bool innerTextVisible: true property bool innerTextVisible: true
property string innerText: Number.parseFloat(value*100).toFixed(0) + "%" property string innerText: Number.parseFloat(value * 100).toFixed(0) + "%"
property real barWidth: mainItem.visualPosition * mainItem.width property real barWidth: mainItem.visualPosition * mainItem.width
property bool centeredText: textSize.width >= barWidth property bool centeredText: textSize.width >= barWidth
TextMetrics{ TextMetrics {
id: textSize id: textSize
text: mainItem.innerText text: mainItem.innerText
font { font {

View file

@ -4,7 +4,7 @@ import QtQuick.Shapes
import Linphone import Linphone
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ProgressBar{ ProgressBar {
id: mainItem id: mainItem
property string text: value + '%' property string text: value + '%'
implicitHeight: 35 implicitHeight: 35
@ -12,19 +12,20 @@ ProgressBar{
to: 100 to: 100
value: 0 value: 0
background: Item {} background: Item {}
Timer{ Timer {
id: animationTest id: animationTest
repeat: true repeat: true
onTriggered: value = (value + 1) % to onTriggered: value = (value + 1) % to
interval: 5 interval: 5
} }
contentItem: Item{ contentItem: Item {
Shape { Shape {
id: shape id: shape
anchors.fill: parent anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(2) anchors.margins: Utils.getSizeWithScreenRatio(2)
property real progressionRadius : Math.round(Math.min(shape.width / 2, shape.height / 2) - Utils.getSizeWithScreenRatio(3) / 2) property real progressionRadius: Math.round(Math.min(shape.width / 2, shape.height / 2)
- Utils.getSizeWithScreenRatio(3) / 2)
layer.enabled: true layer.enabled: true
layer.samples: 8 layer.samples: 8
@ -61,11 +62,11 @@ ProgressBar{
centerX: Math.round(shape.width / 2) centerX: Math.round(shape.width / 2)
centerY: Math.round(shape.height / 2) centerY: Math.round(shape.height / 2)
startAngle: -90 // top start startAngle: -90 // top start
sweepAngle: (360/ mainItem.to * mainItem.value) sweepAngle: (360 / mainItem.to * mainItem.value)
} }
} }
} }
Text{ Text {
anchors.centerIn: parent anchors.centerIn: parent
text: mainItem.text text: mainItem.text
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import CustomControls 1.0 import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Item { Item {
id: mainItem id: mainItem
@ -16,15 +16,15 @@ Item {
property string titleText property string titleText
property bool isSelected: false property bool isSelected: false
signal selected() signal selected
//: %1 settings //: %1 settings
Accessible.name: qsTr("setting_tab_accessible_name").arg(titleText) Accessible.name: qsTr("setting_tab_accessible_name").arg(titleText)
Accessible.role: Accessible.ListItem Accessible.role: Accessible.ListItem
Keys.onPressed: (event)=>{ Keys.onPressed: event => {
if(event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter){ if (event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter) {
mainItem.selected() mainItem.selected();
} }
} }
MouseArea { MouseArea {
@ -43,7 +43,7 @@ Item {
border.width: mainItem.keyboardOtherFocus ? Utils.getSizeWithScreenRatio(3) : 0 border.width: mainItem.keyboardOtherFocus ? Utils.getSizeWithScreenRatio(3) : 0
} }
onClicked: { onClicked: {
mainItem.selected() mainItem.selected();
} }
} }
Text { Text {
@ -54,5 +54,4 @@ Item {
text: mainItem.titleText text: mainItem.titleText
font: Typography.h4 font: Typography.h4
} }
} }

View file

@ -23,51 +23,30 @@ Item {
property var callState: call && call.core.state || undefined property var callState: call && call.core.state || undefined
property AccountGui account: null property AccountGui account: null
property ParticipantDeviceGui participantDevice: null property ParticipantDeviceGui participantDevice: null
property bool displayBorder : participantDevice && participantDevice.core.isSpeaking || false property bool displayBorder: participantDevice && participantDevice.core.isSpeaking || false
property alias displayPresence: avatar.displayPresence property alias displayPresence: avatar.displayPresence
property color color: DefaultStyle.grey_600 property color color: DefaultStyle.grey_600
property real radius: Utils.getSizeWithScreenRatio(15) property real radius: Utils.getSizeWithScreenRatio(15)
property bool remoteIsPaused: participantDevice property bool remoteIsPaused: participantDevice ? participantDevice.core.isPaused : previewEnabled ? callState
? participantDevice.core.isPaused === LinphoneEnums.CallState.Paused : callState === LinphoneEnums.CallState.PausedByRemote
: previewEnabled
? callState === LinphoneEnums.CallState.Paused
: callState === LinphoneEnums.CallState.PausedByRemote
property string remoteAddress: account property string remoteAddress: account ? account.core.identityAddress : participantDevice
? account.core.identityAddress ? participantDevice.core.address : call ? call.core.remoteAddress : ""
: participantDevice property var localNameObj: previewEnabled && call ? UtilsCpp.getDisplayName(call.core.localAddress) : null
? participantDevice.core.address
: call
? call.core.remoteAddress
: ""
property var localNameObj: previewEnabled && call
? UtilsCpp.getDisplayName(call.core.localAddress)
: null
property string localName: localNameObj ? localNameObj.value : "" property string localName: localNameObj ? localNameObj.value : ""
property string displayName: account property string displayName: account ? account.core.displayName : participantDevice
? account.core.displayName ? participantDevice.core.displayName : call ? previewEnabled ? localName : call.core.remoteName : ""
: participantDevice
? participantDevice.core.displayName
: call
? previewEnabled
? localName
: call.core.remoteName
: ""
property var contactObj: call ? UtilsCpp.findFriendByAddress(call.core.remoteAddress) : null property var contactObj: call ? UtilsCpp.findFriendByAddress(call.core.remoteAddress) : null
property var contact: contactObj && contactObj.value || null property var contact: contactObj && contactObj.value || null
property var identityAddress: account ? UtilsCpp.getDisplayName(account.core.identityAddress) : null property var identityAddress: account ? UtilsCpp.getDisplayName(account.core.identityAddress) : null
property bool videoEnabled: (previewEnabled && call && call.core.cameraEnabled) property bool videoEnabled: (previewEnabled && call && call.core.cameraEnabled) || (!previewEnabled && call
|| (!previewEnabled && call && call.core.remoteVideoEnabled) && call.core.remoteVideoEnabled) || (participantDevice && participantDevice.core.videoEnabled)
|| (participantDevice && participantDevice.core.videoEnabled)
property string qmlName property string qmlName
property bool displayAll : !!mainItem.call property bool displayAll: !!mainItem.call
property bool mutedStatus: participantDevice property bool mutedStatus: participantDevice ? participantDevice.core.isMuted : account && call ? call.core.conference
? participantDevice.core.isMuted && call.core.microphoneMuted : false
: account && call
? call.core.conference && call.core.microphoneMuted
: false
clip: false clip: false
Rectangle { Rectangle {
id: background id: background
@ -87,11 +66,11 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
// Layout.alignment: Qt.AlignHCenter |Qt.AlignTop // Layout.alignment: Qt.AlignHCenter |Qt.AlignTop
spacing: 0 spacing: 0
visible: !mainItem.account && (mainItem.callState === LinphoneEnums.CallState.OutgoingInit visible: !mainItem.account && (mainItem.callState === LinphoneEnums.CallState.OutgoingInit || mainItem.callState
|| mainItem.callState === LinphoneEnums.CallState.OutgoingProgress === LinphoneEnums.CallState.OutgoingProgress || mainItem.callState
|| mainItem.callState === LinphoneEnums.CallState.OutgoingRinging === LinphoneEnums.CallState.OutgoingRinging || mainItem.callState
|| mainItem.callState === LinphoneEnums.CallState.OutgoingEarlyMedia === LinphoneEnums.CallState.OutgoingEarlyMedia || mainItem.callState
|| mainItem.callState === LinphoneEnums.CallState.IncomingReceived) === LinphoneEnums.CallState.IncomingReceived)
BusyIndicator { BusyIndicator {
indicatorColor: DefaultStyle.main2_100 indicatorColor: DefaultStyle.main2_100
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@ -99,29 +78,30 @@ Item {
indicatorWidth: Utils.getSizeWithScreenRatio(42) indicatorWidth: Utils.getSizeWithScreenRatio(42)
} }
} }
Item{ Item {
id: centerItem id: centerItem
visible: !mainItem.remoteIsPaused visible: !mainItem.remoteIsPaused
anchors.centerIn: parent anchors.centerIn: parent
height: mainItem.conference height: mainItem.conference ? background.minSize * 142 / 372 : Utils.getSizeWithScreenRatio(120)
? background.minSize * 142 / 372
: Utils.getSizeWithScreenRatio(120)
width: height width: height
Avatar{ Avatar {
id: avatar id: avatar
anchors.fill: parent anchors.fill: parent
visible: !joiningView.visible visible: !joiningView.visible
account: mainItem.account account: mainItem.account
call: !mainItem.previewEnabled ? mainItem.call : null call: !mainItem.previewEnabled ? mainItem.call : null
displayNameVal: mainItem.displayName displayNameVal: mainItem.displayName
securityBreach: mainItem.securityBreach ? mainItem.securityBreach : securityLevel === LinphoneEnums.SecurityLevel.Unsafe securityBreach: mainItem.securityBreach ? mainItem.securityBreach : securityLevel
=== LinphoneEnums.SecurityLevel.Unsafe
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
} }
ColumnLayout{ ColumnLayout {
id: joiningView id: joiningView
anchors.centerIn: parent anchors.centerIn: parent
spacing: 0 spacing: 0
visible: mainItem.participantDevice && (mainItem.participantDevice.core.state == LinphoneEnums.ParticipantDeviceState.Joining || mainItem.participantDevice.core.state == LinphoneEnums.ParticipantDeviceState.Alerting) || false visible: mainItem.participantDevice && (mainItem.participantDevice.core.state
== LinphoneEnums.ParticipantDeviceState.Joining || mainItem.participantDevice.core.state
== LinphoneEnums.ParticipantDeviceState.Alerting) || false
BusyIndicator { BusyIndicator {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(42) Layout.preferredHeight: Utils.getSizeWithScreenRatio(42)
indicatorColor: DefaultStyle.main2_100 indicatorColor: DefaultStyle.main2_100
@ -198,31 +178,31 @@ Item {
} }
} }
} }
Loader{ Loader {
id: cameraLoader id: cameraLoader
anchors.fill: parent anchors.fill: parent
property bool reset: false property bool reset: false
Timer{ Timer {
id: resetTimer id: resetTimer
interval: 1 interval: 1
triggeredOnStart: true triggeredOnStart: true
onTriggered: {cameraLoader.reset = !cameraLoader.reset} onTriggered: {
cameraLoader.reset = !cameraLoader.reset;
} }
active: mainItem.visible && !mainItem.remoteIsPaused }
&& mainItem.videoEnabled active: mainItem.visible && !mainItem.remoteIsPaused && mainItem.videoEnabled && mainItem.callState
&& mainItem.callState !== LinphoneEnums.CallState.End !== LinphoneEnums.CallState.End && mainItem.callState !== LinphoneEnums.CallState.Released && !cameraLoader.reset
&& mainItem.callState !== LinphoneEnums.CallState.Released onActiveChanged: console.log("(" + mainItem.qmlName + ") Camera active " + active + ", visible=" + mainItem.visible
&& !cameraLoader.reset + ", videoEnabled=" + mainItem.videoEnabled + ", reset=" + cameraLoader.reset)
onActiveChanged: console.log("("+mainItem.qmlName+") Camera active " + active +", visible="+mainItem.visible +", videoEnabled="+mainItem.videoEnabled +", reset="+cameraLoader.reset)
sourceComponent: cameraComponent sourceComponent: cameraComponent
} }
Component{ Component {
id: cameraComponent id: cameraComponent
Item { Item {
height: cameraLoader.height height: cameraLoader.height
width: cameraLoader.width width: cameraLoader.width
property alias isReady: cameraItem.isReady property alias isReady: cameraItem.isReady
CameraGui{ CameraGui {
id: cameraItem id: cameraItem
anchors.fill: parent anchors.fill: parent
visible: false visible: false
@ -232,8 +212,8 @@ Item {
participantDevice: mainItem.participantDevice participantDevice: mainItem.participantDevice
onRequestNewRenderer: { onRequestNewRenderer: {
console.log("Request new renderer for " +mainItem.qmlName) console.log("Request new renderer for " + mainItem.qmlName);
resetTimer.restart() resetTimer.restart();
} }
layer.enabled: true layer.enabled: true
} }
@ -261,11 +241,8 @@ Item {
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10) anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
width: implicitWidth width: implicitWidth
maximumLineCount: 1 maximumLineCount: 1
property string _text: mainItem.displayName != '' property string _text: mainItem.displayName != '' ? mainItem.displayName : mainItem.account
? mainItem.displayName && mainItem.identityAddress ? mainItem.identityAddress.value : ""
: mainItem.account && mainItem.identityAddress
? mainItem.identityAddress.value
: ""
text: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_text) : _text text: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_text) : _text
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font { font {
@ -284,7 +261,7 @@ Item {
shadowScale: 1.05 shadowScale: 1.05
shadowOpacity: 0.5 shadowOpacity: 0.5
} }
RowLayout{ RowLayout {
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.rightMargin: Utils.getSizeWithScreenRatio(8) anchors.rightMargin: Utils.getSizeWithScreenRatio(8)
@ -298,11 +275,11 @@ Item {
Layout.preferredHeight: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20)) Layout.preferredHeight: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
visible: mainItem.mutedStatus visible: mainItem.mutedStatus
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
radius: width /2 radius: width / 2
EffectImage { EffectImage {
anchors.centerIn: parent anchors.centerIn: parent
imageWidth: Math.min(Math.round(mainItem.width / 16),Utils.getSizeWithScreenRatio(20)) imageWidth: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
imageHeight: Math.min(Math.round(mainItem.width / 16),Utils.getSizeWithScreenRatio(20)) imageHeight: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
imageSource: AppIcons.microphoneSlash imageSource: AppIcons.microphoneSlash
colorizationColor: DefaultStyle.main2_500_main colorizationColor: DefaultStyle.main2_500_main
} }

View file

@ -9,14 +9,14 @@ Text {
color: DefaultStyle.danger_500_main color: DefaultStyle.danger_500_main
property bool isVisible: text.length > 0 property bool isVisible: text.length > 0
function clear() { function clear() {
autoHideErrorMessage.stop() autoHideErrorMessage.stop();
text = "" text = "";
} }
function setText(text) { function setText(text) {
if (text.length === 0) { if (text.length === 0) {
clear() clear();
} else { } else {
mainItem.text = text mainItem.text = text;
} }
} }
font { font {
@ -27,9 +27,10 @@ Text {
id: autoHideErrorMessage id: autoHideErrorMessage
interval: 5000 interval: 5000
onTriggered: { onTriggered: {
mainItem.clear() mainItem.clear();
} }
} }
onTextChanged: if (mainItem.text.length > 0) autoHideErrorMessage.restart() onTextChanged: if (mainItem.text.length > 0)
autoHideErrorMessage.restart()
} }

View file

@ -15,7 +15,7 @@ Control.Control {
Rectangle { Rectangle {
id: background id: background
anchors.fill: parent anchors.fill: parent
radius: width/2 radius: width / 2
color: DefaultStyle.danger_500_main color: DefaultStyle.danger_500_main
} }
MultiEffect { MultiEffect {

View file

@ -25,9 +25,18 @@ FocusScope {
spacing: 0 spacing: 0
Repeater { Repeater {
model: [ model: [
{text: qsTr("conference_layout_grid"), imgUrl: AppIcons.layout}, {
{text: qsTr("conference_layout_active_speaker"), imgUrl: AppIcons.pip}, text: qsTr("conference_layout_grid"),
{text: qsTr("conference_layout_audio_only"), imgUrl: AppIcons.waveform} imgUrl: AppIcons.layout
},
{
text: qsTr("conference_layout_active_speaker"),
imgUrl: AppIcons.pip
},
{
text: qsTr("conference_layout_audio_only"),
imgUrl: AppIcons.waveform
}
] ]
RadioButton { RadioButton {
id: radiobutton id: radiobutton
@ -37,12 +46,11 @@ FocusScope {
indicatorSize: Utils.getSizeWithScreenRatio(20) indicatorSize: Utils.getSizeWithScreenRatio(20)
leftPadding: indicator.width + spacing leftPadding: indicator.width + spacing
spacing: Utils.getSizeWithScreenRatio(8) spacing: Utils.getSizeWithScreenRatio(8)
checkable: false // Qt Documentation is wrong: It is true by default. We don't want to change the checked state if the layout change is not effective. checkable:
checked: index == 0 false // Qt Documentation is wrong: It is true by default. We don't want to change the checked state if the layout change is not effective.
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid checked: index == 0 ? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid : index == 1
: index == 1 ? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker : mainItem.conferenceLayout
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker === LinphoneEnums.ConferenceLayout.AudioOnly
: mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.AudioOnly
onClicked: mainItem.changeLayoutRequested(index) onClicked: mainItem.changeLayoutRequested(index)
contentItem: RowLayout { contentItem: RowLayout {
@ -66,6 +74,8 @@ FocusScope {
} }
} }
} }
Item {Layout.fillHeight: true} Item {
Layout.fillHeight: true
}
} }
} }

View file

@ -3,8 +3,8 @@ import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import ConstantsCpp 1.0 import ConstantsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
@ -52,12 +52,11 @@ ColumnLayout {
target: LoginPageCpp target: LoginPageCpp
function onErrorMessageChanged() { function onErrorMessageChanged() {
if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0) if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0)
errorText.setText(LoginPageCpp.errorMessage) errorText.setText(LoginPageCpp.errorMessage);
} }
} }
} }
} }
} }
RowLayout { RowLayout {
@ -92,34 +91,34 @@ ColumnLayout {
target: LoginPageCpp target: LoginPageCpp
function onRegistrationStateChanged() { function onRegistrationStateChanged() {
if (LoginPageCpp.registrationState != LinphoneEnums.RegistrationState.Progress) { if (LoginPageCpp.registrationState != LinphoneEnums.RegistrationState.Progress) {
connectionButton.enabled = true connectionButton.enabled = true;
connectionButtonContent.currentIndex = 0 connectionButtonContent.currentIndex = 0;
} }
} }
function onErrorMessageChanged() { function onErrorMessageChanged() {
connectionButton.enabled = true connectionButton.enabled = true;
connectionButtonContent.currentIndex = 0 connectionButtonContent.currentIndex = 0;
} }
} }
} }
function trigger() { function trigger() {
username.errorMessage = "" username.errorMessage = "";
password.errorMessage = "" password.errorMessage = "";
errorText.text = "" errorText.text = "";
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) { if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) {
if (usernameEdit.text.length == 0) if (usernameEdit.text.length == 0)
//: "Veuillez saisir un nom d'utilisateur" //: "Veuillez saisir un nom d'utilisateur"
username.errorMessage = qsTr("assistant_account_login_missing_username") username.errorMessage = qsTr("assistant_account_login_missing_username");
if (passwordEdit.text.length == 0) if (passwordEdit.text.length == 0)
//: "Veuillez saisir un mot de passe" //: "Veuillez saisir un mot de passe"
password.errorMessage = qsTr("assistant_account_login_missing_password") password.errorMessage = qsTr("assistant_account_login_missing_password");
return return;
} }
LoginPageCpp.login(usernameEdit.text, passwordEdit.text) LoginPageCpp.login(usernameEdit.text, passwordEdit.text);
connectionButton.enabled = false connectionButton.enabled = false;
connectionButtonContent.currentIndex = 1 connectionButtonContent.currentIndex = 1;
} }
onPressed: connectionButton.trigger() onPressed: connectionButton.trigger()
@ -132,6 +131,5 @@ ColumnLayout {
underline: true underline: true
onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl) onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl)
} }
} }
} }

View file

@ -3,12 +3,12 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import SettingsCpp 1.0 import SettingsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
signal encryptionValidationRequested() signal encryptionValidationRequested
property var call property var call
RoundedPane { RoundedPane {
Layout.fillWidth: true Layout.fillWidth: true
@ -31,7 +31,8 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(7) spacing: Utils.getSizeWithScreenRatio(7)
Text { Text {
property bool isPostQuantum: mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp && mainItem.call.core.zrtpStats.isPostQuantum property bool isPostQuantum: mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
&& mainItem.call.core.zrtpStats.isPostQuantum
//: Media encryption : %1 //: Media encryption : %1
text: qsTr("call_stats_media_encryption").arg(mainItem.call.core.encryptionString) text: qsTr("call_stats_media_encryption").arg(mainItem.call.core.encryptionString)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@ -53,7 +54,8 @@ ColumnLayout {
} }
Text { Text {
//: "Algorithme d'accord de clé : %1" //: "Algorithme d'accord de clé : %1"
text: qsTr("call_stats_zrtp_key_agreement_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.keyAgreementAlgo) text: qsTr("call_stats_zrtp_key_agreement_algo").arg(mainItem.call
&& mainItem.call.core.zrtpStats.keyAgreementAlgo)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Utils.getSizeWithScreenRatio(12) pixelSize: Utils.getSizeWithScreenRatio(12)
@ -91,9 +93,13 @@ ColumnLayout {
} }
} }
} }
Item{Layout.fillHeight: true} Item {
Layout.fillHeight: true
}
Button { Button {
visible: mainItem.call && !mainItem.call.core.conference && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp visible: mainItem.call && !mainItem.call.core.conference && mainItem.call.core.encryption
=== LinphoneEnums.MediaEncryption.Zrtp
Layout.fillWidth: true Layout.fillWidth: true
//: "Validation chiffrement" //: "Validation chiffrement"
text: qsTr("call_zrtp_validation_button_label") text: qsTr("call_zrtp_validation_button_label")

View file

@ -3,7 +3,7 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
@ -95,7 +95,7 @@ ColumnLayout {
enabled: mainItem.call enabled: mainItem.call
target: outputAudioDeviceCBox target: outputAudioDeviceCBox
function onCurrentValueChanged() { function onCurrentValueChanged() {
SettingsCpp.lSetPlaybackDevice(outputAudioDeviceCBox.currentValue) SettingsCpp.lSetPlaybackDevice(outputAudioDeviceCBox.currentValue);
} }
} }
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_speaker_title")) Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_speaker_title"))
@ -107,8 +107,10 @@ ColumnLayout {
to: 1.0 to: 1.0
value: SettingsCpp.playbackGain value: SettingsCpp.playbackGain
onMoved: { onMoved: {
if (mainItem.call) SettingsCpp.lSetPlaybackGain(value) if (mainItem.call)
else SettingsCpp.playbackGain = value SettingsCpp.lSetPlaybackGain(value);
else
SettingsCpp.playbackGain = value;
} }
//: %1 volume //: %1 volume
Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_speaker_title")) Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_speaker_title"))
@ -146,7 +148,7 @@ ColumnLayout {
enabled: mainItem.call enabled: mainItem.call
target: inputAudioDeviceCBox target: inputAudioDeviceCBox
function onCurrentValueChanged() { function onCurrentValueChanged() {
SettingsCpp.lSetCaptureDevice(inputAudioDeviceCBox.currentValue) SettingsCpp.lSetCaptureDevice(inputAudioDeviceCBox.currentValue);
} }
} }
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_microphone_title")) Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_microphone_title"))
@ -158,8 +160,10 @@ ColumnLayout {
to: 1.0 to: 1.0
value: SettingsCpp.captureGain value: SettingsCpp.captureGain
onMoved: { onMoved: {
if (mainItem.call) SettingsCpp.lSetCaptureGain(value) if (mainItem.call)
else SettingsCpp.captureGain = value SettingsCpp.lSetCaptureGain(value);
else
SettingsCpp.captureGain = value;
} }
//: %1 volume //: %1 volume
Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_microphone_title")) Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_microphone_title"))
@ -170,7 +174,7 @@ ColumnLayout {
repeat: true repeat: true
running: false running: false
onTriggered: { onTriggered: {
SettingsCpp.updateMicVolume() SettingsCpp.updateMicVolume();
} }
} }
Slider { Slider {
@ -194,13 +198,21 @@ ColumnLayout {
height: parent.height height: parent.height
gradient: Gradient { gradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.vue_meter_light_green } GradientStop {
GradientStop { position: 1.0; color: DefaultStyle.vue_meter_dark_green} position: 0.0
color: DefaultStyle.vue_meter_light_green
}
GradientStop {
position: 1.0
color: DefaultStyle.vue_meter_dark_green
}
} }
radius: Utils.getSizeWithScreenRatio(2) radius: Utils.getSizeWithScreenRatio(2)
} }
} }
handle: Item {visible: false} handle: Item {
visible: false
}
} }
} }
ColumnLayout { ColumnLayout {
@ -235,7 +247,7 @@ ColumnLayout {
enabled: mainItem.call enabled: mainItem.call
target: videoDevicesCbox target: videoDevicesCbox
function onCurrentValueChanged() { function onCurrentValueChanged() {
SettingsCpp.lSetVideoDevice(videoDevicesCbox.currentValue) SettingsCpp.lSetVideoDevice(videoDevicesCbox.currentValue);
} }
} }
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_camera_title")) Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_camera_title"))
@ -243,17 +255,17 @@ ColumnLayout {
} }
Connections { Connections {
target: SettingsCpp target: SettingsCpp
onMicVolumeChanged: (value) => { onMicVolumeChanged: value => {
audioTestSlider.value = value audioTestSlider.value = value;
} }
} }
Component.onCompleted: { Component.onCompleted: {
SettingsCpp.accessCallSettings() SettingsCpp.accessCallSettings();
audioTestSliderTimer.running = true audioTestSliderTimer.running = true;
} }
Component.onDestruction: { Component.onDestruction: {
audioTestSliderTimer.running = false audioTestSliderTimer.running = false;
SettingsCpp.closeCallSettings() SettingsCpp.closeCallSettings();
} }
} }
} }

View file

@ -4,7 +4,7 @@ import QtQuick.Effects
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp 1.0 import UtilsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
@ -12,12 +12,15 @@ ColumnLayout {
property CallGui call property CallGui call
property ConferenceGui conference: call.core.conference property ConferenceGui conference: call.core.conference
property var desc: call.core.videoSourceDescriptor property var desc: call.core.videoSourceDescriptor
property bool isLocalScreenSharing : conference?.core.isLocalScreenSharing || false property bool isLocalScreenSharing: conference?.core.isLocalScreenSharing || false
property bool screenSharingAvailable: !!conference && (!conference.core.isScreenSharingEnabled || isLocalScreenSharing) property bool screenSharingAvailable: !!conference && (!conference.core.isScreenSharingEnabled || isLocalScreenSharing)
spacing: Utils.getSizeWithScreenRatio(12) spacing: Utils.getSizeWithScreenRatio(12)
onIsLocalScreenSharingChanged: {if(isLocalScreenSharing) mainItem.call.core.videoSourceDescriptor = mainItem.desc } onIsLocalScreenSharingChanged: {
if (isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc;
}
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
//: "Veuillez choisir lécran ou la fenêtre que vous souihaitez partager au autres participants" //: "Veuillez choisir lécran ou la fenêtre que vous souihaitez partager au autres participants"
@ -26,8 +29,8 @@ ColumnLayout {
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
} }
TabBar { TabBar {
Layout.fillWidth: true
id: bar id: bar
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(40) spacing: Utils.getSizeWithScreenRatio(40)
pixelSize: Utils.getSizeWithScreenRatio(16) pixelSize: Utils.getSizeWithScreenRatio(16)
//: "Ecran entier" //: "Ecran entier"
@ -37,7 +40,7 @@ ColumnLayout {
} }
component ScreenPreviewLayout: Control.Control { component ScreenPreviewLayout: Control.Control {
id: screenPreview id: screenPreview
signal clicked() signal clicked
property var screenSource property var screenSource
property int screenIndex property int screenIndex
property bool selected: false property bool selected: false
@ -58,32 +61,32 @@ ColumnLayout {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
screenPreview.clicked() screenPreview.clicked();
} }
} }
} }
contentItem: ColumnLayout { contentItem: ColumnLayout {
spacing: 0 spacing: 0
Item{ Item {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Image { Image {
anchors.centerIn: parent anchors.centerIn: parent
//Layout.preferredHeight: Utils.getSizeWithScreenRatio(170) //Layout.preferredHeight: Utils.getSizeWithScreenRatio(170)
source: $modelData?.windowId ? "image://window/"+ $modelData.windowId : "image://screen/"+ $modelData.screenIndex source: $modelData?.windowId ? "image://window/" + $modelData.windowId : "image://screen/" + $modelData.screenIndex
sourceSize.width: parent.width sourceSize.width: parent.width
sourceSize.height: parent.height sourceSize.height: parent.height
cache: false cache: false
} }
} }
RowLayout{ RowLayout {
Layout.topMargin: Utils.getSizeWithScreenRatio(6) Layout.topMargin: Utils.getSizeWithScreenRatio(6)
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
Image{ Image {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(15) Layout.preferredHeight: Utils.getSizeWithScreenRatio(15)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(15) Layout.preferredWidth: Utils.getSizeWithScreenRatio(15)
visible: !!$modelData?.windowId visible: !!$modelData?.windowId
source: visible ? "image://window_icon/"+ $modelData.windowId : '' source: visible ? "image://window_icon/" + $modelData.windowId : ''
sourceSize.width: width sourceSize.width: width
sourceSize.height: height sourceSize.height: height
cache: false cache: false
@ -91,7 +94,7 @@ ColumnLayout {
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
//: "Ecran %1" //: "Ecran %1"
text: !!$modelData?.windowId ? $modelData.name : qsTr("screencast_settings_screen").arg(screenIndex+1) text: !!$modelData?.windowId ? $modelData.name : qsTr("screencast_settings_screen").arg(screenIndex + 1)
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
font.pixelSize: Utils.getSizeWithScreenRatio(displayScreen ? 14 : 10) font.pixelSize: Utils.getSizeWithScreenRatio(displayScreen ? 14 : 10)
elide: Text.ElideRight elide: Text.ElideRight
@ -103,49 +106,54 @@ ColumnLayout {
StackLayout { StackLayout {
id: stacklayout id: stacklayout
currentIndex: bar.currentIndex currentIndex: bar.currentIndex
ListView{ ListView {
id: screensLayout id: screensLayout
spacing: Utils.getSizeWithScreenRatio(16) spacing: Utils.getSizeWithScreenRatio(16)
clip: true clip: true
Layout.fillWidth: true Layout.fillWidth: true
height: visible ? contentHeight : 0 height: visible ? contentHeight : 0
currentIndex: -1 currentIndex: -1
model: ScreenProxy{ model: ScreenProxy {
id: screensList id: screensList
mode: ScreenList.SCREENS mode: ScreenList.SCREENS
} }
onVisibleChanged: { onVisibleChanged: {
if(visible) screensList.update() if (visible)
else currentIndex = -1 screensList.update();
else
currentIndex = -1;
} }
delegate: ScreenPreviewLayout { delegate: ScreenPreviewLayout {
horizontalMargin: Utils.getSizeWithScreenRatio(28 - 20 ) // 20 coming from CallsWindow panel horizontalMargin: Utils.getSizeWithScreenRatio(28 - 20) // 20 coming from CallsWindow panel
width: screensLayout.width width: screensLayout.width
height: Utils.getSizeWithScreenRatio(219) height: Utils.getSizeWithScreenRatio(219)
screenIndex: index screenIndex: index
onClicked: {//screensLayout.selectedIndex = index onClicked: {
screensLayout.currentIndex = index //screensLayout.selectedIndex = index
mainItem.desc.core.screenSharingIndex = index screensLayout.currentIndex = index;
if( mainItem.conference.core.isLocalScreenSharing) mainItem.desc.core.screenSharingIndex = index;
mainItem.call.core.videoSourceDescriptor = mainItem.desc if (mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc;
} }
selected: mainItem.desc.core.screenSharingIndex === index selected: mainItem.desc.core.screenSharingIndex === index
} }
} }
GridView{ GridView {
id: windowsLayout id: windowsLayout
//property int selectedIndex //property int selectedIndex
Layout.preferredHeight: visible ? contentHeight : 0 Layout.preferredHeight: visible ? contentHeight : 0
Layout.fillWidth: true Layout.fillWidth: true
model: ScreenProxy{ model: ScreenProxy {
id: windowsList id: windowsList
mode: ScreenList.WINDOWS mode: ScreenList.WINDOWS
} }
currentIndex: -1 currentIndex: -1
onVisibleChanged: { onVisibleChanged: {
if(visible) windowsList.update() if (visible)
else currentIndex = -1 windowsList.update();
else
currentIndex = -1;
} }
cellWidth: width / 2 cellWidth: width / 2
cellHeight: Utils.getSizeWithScreenRatio(112 + 15) cellHeight: Utils.getSizeWithScreenRatio(112 + 15)
@ -159,10 +167,10 @@ ColumnLayout {
displayScreen: false displayScreen: false
screenIndex: index screenIndex: index
onClicked: { onClicked: {
windowsLayout.currentIndex = index windowsLayout.currentIndex = index;
mainItem.desc.core.windowId = $modelData.windowId mainItem.desc.core.windowId = $modelData.windowId;
if( mainItem.conference.core.isLocalScreenSharing) if (mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc mainItem.call.core.videoSourceDescriptor = mainItem.desc;
} }
selected: mainItem.desc.core.windowId == $modelData.windowId selected: mainItem.desc.core.windowId == $modelData.windowId
} }
@ -174,13 +182,13 @@ ColumnLayout {
height: implicitHeight height: implicitHeight
visible: mainItem.screenSharingAvailable$ visible: mainItem.screenSharingAvailable$
enabled: mainItem.isLocalScreenSharing || windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1 enabled: mainItem.isLocalScreenSharing || windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1
text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing ?
//: "Stop //: "Stop
? qsTr("stop") qsTr("stop") :
//: "Partager" //: "Partager"
: qsTr("share") qsTr("share")
onClicked: { onClicked: {
mainItem.conference.core.lToggleScreenSharing() mainItem.conference.core.lToggleScreenSharing();
} }
style: ButtonStyle.main style: ButtonStyle.main
} }

View file

@ -6,7 +6,7 @@ import QtQuick.Effects
import Linphone import Linphone
import ConstantsCpp 1.0 import ConstantsCpp 1.0
import UtilsCpp 1.0 import UtilsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView { ListView {
@ -33,11 +33,12 @@ ListView {
to: UtilsCpp.addYears(new Date(), 5) to: UtilsCpp.addYears(new Date(), 5)
} }
delegate: FocusScope{ delegate: FocusScope {
width: mainItem.width width: mainItem.width
height: mainItem.height height: mainItem.height
property bool isCurrentIndex: index == mainItem.currentIndex property bool isCurrentIndex: index == mainItem.currentIndex
onIsCurrentIndexChanged: if( isCurrentIndex) monthGrid.forceActiveFocus() onIsCurrentIndexChanged: if (isCurrentIndex)
monthGrid.forceActiveFocus()
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
property int currentMonth: model.month property int currentMonth: model.month
@ -46,7 +47,9 @@ ListView {
Layout.fillWidth: true Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(38) spacing: Utils.getSizeWithScreenRatio(38)
Text { Text {
text: UtilsCpp.toDateMonthAndYearString(new Date(model.year, model.month, 15))// 15 because of timezones that can change the date for localeString text: UtilsCpp.toDateMonthAndYearString(new Date(model.year, model.month,
15))// 15 because of timezones that can change the date for localeString
font { font {
pixelSize: Typography.p2l.pixelSize pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight weight: Typography.p2l.weight
@ -64,7 +67,8 @@ ListView {
icon.height: height icon.height: height
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.leftArrow icon.source: AppIcons.leftArrow
onClicked: if (mainItem.currentIndex > 0) mainItem.currentIndex = mainItem.currentIndex - 1 onClicked: if (mainItem.currentIndex > 0)
mainItem.currentIndex = mainItem.currentIndex - 1
} }
Button { Button {
id: nextButton id: nextButton
@ -74,7 +78,8 @@ ListView {
icon.height: height icon.height: height
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.rightArrow icon.source: AppIcons.rightArrow
onClicked: if (mainItem.currentIndex < mainItem.count) mainItem.currentIndex = mainItem.currentIndex + 1 onClicked: if (mainItem.currentIndex < mainItem.count)
mainItem.currentIndex = mainItem.currentIndex + 1
} }
} }
@ -106,42 +111,44 @@ ListView {
locale: Qt.locale(ConstantsCpp.DefaultLocale) locale: Qt.locale(ConstantsCpp.DefaultLocale)
delegate: FocusScope { delegate: FocusScope {
id: focusDay id: focusDay
property bool isSelectedDay: mainItem.selectedDate ? UtilsCpp.datesAreEqual(mainItem.selectedDate, model.date) : false property bool isSelectedDay: mainItem.selectedDate ? UtilsCpp.datesAreEqual(mainItem.selectedDate, model.date) :
false
property var d: model.date property var d: model.date
objectName: 'focusDay' objectName: 'focusDay'
activeFocusOnTab: true activeFocusOnTab: true
focus: UtilsCpp.isCurrentMonth(model.date) && UtilsCpp.isCurrentDay(model.date) || index == 0 focus: UtilsCpp.isCurrentMonth(model.date) && UtilsCpp.isCurrentDay(model.date) || index == 0
Keys.onPressed: (event)=> { Keys.onPressed: event => {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
monthGrid.clicked(model.date) monthGrid.clicked(model.date);
event.accepted = true; event.accepted = true;
}else if(event.key == Qt.Key_Left){ } else if (event.key == Qt.Key_Left) {
var previous = nextItemInFocusChain(false) var previous = nextItemInFocusChain(false);
if( previous.objectName != 'focusDay'){ if (previous.objectName != 'focusDay') {
previousButton.clicked(undefined) previousButton.clicked(undefined);
}else{
if (UtilsCpp.daysOffset(new Date(), model.date) >= 0) previous.forceActiveFocus()
}
}else if(event.key == Qt.Key_Right){
var next = nextItemInFocusChain()
if( next.objectName != 'focusDay'){
nextButton.clicked(undefined)
} else { } else {
next.forceActiveFocus() if (UtilsCpp.daysOffset(new Date(), model.date) >= 0)
previous.forceActiveFocus();
}
} else if (event.key == Qt.Key_Right) {
var next = nextItemInFocusChain();
if (next.objectName != 'focusDay') {
nextButton.clicked(undefined);
} else {
next.forceActiveFocus();
} }
} }
} }
MouseArea{ MouseArea {
id: hoveringArea id: hoveringArea
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
// onEntered: focusDay.forceActiveFocus() // onEntered: focusDay.forceActiveFocus()
onPressed: (event) =>{ onPressed: event => {
focusDay.forceActiveFocus() focusDay.forceActiveFocus();
event.accepted = false event.accepted = false;
} }
} }
@ -152,26 +159,22 @@ ListView {
radius: Utils.getSizeWithScreenRatio(50) radius: Utils.getSizeWithScreenRatio(50)
color: isSelectedDay ? DefaultStyle.main1_500_main : "transparent" color: isSelectedDay ? DefaultStyle.main1_500_main : "transparent"
border.width: focusDay.activeFocus || hoveringArea.containsMouse ? 1 : 0 border.width: focusDay.activeFocus || hoveringArea.containsMouse ? 1 : 0
} }
Text { Text {
anchors.centerIn: parent anchors.centerIn: parent
text: UtilsCpp.toDateDayString(model.date) text: UtilsCpp.toDateDayString(model.date)
color: isSelectedDay color: isSelectedDay ? DefaultStyle.grey_0 : UtilsCpp.isCurrentDay(model.date) ? DefaultStyle.main1_500_main : UtilsCpp.dateisInMonth(
? DefaultStyle.grey_0 model.date, mainItem.currentMonth, mainItem.currentYear) ? DefaultStyle.main2_700 :
: UtilsCpp.isCurrentDay(model.date) DefaultStyle.main2_400
? DefaultStyle.main1_500_main
: UtilsCpp.dateisInMonth(model.date, mainItem.currentMonth, mainItem.currentYear)
? DefaultStyle.main2_700
: DefaultStyle.main2_400
font { font {
pixelSize: Utils.getSizeWithScreenRatio(12) pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
} }
onClicked: (date) => { onClicked: date => {
if (UtilsCpp.daysOffset(new Date(), date) >= 0) mainItem.selectedDate = date if (UtilsCpp.daysOffset(new Date(), date) >= 0)
mainItem.selectedDate = date;
} }
} }
} }

View file

@ -5,8 +5,8 @@ import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Control { Control.Control {
id: mainItem id: mainItem
@ -18,7 +18,7 @@ Control.Control {
// property alias cursorPosition: sendingTextArea.cursorPosition // property alias cursorPosition: sendingTextArea.cursorPosition
property bool dropEnabled: true property bool dropEnabled: true
property bool isEphemeral : false property bool isEphemeral: false
property bool emojiVisible: false property bool emojiVisible: false
// disable record button if call ongoing // disable record button if call ongoing
@ -27,29 +27,29 @@ Control.Control {
property ChatGui chat property ChatGui chat
signal focusTextArea() signal focusTextArea
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
signal dropped (var files) signal dropped(var files)
signal validText (string text) signal validText(string text)
signal sendMessage() signal sendMessage
signal emojiClicked() signal emojiClicked
signal composing() signal composing
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function _emitFiles (files) { function _emitFiles(files) {
// Filtering files, other urls are forbidden. // Filtering files, other urls are forbidden.
files = files.reduce(function (files, file) { files = files.reduce(function (files, file) {
if (file.toString().startsWith("file:")) { if (file.toString().startsWith("file:")) {
files.push(Utils.getSystemPathFromUri(file)) files.push(Utils.getSystemPathFromUri(file));
} }
return files return files;
}, []) }, []);
if (files.length > 0) { if (files.length > 0) {
dropped(files) dropped(files);
} }
} }
@ -74,7 +74,7 @@ Control.Control {
id: sendingAreaStackView id: sendingAreaStackView
initialItem: textAreaComp initialItem: textAreaComp
onHeightChanged: { onHeightChanged: {
mainItem.height = height + mainItem.topPadding + mainItem.bottomPadding mainItem.height = height + mainItem.topPadding + mainItem.bottomPadding;
} }
Component { Component {
id: textAreaComp id: textAreaComp
@ -95,7 +95,7 @@ Control.Control {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.paperclip icon.source: AppIcons.paperclip
onClicked: { onClicked: {
fileDialog.open() fileDialog.open();
} }
} }
Control.Control { Control.Control {
@ -129,21 +129,23 @@ Control.Control {
contentWidth: width contentWidth: width
onContentHeightChanged: { onContentHeightChanged: {
if (sendingTextArea.contentHeight > mainItem.height - (mainItem.topPadding + mainItem.bottomPadding + sendingControl.topPadding + sendingControl.bottomPadding) if (sendingTextArea.contentHeight > mainItem.height - (mainItem.topPadding + mainItem.bottomPadding
&& sendingTextArea.contentHeight < Utils.getSizeWithScreenRatio(100)) { + sendingControl.topPadding + sendingControl.bottomPadding) && sendingTextArea.contentHeight
mainItem.height = sendingTextArea.contentHeight + mainItem.topPadding + mainItem.bottomPadding + sendingControl.topPadding + sendingControl.bottomPadding < Utils.getSizeWithScreenRatio(100)) {
mainItem.height = sendingTextArea.contentHeight + mainItem.topPadding + mainItem.bottomPadding
+ sendingControl.topPadding + sendingControl.bottomPadding;
} }
} }
function ensureVisible(r) { function ensureVisible(r) {
if (contentX >= r.x) if (contentX >= r.x)
contentX = r.x; contentX = r.x;
else if (contentX+width <= r.x+r.width) else if (contentX + width <= r.x + r.width)
contentX = r.x+r.width-width; contentX = r.x + r.width - width;
if (contentY >= r.y) if (contentY >= r.y)
contentY = r.y; contentY = r.y;
else if (contentY+height <= r.y+r.height) else if (contentY + height <= r.y + r.height)
contentY = r.y+r.height-height; contentY = r.y + r.height - height;
} }
TextArea { TextArea {
@ -152,12 +154,12 @@ Control.Control {
height: implicitHeight// sendingAreaFlickable.height height: implicitHeight// sendingAreaFlickable.height
textFormat: TextEdit.PlainText textFormat: TextEdit.PlainText
onTextChanged: { onTextChanged: {
mainItem.text = text mainItem.text = text;
} }
Component.onCompleted: { Component.onCompleted: {
mainItem.textArea = sendingTextArea mainItem.textArea = sendingTextArea;
sendingTextArea.text = mainItem.text sendingTextArea.text = mainItem.text;
} }
//: Say something : placeholder text for sending message text area //: Say something : placeholder text for sending message text area
placeholderText: qsTr("chat_view_send_area_placeholder_text") placeholderText: qsTr("chat_view_send_area_placeholder_text")
@ -170,23 +172,23 @@ Control.Control {
onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle) onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle)
wrapMode: TextEdit.WordWrap wrapMode: TextEdit.WordWrap
KeyNavigation.tab: recordButton.visible ? recordButton : sendMessageButton KeyNavigation.tab: recordButton.visible ? recordButton : sendMessageButton
Keys.onPressed: (event) => { Keys.onPressed: event => {
if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return)) if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return))
if(!(event.modifiers & Qt.ShiftModifier)) { if (!(event.modifiers & Qt.ShiftModifier)) {
mainItem.sendMessage() mainItem.sendMessage();
event.accepted = true event.accepted = true;
} }
} }
Connections { Connections {
target: mainItem target: mainItem
function onTextChanged() { function onTextChanged() {
sendingTextArea.text = mainItem.text sendingTextArea.text = mainItem.text;
} }
function onSendMessage() { function onSendMessage() {
sendingTextArea.clear() sendingTextArea.clear();
} }
function onFocusTextArea() { function onFocusTextArea() {
sendingTextArea.forceActiveFocus() sendingTextArea.forceActiveFocus();
} }
} }
} }
@ -201,12 +203,13 @@ Control.Control {
//: Cannot record a message while a call is ongoing //: Cannot record a message while a call is ongoing
ToolTip.text: qsTr("cannot_record_while_in_call_tooltip") ToolTip.text: qsTr("cannot_record_while_in_call_tooltip")
enabled: !mainItem.callOngoing enabled: !mainItem.callOngoing
visible: !mainItem.callOngoing && sendingTextArea.text.length === 0 && mainItem.selectedFilesCount === 0 && !mainItem.isEditing visible: !mainItem.callOngoing && sendingTextArea.text.length === 0 && mainItem.selectedFilesCount === 0 &&
!mainItem.isEditing
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
hoverEnabled: true hoverEnabled: true
icon.source: AppIcons.microphone icon.source: AppIcons.microphone
onClicked: { onClicked: {
sendingAreaStackView.push(voiceMessageRecordComp) sendingAreaStackView.push(voiceMessageRecordComp);
} }
} }
BigButton { BigButton {
@ -216,7 +219,7 @@ Control.Control {
style: ButtonStyle.noBackgroundOrange style: ButtonStyle.noBackgroundOrange
icon.source: mainItem.isEditing ? AppIcons.pencil : AppIcons.paperPlaneRight icon.source: mainItem.isEditing ? AppIcons.pencil : AppIcons.paperPlaneRight
onClicked: { onClicked: {
mainItem.sendMessage() mainItem.sendMessage();
} }
} }
} }
@ -239,21 +242,22 @@ Control.Control {
Layout.preferredWidth: width Layout.preferredWidth: width
Layout.preferredHeight: height Layout.preferredHeight: height
onClicked: { onClicked: {
if (voiceMessage.chatMessage) mainItem.chat.core.lDeleteMessage(voiceMessage.chatMessage) if (voiceMessage.chatMessage)
sendingAreaStackView.pop() mainItem.chat.core.lDeleteMessage(voiceMessage.chatMessage);
sendingAreaStackView.pop();
} }
} }
ChatAudioContent { ChatAudioContent {
id: voiceMessage id: voiceMessage
onHeightChanged: { onHeightChanged: {
sendingAreaStackView.height = height sendingAreaStackView.height = height;
} }
recording: true recording: true
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(48) Layout.preferredHeight: Utils.getSizeWithScreenRatio(48)
chatMessageContentGui: chatMessage ? chatMessage.core.getVoiceRecordingContent() : null chatMessageContentGui: chatMessage ? chatMessage.core.getVoiceRecordingContent() : null
onVoiceRecordingMessageCreationRequested: (recorderGui) => { onVoiceRecordingMessageCreationRequested: recorderGui => {
chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderGui, mainItem.chat) chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderGui, mainItem.chat);
} }
} }
BigButton { BigButton {
@ -267,21 +271,20 @@ Control.Control {
property bool sendVoiceRecordingOnCreated: false property bool sendVoiceRecordingOnCreated: false
onClicked: { onClicked: {
if (voiceMessage.chatMessage) { if (voiceMessage.chatMessage) {
voiceMessage.chatMessage.core.lSend() voiceMessage.chatMessage.core.lSend();
sendingAreaStackView.pop() sendingAreaStackView.pop();
} } else {
else { sendVoiceRecordingOnCreated = true;
sendVoiceRecordingOnCreated = true voiceMessage.stopRecording();
voiceMessage.stopRecording()
} }
} }
Connections { Connections {
target: voiceMessage target: voiceMessage
function onChatMessageChanged() { function onChatMessageChanged() {
if (sendButton.sendVoiceRecordingOnCreated) { if (sendButton.sendVoiceRecordingOnCreated) {
voiceMessage.chatMessage.core.lSend() voiceMessage.chatMessage.core.lSend();
sendButton.sendVoiceRecordingOnCreated = false sendButton.sendVoiceRecordingOnCreated = false;
sendingAreaStackView.pop() sendingAreaStackView.pop();
} }
} }
} }
@ -316,13 +319,13 @@ Control.Control {
} }
DropArea { DropArea {
anchors.fill: parent anchors.fill: parent
keys: [ 'text/uri-list' ] keys: ['text/uri-list']
visible: mainItem.dropEnabled visible: mainItem.dropEnabled
onDropped: (drop) => { onDropped: drop => {
state = '' state = '';
if (drop.hasUrls) { if (drop.hasUrls) {
_emitFiles(drop.urls) _emitFiles(drop.urls);
} }
} }
onEntered: state = 'hover' onEntered: state = 'hover'
@ -330,7 +333,10 @@ Control.Control {
states: State { states: State {
name: 'hover' name: 'hover'
PropertyChanges { target: hoverContent; visible: true } PropertyChanges {
target: hoverContent
visible: true
}
} }
} }
} }

View file

@ -24,7 +24,7 @@ FormItemLayout {
property var value: propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName] property var value: propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName]
function value() { function value() {
return propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName] return propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName];
} }
property alias hidden: textField.hidden property alias hidden: textField.hidden
@ -34,19 +34,20 @@ FormItemLayout {
property alias customCallback: textField.customCallback property alias customCallback: textField.customCallback
property alias customButtonAccessibleName: textField.customButtonAccessibleName property alias customButtonAccessibleName: textField.customButtonAccessibleName
property var isValid: function(text) { property var isValid: function (text) {
return true return true;
} }
function empty() { function empty() {
textField.text = "" textField.text = "";
} }
contentItem: TextField { contentItem: TextField {
id: textField id: textField
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
placeholderText: useTitleAsPlaceHolder ? mainItem.title : mainItem.placeHolder placeholderText: useTitleAsPlaceHolder ? mainItem.title : mainItem.placeHolder
initialText: (mainItem.propertyOwnerGui ? mainItem.propertyOwnerGui.core[mainItem.propertyName] : mainItem.propertyOwner[mainItem.propertyName]) || '' initialText: (mainItem.propertyOwnerGui ? mainItem.propertyOwnerGui.core[mainItem.propertyName] :
mainItem.propertyOwner[mainItem.propertyName]) || ''
customWidth: mainItem.parent.width customWidth: mainItem.parent.width
propertyName: mainItem.propertyName propertyName: mainItem.propertyName
propertyOwner: mainItem.propertyOwner propertyOwner: mainItem.propertyOwner
@ -54,18 +55,18 @@ FormItemLayout {
canBeEmpty: mainItem.canBeEmpty canBeEmpty: mainItem.canBeEmpty
isValid: mainItem.isValid isValid: mainItem.isValid
toValidate: mainItem.toValidate toValidate: mainItem.toValidate
onValidationChecked: (isValid) => { onValidationChecked: isValid => {
if (isValid) return if (isValid)
return;
if (!canBeEmpty && empty) { if (!canBeEmpty && empty) {
//: "ne peut être vide" //: "ne peut être vide"
mainItem.errorMessage = qsTr("textfield_error_message_cannot_be_empty") mainItem.errorMessage = qsTr("textfield_error_message_cannot_be_empty");
} else { } else {
//: "Format non reconnu" //: "Format non reconnu"
mainItem.errorMessage = qsTr("textfield_error_message_unknown_format") mainItem.errorMessage = qsTr("textfield_error_message_unknown_format");
} }
} }
onTextChanged: mainItem.clearErrorText() onTextChanged: mainItem.clearErrorText()
Accessible.name: mainItem.title Accessible.name: mainItem.title
} }
} }

View file

@ -8,7 +8,10 @@ Control.TextField {
property real inputSize: Utils.getSizeWithScreenRatio(100) property real inputSize: Utils.getSizeWithScreenRatio(100)
property bool isError: false property bool isError: false
color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main
validator: IntValidator{bottom: 0; top: 9} validator: IntValidator {
bottom: 0
top: 9
}
width: inputSize * 0.9 width: inputSize * 0.9
height: inputSize height: inputSize
@ -21,7 +24,7 @@ Control.TextField {
placeholderTextColor: "transparent" placeholderTextColor: "transparent"
// cursorVisible is overwritten on focus change so useless to hide the cursor // cursorVisible is overwritten on focus change so useless to hide the cursor
cursorDelegate: Item{} cursorDelegate: Item {}
// horizontalAlignment: Control.TextField.AlignHCenter // horizontalAlignment: Control.TextField.AlignHCenter
font.family: DefaultStyle.defaultFont font.family: DefaultStyle.defaultFont
@ -35,11 +38,8 @@ Control.TextField {
Rectangle { Rectangle {
id: background id: background
border.width: Utils.getSizeWithScreenRatio(1) border.width: Utils.getSizeWithScreenRatio(1)
border.color: mainItem.isError border.color: mainItem.isError ? DefaultStyle.danger_500_main : mainItem.activeFocus ? DefaultStyle.main1_500_main :
? DefaultStyle.danger_500_main DefaultStyle.main2_500_main
: mainItem.activeFocus
? DefaultStyle.main1_500_main
: DefaultStyle.main2_500_main
radius: mainItem.inputSize * 0.15 radius: mainItem.inputSize * 0.15
width: mainItem.inputSize * 0.9 width: mainItem.inputSize * 0.9
height: mainItem.inputSize height: mainItem.inputSize
@ -48,7 +48,7 @@ Control.TextField {
id: indicator id: indicator
visible: mainItem.activeFocus visible: mainItem.activeFocus
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
height : Utils.getSizeWithScreenRatio(1) height: Utils.getSizeWithScreenRatio(1)
width: mainItem.inputSize * 0.67 width: mainItem.inputSize * 0.67
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom anchors.bottom: parent.bottom

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts as Layout
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope { FocusScope {
@ -15,19 +15,21 @@ FocusScope {
property var currentCall property var currentCall
property bool lastRowVisible: true property bool lastRowVisible: true
onButtonPressed: (text) => { onButtonPressed: text => {
if (currentCall) currentCall.core.lSendDtmf(text) if (currentCall)
else UtilsCpp.playDtmf(text) currentCall.core.lSendDtmf(text);
else
UtilsCpp.playDtmf(text);
} }
signal buttonPressed(string text) signal buttonPressed(string text)
signal launchCall() signal launchCall
signal wipe() signal wipe
function keypadKeyPressedAtIndex(index) { function keypadKeyPressedAtIndex(index) {
var button = numPadGrid.getButtonAt(index) var button = numPadGrid.getButtonAt(index);
button.shadowEnabled = true button.shadowEnabled = true;
button.clicked() button.clicked();
removeButtonsShadow.restart() removeButtonsShadow.restart();
} }
Timer { Timer {
@ -36,74 +38,74 @@ FocusScope {
repeat: false repeat: false
onTriggered: { onTriggered: {
for (var i = 0; i < 12; i++) { for (var i = 0; i < 12; i++) {
numPadGrid.getButtonAt(i).shadowEnabled = false numPadGrid.getButtonAt(i).shadowEnabled = false;
} }
} }
} }
function handleKeyPadEvent(event) { function handleKeyPadEvent(event) {
if (event.key === Qt.Key_0) { if (event.key === Qt.Key_0) {
keypadKeyPressedAtIndex(10) keypadKeyPressedAtIndex(10);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_1) { if (event.key === Qt.Key_1) {
keypadKeyPressedAtIndex(0) keypadKeyPressedAtIndex(0);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_2) { if (event.key === Qt.Key_2) {
keypadKeyPressedAtIndex(1) keypadKeyPressedAtIndex(1);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_3) { if (event.key === Qt.Key_3) {
keypadKeyPressedAtIndex(2) keypadKeyPressedAtIndex(2);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_4) { if (event.key === Qt.Key_4) {
keypadKeyPressedAtIndex(3) keypadKeyPressedAtIndex(3);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_5) { if (event.key === Qt.Key_5) {
keypadKeyPressedAtIndex(4) keypadKeyPressedAtIndex(4);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_6) { if (event.key === Qt.Key_6) {
keypadKeyPressedAtIndex(5) keypadKeyPressedAtIndex(5);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_7) { if (event.key === Qt.Key_7) {
keypadKeyPressedAtIndex(6) keypadKeyPressedAtIndex(6);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_8) { if (event.key === Qt.Key_8) {
keypadKeyPressedAtIndex(7) keypadKeyPressedAtIndex(7);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_9) { if (event.key === Qt.Key_9) {
keypadKeyPressedAtIndex(8) keypadKeyPressedAtIndex(8);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_Asterisk) { if (event.key === Qt.Key_Asterisk) {
keypadKeyPressedAtIndex(9) keypadKeyPressedAtIndex(9);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_Plus) { if (event.key === Qt.Key_Plus) {
mainItem.buttonPressed("+") mainItem.buttonPressed("+");
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
mainItem.launchCall() mainItem.launchCall();
event.accepted = true event.accepted = true;
} }
} }
Keys.onPressed: (event) => { Keys.onPressed: event => {
event.accepted = false event.accepted = false;
if (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return) { if (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return) {
handleKeyPadEvent(event) handleKeyPadEvent(event);
} }
if (event.key === Qt.Key_Backspace) { if (event.key === Qt.Key_Backspace) {
mainItem.wipe() mainItem.wipe();
event.accepted = true event.accepted = true;
} }
} }
@ -112,17 +114,17 @@ FocusScope {
columns: 3 columns: 3
columnSpacing: Utils.getSizeWithScreenRatio(40) columnSpacing: Utils.getSizeWithScreenRatio(40)
rowSpacing: Utils.getSizeWithScreenRatio(10) rowSpacing: Utils.getSizeWithScreenRatio(10)
function getButtonAt(index){ function getButtonAt(index) {
index = (index+15) % 15 index = (index + 15) % 15;
if(index >= 0){ if (index >= 0) {
if( index < 9){ if (index < 9) {
return numPadRepeater.itemAt(index) return numPadRepeater.itemAt(index);
}else if( index < 12){ } else if (index < 12) {
return digitRepeater.itemAt(index-9) return digitRepeater.itemAt(index - 9);
}else if (index < 14){ } else if (index < 14) {
return launchCallButton return launchCallButton;
}else if( index < 15){ } else if (index < 15) {
return eraseButton return eraseButton;
} }
} }
} }
@ -136,7 +138,7 @@ FocusScope {
implicitWidth: Utils.getSizeWithScreenRatio(60) implicitWidth: Utils.getSizeWithScreenRatio(60)
implicitHeight: Utils.getSizeWithScreenRatio(60) implicitHeight: Utils.getSizeWithScreenRatio(60)
onClicked: { onClicked: {
mainItem.buttonPressed(text) mainItem.buttonPressed(text);
} }
KeyNavigation.left: numPadGrid.getButtonAt(index - 1) KeyNavigation.left: numPadGrid.getButtonAt(index - 1)
KeyNavigation.right: numPadGrid.getButtonAt(index + 1) KeyNavigation.right: numPadGrid.getButtonAt(index + 1)
@ -152,9 +154,16 @@ FocusScope {
Repeater { Repeater {
id: digitRepeater id: digitRepeater
model: [ model: [
{pressText: "*"}, {
{pressText: "0", longPressText: "+"}, pressText: "*"
{pressText: "#"} },
{
pressText: "0",
longPressText: "+"
},
{
pressText: "#"
}
] ]
BigButton { BigButton {
id: digitButton id: digitButton
@ -165,15 +174,16 @@ FocusScope {
onClicked: mainItem.buttonPressed(pressText.text) onClicked: mainItem.buttonPressed(pressText.text)
onPressAndHold: mainItem.buttonPressed(longPressText.text) onPressAndHold: mainItem.buttonPressed(longPressText.text)
KeyNavigation.left: numPadGrid.getButtonAt((index - 1)+9) KeyNavigation.left: numPadGrid.getButtonAt((index - 1) + 9)
KeyNavigation.right: numPadGrid.getButtonAt((index + 1)+9) KeyNavigation.right: numPadGrid.getButtonAt((index + 1) + 9)
KeyNavigation.up: numPadGrid.getButtonAt((index - 3)+9) KeyNavigation.up: numPadGrid.getButtonAt((index - 3) + 9)
KeyNavigation.down: numPadGrid.getButtonAt((index + 3)+9) KeyNavigation.down: numPadGrid.getButtonAt((index + 3) + 9)
radius: Utils.getSizeWithScreenRatio(71) radius: Utils.getSizeWithScreenRatio(71)
style: ButtonStyle.numericPad style: ButtonStyle.numericPad
//: %1 longpress %2 //: %1 longpress %2
Accessible.name: longPressText.text ? qsTr("numpad_longpress_accessible_name").arg(pressText.text).arg(longPressText.text) : pressText.text Accessible.name: longPressText.text ? qsTr("numpad_longpress_accessible_name").arg(pressText.text).arg(
longPressText.text) : pressText.text
contentItem: Item { contentItem: Item {
anchors.fill: parent anchors.fill: parent
@ -184,7 +194,10 @@ FocusScope {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
Component.onCompleted: {if (modelData.longPressText === undefined) anchors.centerIn= parent} Component.onCompleted: {
if (modelData.longPressText === undefined)
anchors.centerIn = parent;
}
text: modelData.pressText text: modelData.pressText
font.pixelSize: Utils.getSizeWithScreenRatio(32) font.pixelSize: Utils.getSizeWithScreenRatio(32)
} }
@ -194,7 +207,7 @@ FocusScope {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
color: digitButton.pressed ? digitButton.pressedTextColor : digitButton.textColor color: digitButton.pressed ? digitButton.pressedTextColor : digitButton.textColor
y: digitButton.height/2 y: digitButton.height / 2
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
visible: modelData.longPressText ? modelData.longPressText.length > 0 : false visible: modelData.longPressText ? modelData.longPressText.length > 0 : false
text: modelData.longPressText ? modelData.longPressText : "" text: modelData.longPressText ? modelData.longPressText : ""

View file

@ -10,7 +10,7 @@ ColumnLayout {
property string label: "" property string label: ""
property alias errorMessage: errorText.text property alias errorMessage: errorText.text
property string placeholderText : "" property string placeholderText: ""
property bool mandatory: false property bool mandatory: false
property bool enableErrorText: true property bool enableErrorText: true
property real textInputWidth: width property real textInputWidth: width
@ -44,11 +44,8 @@ ColumnLayout {
anchors.fill: parent anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(63) radius: Utils.getSizeWithScreenRatio(63)
color: DefaultStyle.grey_100 color: DefaultStyle.grey_100
border.color: mainItem.errorMessage.length > 0 border.color: mainItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : (textField.activeFocus
? DefaultStyle.danger_500_main || combobox.activeFocus) ? DefaultStyle.main1_500_main : DefaultStyle.grey_200
: (textField.activeFocus || combobox.activeFocus)
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200
border.width: mainItem.borderWidth border.width: mainItem.borderWidth
} }
contentItem: RowLayout { contentItem: RowLayout {
@ -80,7 +77,9 @@ ColumnLayout {
border.width: mainItem.keyboardFocusedBorderWidth border.width: mainItem.keyboardFocusedBorderWidth
} }
initialText: initialPhoneNumber initialText: initialPhoneNumber
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/} validator: RegularExpressionValidator {
regularExpression: /[0-9]+/
}
//: %1 number //: %1 number
Accessible.name: qsTr("number_phone_number_accessible_name").arg(mainItem.Accessible.name) Accessible.name: qsTr("number_phone_number_accessible_name").arg(mainItem.Accessible.name)
} }

View file

@ -3,13 +3,13 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import CustomControls 1.0 import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
FocusScope { FocusScope {
id: mainItem id: mainItem
property bool magnifierVisible: true property bool magnifierVisible: true
property var validator: RegularExpressionValidator{} property var validator: RegularExpressionValidator {}
property var numericPadPopup property var numericPadPopup
property alias numericPadButton: dialerButton property alias numericPadButton: dialerButton
readonly property bool hasActiveFocus: textField.activeFocus readonly property bool hasActiveFocus: textField.activeFocus
@ -28,31 +28,33 @@ FocusScope {
property real textInputWidth: Utils.getSizeWithScreenRatio(350) property real textInputWidth: Utils.getSizeWithScreenRatio(350)
property string text: textField.searchText property string text: textField.searchText
signal openNumericPadRequested()// Useful for redirection before displaying numeric pad. signal openNumericPadRequested// Useful for redirection before displaying numeric pad.
function clearText() { function clearText() {
textField.text = "" textField.text = "";
} }
Connections { Connections {
enabled: numericPadPopup != undefined && handleNumericPadPopupButtonsPressed enabled: numericPadPopup != undefined && handleNumericPadPopupButtonsPressed
target: numericPadPopup ? numericPadPopup : null target: numericPadPopup ? numericPadPopup : null
function onButtonPressed(text) { function onButtonPressed(text) {
textField.text += text textField.text += text;
}
function onWipe() {
textField.text = textField.text.slice(0, -1);
} }
function onWipe(){ textField.text = textField.text.slice(0, -1)}
} }
implicitWidth: mainItem.textInputWidth implicitWidth: mainItem.textInputWidth
implicitHeight: Utils.getSizeWithScreenRatio(50) implicitHeight: Utils.getSizeWithScreenRatio(50)
Rectangle{ Rectangle {
id: backgroundItem id: backgroundItem
anchors.fill: parent anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(28) radius: Utils.getSizeWithScreenRatio(28)
color: DefaultStyle.grey_100 color: DefaultStyle.grey_100
border.color: textField.keyboardFocus ? mainItem.keyboardFocusedBorderColor : textField.activeFocus ? mainItem.focusedBorderColor : mainItem.borderColor border.color: textField.keyboardFocus ? mainItem.keyboardFocusedBorderColor : textField.activeFocus
? mainItem.focusedBorderColor : mainItem.borderColor
border.width: textField.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth border.width: textField.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
EffectImage { EffectImage {
@ -98,17 +100,18 @@ FocusScope {
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
width: Utils.getSizeWithScreenRatio(1) width: Utils.getSizeWithScreenRatio(1)
} }
Timer{ Timer {
id: delayTimer id: delayTimer
interval: 300 interval: 300
repeat: false repeat: false
onTriggered: textField.searchText = textField.text onTriggered: textField.searchText = textField.text
} }
Keys.onPressed: (event) => { Keys.onPressed: event => {
event.accepted = false event.accepted = false;
if (mainItem.numericPadPopup && mainItem.numericPadPopup.opened && (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return)) { if (mainItem.numericPadPopup && mainItem.numericPadPopup.opened && (event.modifiers & Qt.KeypadModifier
mainItem.numericPadPopup.keyPadKeyPressed(event) || event.key === Qt.Key_Return)) {
event.accepted = true mainItem.numericPadPopup.keyPadKeyPressed(event);
event.accepted = true;
} }
} }
} }
@ -130,10 +133,11 @@ FocusScope {
//: "Open dialer" //: "Open dialer"
Accessible.name: qsTr("open_dialer_acccessibility_label") Accessible.name: qsTr("open_dialer_acccessibility_label")
onClicked: { onClicked: {
if(!checked){ if (!checked) {
mainItem.openNumericPadRequested() mainItem.openNumericPadRequested();
mainItem.numericPadPopup.open() mainItem.numericPadPopup.open();
} else mainItem.numericPadPopup.close() } else
mainItem.numericPadPopup.close();
} }
} }
Button { Button {
@ -150,7 +154,7 @@ FocusScope {
//: "Clear text input" //: "Clear text input"
Accessible.name: qsTr("clear_text_input_acccessibility_label") Accessible.name: qsTr("clear_text_input_acccessibility_label")
onClicked: { onClicked: {
textField.clear() textField.clear();
} }
} }
} }

View file

@ -25,15 +25,14 @@ TextEdit {
property string richFormatText: encodeTextObj && encodeTextObj.value || "" property string richFormatText: encodeTextObj && encodeTextObj.value || ""
property color textAreaColor property color textAreaColor
Component.onCompleted: { Component.onCompleted: {
mainItem.textAreaColor = mainItem.color // backup original color mainItem.textAreaColor = mainItem.color; // backup original color
if (displayAsRichText) if (displayAsRichText)
mainItem.color = 'transparent' mainItem.color = 'transparent';
} }
onTextChanged: { onTextChanged: {
encodeTextObj = UtilsCpp.encodeTextToQmlRichFormat(text) encodeTextObj = UtilsCpp.encodeTextToQmlRichFormat(text);
} }
MouseArea { MouseArea {
@ -75,13 +74,13 @@ TextEdit {
anchors.fill: parent anchors.fill: parent
focus: false focus: false
onHoveredLinkChanged: { onHoveredLinkChanged: {
mainItem.hovered = mainItem.displayAsRichText && hoveredLink !== "" mainItem.hovered = mainItem.displayAsRichText && hoveredLink !== "";
} }
onLinkActivated: { onLinkActivated: {
if (link.startsWith('sip')) if (link.startsWith('sip'))
UtilsCpp.createCall(link) UtilsCpp.createCall(link);
else else
Qt.openUrlExternally(link) Qt.openUrlExternally(link);
} }
} }
} }

View file

@ -3,7 +3,7 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import CustomControls 1.0 import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.TextField { Control.TextField {
@ -12,16 +12,15 @@ Control.TextField {
width: Utils.getSizeWithScreenRatio(customWidth ? customWidth - 1 : 360) width: Utils.getSizeWithScreenRatio(customWidth ? customWidth - 1 : 360)
height: Utils.getSizeWithScreenRatio(49) height: Utils.getSizeWithScreenRatio(49)
leftPadding: Utils.getSizeWithScreenRatio(15) leftPadding: Utils.getSizeWithScreenRatio(15)
rightPadding: eyeButton.visible rightPadding: eyeButton.visible ? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin :
? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin Utils.getSizeWithScreenRatio(15)
: Utils.getSizeWithScreenRatio(15)
echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
// Workaround for Windows slowness when first typing a password // Workaround for Windows slowness when first typing a password
// due to Qt not initializing the Password echo mode before the first letter is typed // due to Qt not initializing the Password echo mode before the first letter is typed
Component.onCompleted: { Component.onCompleted: {
text = "workaround" text = "workaround";
resetText() resetText();
} }
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
@ -68,54 +67,54 @@ Control.TextField {
property var propertyOwnerGui property var propertyOwnerGui
property var initialReading: true property var initialReading: true
property var isValid: function (text) { property var isValid: function (text) {
return true return true;
} }
property bool toValidate: false property bool toValidate: false
property int idleTimeOut: 200 property int idleTimeOut: 200
property bool empty: propertyOwnerGui property bool empty: propertyOwnerGui ? mainItem.propertyOwnerGui.core != undefined
? mainItem.propertyOwnerGui.core != undefined && mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0 && mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0 : mainItem.propertyOwner != undefined
: mainItem.propertyOwner != undefined && mainItem.propertyOwner[mainItem.propertyName]?.length == 0 && mainItem.propertyOwner[mainItem.propertyName]?.length == 0
property bool canBeEmpty: true property bool canBeEmpty: true
signal validationChecked(bool valid) signal validationChecked(bool valid)
function resetText() { function resetText() {
text = initialText text = initialText;
} }
signal enterPressed signal enterPressed
onAccepted: { onAccepted: {
// No need to process changing focus because of TextEdited callback. // No need to process changing focus because of TextEdited callback.
idleTimer.stop() idleTimer.stop();
updateText() updateText();
} }
onTextChanged: { onTextChanged: {
if (mainItem.toValidate) { if (mainItem.toValidate) {
idleTimer.restart() idleTimer.restart();
} }
} }
function updateText() { function updateText() {
mainItem.empty = text.length == 0 mainItem.empty = text.length == 0;
if (initialReading) { if (initialReading) {
initialReading = false initialReading = false;
} }
if (mainItem.empty && !mainItem.canBeEmpty) { if (mainItem.empty && !mainItem.canBeEmpty) {
mainItem.validationChecked(false) mainItem.validationChecked(false);
return return;
} }
if (mainItem.propertyName && isValid(text)) { if (mainItem.propertyName && isValid(text)) {
if (mainItem.propertyOwnerGui) { if (mainItem.propertyOwnerGui) {
if (mainItem.propertyOwnerGui.core[mainItem.propertyName] != text) { if (mainItem.propertyOwnerGui.core[mainItem.propertyName] != text) {
mainItem.propertyOwnerGui.core[mainItem.propertyName] = text mainItem.propertyOwnerGui.core[mainItem.propertyName] = text;
} }
} else { } else {
if (mainItem.propertyOwner[mainItem.propertyName] != text) if (mainItem.propertyOwner[mainItem.propertyName] != text)
mainItem.propertyOwner[mainItem.propertyName] = text mainItem.propertyOwner[mainItem.propertyName] = text;
} }
mainItem.validationChecked(true) mainItem.validationChecked(true);
} else } else
mainItem.validationChecked(false) mainItem.validationChecked(false);
} }
// Validation textfield functions // Validation textfield functions
Timer { Timer {
@ -124,7 +123,7 @@ Control.TextField {
interval: mainItem.idleTimeOut interval: mainItem.idleTimeOut
repeat: false repeat: false
onTriggered: { onTriggered: {
mainItem.accepted() mainItem.accepted();
} }
} }
@ -134,7 +133,9 @@ Control.TextField {
anchors.fill: parent anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(79) radius: Utils.getSizeWithScreenRatio(79)
color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor
border.color: mainItem.isError ? mainItem.errorBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus ? mainItem.activeBorderColor : mainItem.backgroundBorderColor border.color: mainItem.isError ? mainItem.errorBorderColor : mainItem.keyboardFocus
? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus ? mainItem.activeBorderColor :
mainItem.backgroundBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
@ -169,24 +170,21 @@ Control.TextField {
} }
onStopped: { onStopped: {
cursor.visible = false cursor.visible = false;
} }
} }
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key == Qt.Key_Control) if (event.key == Qt.Key_Control)
mainItem.controlIsDown = true mainItem.controlIsDown = true;
if (event.key === Qt.Key_Enter if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|| event.key === Qt.Key_Return) { enterPressed();
enterPressed() if (mainItem.controlIsDown) {}
if (mainItem.controlIsDown) {
}
} }
} }
Keys.onReleased: event => { Keys.onReleased: event => {
if (event.jey == Qt.Key_Control) if (event.jey == Qt.Key_Control)
mainItem.controlIsDown = false mainItem.controlIsDown = false;
} }
Button { Button {
@ -210,8 +208,7 @@ Control.TextField {
//: Hide %1 //: Hide %1
qsTr("hide_accessible_name") : qsTr("hide_accessible_name") :
//: Show %1 //: Show %1
qsTr("show_accessible_name") qsTr("show_accessible_name")).arg(mainItem.Accessible.name)
).arg(mainItem.Accessible.name)
} }
Button { Button {
id: customButton id: customButton
@ -229,6 +226,7 @@ Control.TextField {
anchors.rightMargin: Utils.getSizeWithScreenRatio(15) anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
onClicked: mainItem.customCallback() onClicked: mainItem.customCallback()
//: %1 button of %2 //: %1 button of %2
Accessible.name: qsTr("textfield_custom_button_accessible_name").arg(mainItem.customButtonAccessibleName).arg(mainItem.Accessible.name) Accessible.name: qsTr("textfield_custom_button_accessible_name").arg(mainItem.customButtonAccessibleName).arg(
mainItem.Accessible.name)
} }
} }

View file

@ -10,16 +10,16 @@ ComboBox {
onSelectedDateTimeChanged: { onSelectedDateTimeChanged: {
if (minTime != undefined) { if (minTime != undefined) {
if (UtilsCpp.timeOffset(minTime, selectedDateTime) < 0) if (UtilsCpp.timeOffset(minTime, selectedDateTime) < 0)
selectedDateTime = minTime selectedDateTime = minTime;
} }
if (maxTime != undefined) { if (maxTime != undefined) {
if (UtilsCpp.timeOffset(maxTime, selectedDateTime) > 0) if (UtilsCpp.timeOffset(maxTime, selectedDateTime) > 0)
selectedDateTime = maxTime selectedDateTime = maxTime;
} }
} }
readonly property string selectedTimeString: Qt.formatDateTime(selectedDateTime, "hh:mm") readonly property string selectedTimeString: Qt.formatDateTime(selectedDateTime, "hh:mm")
property int selectedHour: input.hour*1 property int selectedHour: input.hour * 1
property int selectedMin: input.min*1 property int selectedMin: input.min * 1
property alias contentText: input property alias contentText: input
property var minTime property var minTime
property var maxTime property var maxTime
@ -31,12 +31,12 @@ ComboBox {
popup.closePolicy: Popup.PressOutsideParent | Popup.CloseOnPressOutside popup.closePolicy: Popup.PressOutsideParent | Popup.CloseOnPressOutside
onCurrentTextChanged: input.text = currentText onCurrentTextChanged: input.text = currentText
popup.onOpened: { popup.onOpened: {
input.forceActiveFocus() input.forceActiveFocus();
} }
contentItem: TextInput { contentItem: TextInput {
id: input id: input
validator: IntValidator{} validator: IntValidator {}
// activeFocusOnPress: false // activeFocusOnPress: false
inputMask: "00:00" inputMask: "00:00"
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
@ -46,10 +46,10 @@ ComboBox {
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
onActiveFocusChanged: { onActiveFocusChanged: {
if (activeFocus) { if (activeFocus) {
selectAll() selectAll();
} else { } else {
listView.currentIndex = -1 listView.currentIndex = -1;
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min) mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
} }
} }
font { font {
@ -57,20 +57,20 @@ ComboBox {
weight: Typography.p2l.weight weight: Typography.p2l.weight
} }
text: mainItem.selectedTimeString text: mainItem.selectedTimeString
Keys.onPressed: (event) => { Keys.onPressed: event => {
if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
focus = false focus = false;
} }
} }
onFocusChanged: if (!focus) { onFocusChanged: if (!focus) {
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min) mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
console.log("set time", hour, min) console.log("set time", hour, min);
} }
} }
listView.delegate: Text { listView.delegate: Text {
id: hourDelegate id: hourDelegate
property int hour: modelData /2 property int hour: modelData / 2
property int min: modelData%2 === 0 ? 0 : 30 property int min: modelData % 2 === 0 ? 0 : 30
property var currentDateTime: UtilsCpp.createDateTime(new Date(), hour, min) property var currentDateTime: UtilsCpp.createDateTime(new Date(), hour, min)
text: Qt.formatDateTime(currentDateTime, "hh:mm") text: Qt.formatDateTime(currentDateTime, "hh:mm")
width: mainItem.width width: mainItem.width
@ -88,9 +88,9 @@ ComboBox {
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: { onClicked: {
// mainItem.text = parent.text // mainItem.text = parent.text
mainItem.listView.currentIndex = index mainItem.listView.currentIndex = index;
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min) mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
mainItem.popup.close() mainItem.popup.close();
} }
Rectangle { Rectangle {
visible: parent.containsMouse visible: parent.containsMouse

View file

@ -17,14 +17,14 @@ Window {
default property alias _content: content.data default property alias _content: content.data
property bool _isOpen: false property bool _isOpen: false
signal isOpened() signal isOpened
signal isClosed() signal isClosed
signal dataChanged() signal dataChanged
on_ContentChanged: dataChanged(_content) on_ContentChanged: dataChanged(_content)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function open () { function open() {
_isOpen = true; _isOpen = true;
isOpened(); isOpened();
} }
@ -37,24 +37,24 @@ Window {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
objectName: '__internalWindow' objectName: '__internalWindow'
property bool showAsTool : false property bool showAsTool: false
// Don't use Popup for flags : it could lead to error in geometry. On Mac, Using Tool ensure to have the Window on Top and fullscreen independant // Don't use Popup for flags : it could lead to error in geometry. On Mac, Using Tool ensure to have the Window on Top and fullscreen independant
// flags: Qt.WindowDoesNotAcceptFocus | Qt.BypassWindowManagerHint | (showAsTool?Qt.Tool:Qt.WindowStaysOnTopHint) | Qt.Window | Qt.FramelessWindowHint; // flags: Qt.WindowDoesNotAcceptFocus | Qt.BypassWindowManagerHint | (showAsTool?Qt.Tool:Qt.WindowStaysOnTopHint) | Qt.Window | Qt.FramelessWindowHint;
flags: Qt.SplashScreen | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint // | Qt.WindowStaysOnTopHint flags: Qt.SplashScreen | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint // | Qt.WindowStaysOnTopHint
opacity: 1.0 opacity: 1.0
height: _content[0] != null ? _content[0].height : 0 height: _content[0] != null ? _content[0].height : 0
width: _content[0] != null ? _content[0].width : 0 width: _content[0] != null ? _content[0].width : 0
visible:true visible: true
Item { Item {
id: content id: content
anchors.fill:parent anchors.fill: parent
focus: false focus: false
property var $parent: mainItem property var $parent: mainItem
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/* /*
states: State { states: State {
name: 'opening' name: 'opening'
when: _isOpen when: _isOpen

View file

@ -7,7 +7,7 @@ import QtQuick.Dialogs
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Dialog { Dialog {
@ -27,15 +27,17 @@ Dialog {
closePolicy: Popup.NoAutoClose closePolicy: Popup.NoAutoClose
onAccepted: { onAccepted: {
if( callback) callback.cb(password) if (callback)
close() callback.cb(password);
close();
} }
onRejected: close() onRejected: close()
Component.onDestruction: if(callback) callback.destroy() Component.onDestruction: if (callback)
callback.destroy()
content: ColumnLayout { content: ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(20)
id: contentLayout id: contentLayout
spacing: Utils.getSizeWithScreenRatio(20)
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(250) Layout.preferredWidth: Utils.getSizeWithScreenRatio(250)
@ -99,13 +101,13 @@ Dialog {
KeyNavigation.up: passwordEdit KeyNavigation.up: passwordEdit
KeyNavigation.right: cancelButton KeyNavigation.right: cancelButton
onClicked: { onClicked: {
passwordItem.errorMessage = "" passwordItem.errorMessage = "";
if (passwordEdit.text.length == 0) { if (passwordEdit.text.length == 0) {
//: Veuillez saisir un mot de passe //: Veuillez saisir un mot de passe
passwordItem.errorMessage = qsTr("assistant_account_login_missing_password") passwordItem.errorMessage = qsTr("assistant_account_login_missing_password");
return return;
} }
mainItem.accepted() mainItem.accepted();
} }
} }
] ]

View file

@ -3,7 +3,7 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Popup { Popup {
@ -22,11 +22,10 @@ Popup {
property string text property string text
property string details property string details
//: "Confirmer" //: "Confirmer"
property string firstButtonText: firstButtonAccept ? qsTr("dialog_confirm") property string firstButtonText: firstButtonAccept ? qsTr("dialog_confirm") :
//: "Annuler" //: "Annuler"
: qsTr("dialog_cancel") qsTr("dialog_cancel")
property string secondButtonText: secondButtonAccept ? qsTr("dialog_confirm") property string secondButtonText: secondButtonAccept ? qsTr("dialog_confirm") : qsTr("dialog_cancel")
: qsTr("dialog_cancel")
property alias content: contentLayout.data property alias content: contentLayout.data
property alias buttons: buttonsLayout.data property alias buttons: buttonsLayout.data
property alias firstButton: firstButtonId property alias firstButton: firstButtonId
@ -34,19 +33,20 @@ Popup {
property bool firstButtonAccept: true property bool firstButtonAccept: true
property bool secondButtonAccept: false property bool secondButtonAccept: false
signal accepted() signal accepted
signal rejected() signal rejected
contentItem: FocusScope { contentItem: FocusScope {
implicitWidth: child.implicitWidth implicitWidth: child.implicitWidth
implicitHeight: child.implicitHeight implicitHeight: child.implicitHeight
onVisibleChanged: { onVisibleChanged: {
if(visible) forceActiveFocus() if (visible)
forceActiveFocus();
} }
Keys.onPressed: (event) => { Keys.onPressed: event => {
if(visible && event.key == Qt.Key_Escape){ if (visible && event.key == Qt.Key_Escape) {
mainItem.close() mainItem.close();
event.accepted = true event.accepted = true;
} }
} }
ColumnLayout { ColumnLayout {
@ -54,7 +54,7 @@ Popup {
anchors.fill: parent anchors.fill: parent
spacing: Utils.getSizeWithScreenRatio(15) spacing: Utils.getSizeWithScreenRatio(15)
Text{ Text {
id: titleText id: titleText
Layout.fillWidth: true Layout.fillWidth: true
visible: text.length != 0 visible: text.length != 0
@ -67,7 +67,7 @@ Popup {
wrapMode: Text.Wrap wrapMode: Text.Wrap
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
} }
Rectangle{ Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 1 Layout.preferredHeight: 1
color: DefaultStyle.main2_400 color: DefaultStyle.main2_400
@ -111,23 +111,23 @@ Popup {
RowLayout { RowLayout {
id: buttonsLayout id: buttonsLayout
Layout.alignment: Qt.AlignBottom | ( titleText.visible ? Qt.AlignRight : Qt.AlignHCenter) Layout.alignment: Qt.AlignBottom | (titleText.visible ? Qt.AlignRight : Qt.AlignHCenter)
spacing: Utils.getSizeWithScreenRatio(titleText.visible ? 20 : 10) spacing: Utils.getSizeWithScreenRatio(titleText.visible ? 20 : 10)
// Default buttons only visible if no other children // Default buttons only visible if no other children
// have been set // have been set
MediumButton { MediumButton {
id:firstButtonId id: firstButtonId
visible: mainItem.buttons.length === 2 visible: mainItem.buttons.length === 2
text: mainItem.firstButtonText text: mainItem.firstButtonText
style: mainItem.firstButtonAccept ? ButtonStyle.main : ButtonStyle.secondary style: mainItem.firstButtonAccept ? ButtonStyle.main : ButtonStyle.secondary
focus: !mainItem.firstButtonAccept focus: !mainItem.firstButtonAccept
onClicked: { onClicked: {
if(mainItem.firstButtonAccept) if (mainItem.firstButtonAccept)
mainItem.accepted() mainItem.accepted();
else else
mainItem.rejected() mainItem.rejected();
mainItem.close() mainItem.close();
} }
KeyNavigation.left: secondButtonId KeyNavigation.left: secondButtonId
KeyNavigation.right: secondButtonId KeyNavigation.right: secondButtonId
@ -139,11 +139,11 @@ Popup {
style: mainItem.firstButtonAccept ? ButtonStyle.secondary : ButtonStyle.main style: mainItem.firstButtonAccept ? ButtonStyle.secondary : ButtonStyle.main
focus: !mainItem.secondButtonAccept focus: !mainItem.secondButtonAccept
onClicked: { onClicked: {
if(mainItem.secondButtonAccept) if (mainItem.secondButtonAccept)
mainItem.accepted() mainItem.accepted();
else else
mainItem.rejected() mainItem.rejected();
mainItem.close() mainItem.close();
} }
KeyNavigation.left: firstButtonId KeyNavigation.left: firstButtonId
KeyNavigation.right: firstButtonId KeyNavigation.right: firstButtonId

View file

@ -4,7 +4,7 @@ import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp 1.0 import UtilsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// ============================================================================= // =============================================================================
@ -19,7 +19,8 @@ Dialog {
closePolicy: Popup.NoAutoClose closePolicy: Popup.NoAutoClose
property var call property var call
onCallChanged: if(!call) close() onCallChanged: if (!call)
close()
property bool isTokenVerified: call && call.core.tokenVerified || false property bool isTokenVerified: call && call.core.tokenVerified || false
property bool isCaseMismatch: call && call.core.isMismatch || false property bool isCaseMismatch: call && call.core.isMismatch || false
property bool securityError: false property bool securityError: false
@ -32,11 +33,9 @@ Dialog {
anchors.fill: parent anchors.fill: parent
width: mainItem.width width: mainItem.width
height: mainItem.implicitHeight height: mainItem.implicitHeight
color: mainItem.securityError color: mainItem.securityError ? DefaultStyle.danger_500_main : mainItem.isCaseMismatch ? DefaultStyle.warning_600 :
? DefaultStyle.danger_500_main DefaultStyle.info_500_main
: mainItem.isCaseMismatch
? DefaultStyle.warning_600
: DefaultStyle.info_500_main
radius: mainItem.radius radius: mainItem.radius
Layout.ColumnLayout { Layout.ColumnLayout {
anchors.top: parent.top anchors.top: parent.top
@ -76,7 +75,9 @@ Dialog {
weight: Typography.p2l.weight weight: Typography.p2l.weight
} }
} }
Item{Layout.Layout.fillHeight: true} Item {
Layout.Layout.fillHeight: true
}
} }
SmallButton { SmallButton {
visible: !mainItem.securityError visible: !mainItem.securityError
@ -92,8 +93,8 @@ Dialog {
pressedTextColor: DefaultStyle.grey_200 pressedTextColor: DefaultStyle.grey_200
underline: true underline: true
onClicked: { onClicked: {
call.core.lSkipZrtpAuthentication() call.core.lSkipZrtpAuthentication();
mainItem.close() mainItem.close();
} }
} }
} }
@ -129,11 +130,11 @@ Dialog {
Layout.Layout.preferredWidth: Utils.getSizeWithScreenRatio(343) Layout.Layout.preferredWidth: Utils.getSizeWithScreenRatio(343)
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: !mainItem.isTokenVerified && mainItem.isCaseMismatch text: !mainItem.isTokenVerified && mainItem.isCaseMismatch ?
//: "Pour garantir le chiffrement, nous avons besoin de réauthentifier lappareil de votre correspondant. Echangez vos codes :" //: "Pour garantir le chiffrement, nous avons besoin de réauthentifier lappareil de votre correspondant. Echangez vos codes :"
? qsTr("call_dialog_zrtp_validate_trust_warning_message") qsTr("call_dialog_zrtp_validate_trust_warning_message") :
//: "Pour garantir le chiffrement, nous avons besoin dauthentifier lappareil de votre correspondant. Veuillez échanger vos codes : " //: "Pour garantir le chiffrement, nous avons besoin dauthentifier lappareil de votre correspondant. Veuillez échanger vos codes : "
: qsTr("call_dialog_zrtp_validate_trust_message") qsTr("call_dialog_zrtp_validate_trust_message")
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
font.pixelSize: Utils.getSizeWithScreenRatio(14) font.pixelSize: Utils.getSizeWithScreenRatio(14)
} }
@ -199,8 +200,9 @@ Dialog {
radius: Utils.getSizeWithScreenRatio(71) radius: Utils.getSizeWithScreenRatio(71)
textColor: DefaultStyle.main2_600 textColor: DefaultStyle.main2_600
onClicked: { onClicked: {
console.log("CHECK TOKEN", modelData) console.log("CHECK TOKEN", modelData);
if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(modelData) if (mainItem.call)
mainItem.call.core.lCheckAuthenticationTokenSelected(modelData);
} }
} }
} }
@ -249,7 +251,8 @@ Dialog {
textColor: DefaultStyle.danger_500_main textColor: DefaultStyle.danger_500_main
visible: !mainItem.securityError visible: !mainItem.securityError
onClicked: { onClicked: {
if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(" ") if (mainItem.call)
mainItem.call.core.lCheckAuthenticationTokenSelected(" ");
} }
} }
MediumButton { MediumButton {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic import QtQuick.Controls.Basic
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Popup { Popup {
@ -14,10 +14,10 @@ Popup {
signal closePopup(int index) signal closePopup(int index)
onClosed: closePopup(index) onClosed: closePopup(index)
onAboutToShow: { onAboutToShow: {
autoClosePopup.restart() autoClosePopup.restart();
} }
closePolicy: Popup.NoAutoClose closePolicy: Popup.NoAutoClose
x : parent.x + parent.width - width x: parent.x + parent.width - width
// y : parent.y + parent.height - height // y : parent.y + parent.height - height
rightMargin: Utils.getSizeWithScreenRatio(20) rightMargin: Utils.getSizeWithScreenRatio(20)
bottomMargin: Utils.getSizeWithScreenRatio(20) bottomMargin: Utils.getSizeWithScreenRatio(20)
@ -27,14 +27,16 @@ Popup {
focus: true focus: true
onHoveredChanged: { onHoveredChanged: {
if (hovered) autoClosePopup.stop() if (hovered)
else autoClosePopup.restart() autoClosePopup.stop();
else
autoClosePopup.restart();
} }
Timer { Timer {
id: autoClosePopup id: autoClosePopup
interval: 5000 interval: 5000
onTriggered: { onTriggered: {
mainItem.close() mainItem.close();
} }
} }
contentItem: RowLayout { contentItem: RowLayout {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic import QtQuick.Controls.Basic
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Popup { Popup {
@ -21,7 +21,7 @@ Popup {
spacing: Utils.getSizeWithScreenRatio(15) spacing: Utils.getSizeWithScreenRatio(15)
// width: childrenRect.width // width: childrenRect.width
// height: childrenRect.height // height: childrenRect.height
BusyIndicator{ BusyIndicator {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
width: Utils.getSizeWithScreenRatio(33) width: Utils.getSizeWithScreenRatio(33)
height: width height: width
@ -42,8 +42,9 @@ Popup {
text: qsTr("cancel") text: qsTr("cancel")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
if (callback) mainItem.callback() if (callback)
mainItem.close() mainItem.callback();
mainItem.close();
} }
} }
} }

View file

@ -8,9 +8,8 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
DesktopPopup { DesktopPopup {
id: mainItem id: mainItem
property var notificationData: ({ property var notificationData: ({
timelineModel : null timelineModel: null
}) })
property real overriddenHeight: Utils.getSizeWithScreenRatio(120) property real overriddenHeight: Utils.getSizeWithScreenRatio(120)
property real overriddenWidth: Utils.getSizeWithScreenRatio(300) property real overriddenWidth: Utils.getSizeWithScreenRatio(300)
@ -18,18 +17,18 @@ DesktopPopup {
property color backgroundColor: DefaultStyle.grey_0 property color backgroundColor: DefaultStyle.grey_0
property double backgroundOpacity: 1 property double backgroundOpacity: 1
signal deleteNotification (var notification) signal deleteNotification(var notification)
width: mainItem.overriddenWidth width: mainItem.overriddenWidth
height: mainItem.overriddenHeight height: mainItem.overriddenHeight
// Use as an intermediate between signal/slot without propagate the notification var : last signal parameter will be the last notification instance // Use as an intermediate between signal/slot without propagate the notification var : last signal parameter will be the last notification instance
function deleteNotificationSlot(){ function deleteNotificationSlot() {
deleteNotification(mainItem) deleteNotification(mainItem);
} }
function _close (cb) { function _close(cb) {
if (cb) { if (cb) {
cb() cb();
} }
deleteNotificationSlot(); deleteNotificationSlot();
} }
@ -41,10 +40,10 @@ DesktopPopup {
opacity: mainItem.backgroundOpacity opacity: mainItem.backgroundOpacity
} }
Loader{ Loader {
id: backgroundLoader id: backgroundLoader
asynchronous: true asynchronous: true
sourceComponent: Item{ sourceComponent: Item {
width: mainItem.overriddenWidth width: mainItem.overriddenWidth
height: mainItem.overriddenHeight height: mainItem.overriddenHeight
Rectangle { Rectangle {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// ============================================================================= // =============================================================================
@ -21,13 +21,13 @@ Notification {
property var status: call.core.status property var status: call.core.status
property var conference: call.core.conference property var conference: call.core.conference
onStateChanged:{ onStateChanged: {
if (state != LinphoneEnums.CallState.IncomingReceived){ if (state != LinphoneEnums.CallState.IncomingReceived) {
close() close();
} }
} }
onStatusChanged:{ onStatusChanged: {
console.log("status", status) console.log("status", status);
} }
Popup { Popup {
@ -38,7 +38,7 @@ Notification {
topPadding: Utils.getSizeWithScreenRatio(9) topPadding: Utils.getSizeWithScreenRatio(9)
bottomPadding: Utils.getSizeWithScreenRatio(18) bottomPadding: Utils.getSizeWithScreenRatio(18)
anchors.centerIn: parent anchors.centerIn: parent
background: Item{} background: Item {}
contentItem: ColumnLayout { contentItem: ColumnLayout {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Utils.getSizeWithScreenRatio(9) spacing: Utils.getSizeWithScreenRatio(9)
@ -119,9 +119,9 @@ Notification {
textSize: Utils.getSizeWithScreenRatio(14) textSize: Utils.getSizeWithScreenRatio(14)
textWeight: Utils.getSizeWithScreenRatio(500) textWeight: Utils.getSizeWithScreenRatio(500)
onClicked: { onClicked: {
console.debug("[NotificationReceivedCall] Accept click") console.debug("[NotificationReceivedCall] Accept click");
UtilsCpp.openCallsWindow(mainItem.call) UtilsCpp.openCallsWindow(mainItem.call);
mainItem.call.core.lAccept(false) mainItem.call.core.lAccept(false);
} }
} }
Button { Button {
@ -137,13 +137,12 @@ Notification {
textSize: Utils.getSizeWithScreenRatio(14) textSize: Utils.getSizeWithScreenRatio(14)
textWeight: Utils.getSizeWithScreenRatio(500) textWeight: Utils.getSizeWithScreenRatio(500)
onClicked: { onClicked: {
console.debug("[NotificationReceivedCall] Decline click") console.debug("[NotificationReceivedCall] Decline click");
mainItem.call.core.lDecline() mainItem.call.core.lDecline();
} }
} }
} }
} }
} }
} }
} }

View file

@ -3,7 +3,7 @@ import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import QtQuick.Controls as Control import QtQuick.Controls as Control
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// ============================================================================= // =============================================================================
@ -28,7 +28,7 @@ Notification {
enabled: chat enabled: chat
target: chat ? chat.core : null target: chat ? chat.core : null
function onMessageOpen() { function onMessageOpen() {
close() close();
} }
} }
@ -69,7 +69,9 @@ Notification {
anchors.rightMargin: Utils.getSizeWithScreenRatio(12) anchors.rightMargin: Utils.getSizeWithScreenRatio(12)
padding: 0 padding: 0
z: mousearea.z + 1 z: mousearea.z + 1
background: Item{anchors.fill: parent} background: Item {
anchors.fill: parent
}
icon.source: AppIcons.closeX icon.source: AppIcons.closeX
width: Utils.getSizeWithScreenRatio(14) width: Utils.getSizeWithScreenRatio(14)
height: Utils.getSizeWithScreenRatio(14) height: Utils.getSizeWithScreenRatio(14)
@ -77,15 +79,15 @@ Notification {
icon.height: Utils.getSizeWithScreenRatio(14) icon.height: Utils.getSizeWithScreenRatio(14)
contentImageColor: DefaultStyle.grey_0 contentImageColor: DefaultStyle.grey_0
onPressed: { onPressed: {
mainItem.close() mainItem.close();
} }
} }
MouseArea { MouseArea {
id: mousearea id: mousearea
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
UtilsCpp.openChat(mainItem.chat) UtilsCpp.openChat(mainItem.chat);
mainItem.close() mainItem.close();
} }
} }
} }
@ -139,5 +141,4 @@ Notification {
} }
} }
} }
} }

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts as Layout
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Popup { Control.Popup {
@ -21,11 +21,11 @@ Control.Popup {
onOpened: numPad.forceActiveFocus() onOpened: numPad.forceActiveFocus()
signal buttonPressed(string text) signal buttonPressed(string text)
signal keyPadKeyPressed(KeyEvent event) signal keyPadKeyPressed(KeyEvent event)
onKeyPadKeyPressed: (event) => { onKeyPadKeyPressed: event => {
numPad.handleKeyPadEvent(event) numPad.handleKeyPadEvent(event);
} }
signal launchCall() signal launchCall
signal wipe() signal wipe
background: Item { background: Item {
anchors.fill: parent anchors.fill: parent
@ -73,12 +73,12 @@ Control.Popup {
Accessible.name: qsTr("close_numeric_pad_accessible_name") Accessible.name: qsTr("close_numeric_pad_accessible_name")
} }
} }
contentItem: NumericPad{ contentItem: NumericPad {
id: numPad id: numPad
lastRowVisible: mainItem.lastRowVisible lastRowVisible: mainItem.lastRowVisible
currentCall: mainItem.currentCall currentCall: mainItem.currentCall
onButtonPressed: (text) => { onButtonPressed: text => {
mainItem.buttonPressed(text) mainItem.buttonPressed(text);
} }
onLaunchCall: mainItem.launchCall() onLaunchCall: mainItem.launchCall()
onWipe: mainItem.wipe() onWipe: mainItem.wipe()

View file

@ -5,23 +5,23 @@ import Linphone
import CustomControls 1.0 import CustomControls 1.0
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Popup{ Control.Popup {
id: mainItem id: mainItem
padding: 0 padding: 0
property color underlineColor : DefaultStyle.main1_500_main property color underlineColor: DefaultStyle.main1_500_main
property real radius: Utils.getSizeWithScreenRatio(16) property real radius: Utils.getSizeWithScreenRatio(16)
property bool hovered: mouseArea.containsMouse property bool hovered: mouseArea.containsMouse
property bool keyboardFocus: FocusHelper.keyboardFocus property bool keyboardFocus: FocusHelper.keyboardFocus
background: Item{ background: Item {
Rectangle { Rectangle {
visible: mainItem.underlineColor != undefined visible: mainItem.underlineColor != undefined
width: mainItem.width width: mainItem.width
height: mainItem.height +Utils.getSizeWithScreenRatio(2) height: mainItem.height + Utils.getSizeWithScreenRatio(2)
color: mainItem.underlineColor color: mainItem.underlineColor
radius: mainItem.radius radius: mainItem.radius
} }
Rectangle{ Rectangle {
id: backgroundItem id: backgroundItem
width: mainItem.width width: mainItem.width
height: mainItem.height height: mainItem.height

File diff suppressed because it is too large Load diff

View file

@ -1,28 +1,29 @@
import QtQuick import QtQuick
MouseArea{ MouseArea {
id: mainItem id: mainItem
property var movableArea: mainItem.Window.contentItem property var movableArea: mainItem.Window.contentItem
signal requestResetPosition() signal requestResetPosition
property bool dragging: drag.active property bool dragging: drag.active
onDraggingChanged: { onDraggingChanged: {
if(dragging){ if (dragging) {
xClicked = mouseX xClicked = mouseX;
yClicked = mouseY yClicked = mouseY;
} }
} }
property real margin: 0 property real margin: 0
// Position buffer // Position buffer
property int xClicked : 0 property int xClicked: 0
property int yClicked : 0 property int yClicked: 0
// Scaling buffer // Scaling buffer
property int heightOrigin property int heightOrigin
property int widthOrigin property int widthOrigin
property double startTime: 0 // For acceleration computation to avoid excessive wheel scrolling property double startTime: 0 // For acceleration computation to avoid excessive wheel scrolling
property double mScale: 1.0 // Using scale reduce quality. Apply our factor. property double mScale: 1.0 // Using scale reduce quality. Apply our factor.
property bool scaled : false // Zoom state : -for storing origin state ; -for resetting scale on right click. In this case, second click lead to emit reset signal instead of first.. property bool scaled:
false // Zoom state : -for storing origin state ; -for resetting scale on right click. In this case, second click lead to emit reset signal instead of first..
acceptedButtons: Qt.LeftButton | Qt.RightButton // Left is for Dragging. Right is for resetting. Wheel will scale. acceptedButtons: Qt.LeftButton | Qt.RightButton // Left is for Dragging. Right is for resetting. Wheel will scale.
cursorShape: dragging ? Qt.DragMoveCursor : undefined cursorShape: dragging ? Qt.DragMoveCursor : undefined
@ -30,51 +31,53 @@ MouseArea{
propagateComposedEvents: true propagateComposedEvents: true
hoverEnabled: true hoverEnabled: true
function updateScale(){// Avoid scaling if leading outside movableArea. function updateScale() {// Avoid scaling if leading outside movableArea.
drag.target.height = Math.max(0, Math.min(movableArea.height, heightOrigin * mScale)) drag.target.height = Math.max(0, Math.min(movableArea.height, heightOrigin * mScale));
drag.target.width = Math.max(0, Math.min(movableArea.width, widthOrigin * mScale)) drag.target.width = Math.max(0, Math.min(movableArea.width, widthOrigin * mScale));
updatePosition(0,0) updatePosition(0, 0);
} }
function updatePosition(x, y){// Avoid moving outside movableArea. function updatePosition(x, y) {// Avoid moving outside movableArea.
var parentTLBounds = drag.target.parent.mapFromItem(movableArea, 0, 0); var parentTLBounds = drag.target.parent.mapFromItem(movableArea, 0, 0);
var parentBRBounds = drag.target.parent.mapFromItem(movableArea, movableArea.width, movableArea.height); var parentBRBounds = drag.target.parent.mapFromItem(movableArea, movableArea.width, movableArea.height);
drag.target.x = Math.max(parentTLBounds.x + margin, Math.min(parentBRBounds.x - drag.target.width - margin, drag.target.x + x - margin)) drag.target.x = Math.max(parentTLBounds.x + margin, Math.min(parentBRBounds.x - drag.target.width - margin,
drag.target.y = Math.max(parentTLBounds.y + margin, Math.min(parentBRBounds.y - drag.target.height - margin, drag.target.y + y - margin)) drag.target.x + x - margin));
drag.target.y = Math.max(parentTLBounds.y + margin, Math.min(parentBRBounds.y - drag.target.height - margin,
drag.target.y + y - margin));
} }
onMScaleChanged: updateScale() onMScaleChanged: updateScale()
onPositionChanged: (mouse) => { onPositionChanged: mouse => {
if(dragging){ if (dragging) {
updatePosition(mouse.x - xClicked, mouse.y - yClicked) updatePosition(mouse.x - xClicked, mouse.y - yClicked);
} }
mouse.accepted = false mouse.accepted = false;
} }
onWheel: (wheel) => { onWheel: wheel => {
if(!scaled){ if (!scaled) {
scaled = true scaled = true;
heightOrigin = drag.target.height heightOrigin = drag.target.height;
widthOrigin = drag.target.width widthOrigin = drag.target.width;
} }
var acceleration = 0.01; // Try to make smoother the scaling from wheel var acceleration = 0.01; // Try to make smoother the scaling from wheel
if(startTime == 0){ if (startTime == 0) {
startTime = new Date().getTime(); startTime = new Date().getTime();
}else{ } else {
var delay = new Date().getTime() - startTime; var delay = new Date().getTime() - startTime;
if(delay > 0) if (delay > 0)
acceleration = Math.max(0.01, Math.min(1, 4/delay)); acceleration = Math.max(0.01, Math.min(1, 4 / delay));
else else
acceleration = 1 acceleration = 1;
} }
mScale = Math.max(0.5 , mScale * ( 1 + acceleration*(wheel.angleDelta.y >0 ? 1 : -1) )); mScale = Math.max(0.5, mScale * (1 + acceleration * (wheel.angleDelta.y > 0 ? 1 : -1)));
startTime = new Date().getTime(); startTime = new Date().getTime();
} }
onClicked: (mouse) => { onClicked: mouse => {
if(mouse.button == Qt.RightButton){ if (mouse.button == Qt.RightButton) {
if(scaled) { if (scaled) {
scaled = false scaled = false;
mScale = 1.0 mScale = 1.0;
}else } else
requestResetPosition() requestResetPosition();
} }
mouse.accepted = false mouse.accepted = false;
} }
} }

View file

@ -6,7 +6,7 @@ import UtilsCpp 1.0
// Snippet // Snippet
ListView{ ListView {
id: mainItem id: mainItem
model: AccountProxy {} model: AccountProxy {}
function printObject(o) { function printObject(o) {
@ -14,56 +14,53 @@ ListView{
for (var p in o) { for (var p in o) {
out += p + ': ' + o[p] + '\n'; out += p + ': ' + o[p] + '\n';
} }
if(!o) if (!o)
return 'Empty' return 'Empty';
else else
return out; return out;
} }
delegate: Rectangle{ delegate: Rectangle {
height: 50 height: 50
width: mainItem.width width: mainItem.width
RowLayout{ RowLayout {
anchors.fill: parent anchors.fill: parent
Rectangle{ Rectangle {
Layout.preferredHeight: 50 Layout.preferredHeight: 50
Layout.preferredWidth: 50 Layout.preferredWidth: 50
//color: '#111111' //color: '#111111'
Image{ Image {
id: avatar id: avatar
anchors.fill: parent anchors.fill: parent
source: $modelData.pictureUri source: $modelData.pictureUri
} }
} }
Text{ Text {
// Store the VariantObject and use value on this object. Do not use value in one line because of looping signals. // Store the VariantObject and use value on this object. Do not use value in one line because of looping signals.
property var displayName: UtilsCpp.getDisplayName($modelData.identityAddress) property var displayName: UtilsCpp.getDisplayName($modelData.identityAddress)
text: displayName ? displayName.value : "" text: displayName ? displayName.value : ""
onTextChanged: console.log("[ProtoAccounts] Async account displayName: " +$modelData.identityAddress + " => " +text) onTextChanged: console.log("[ProtoAccounts] Async account displayName: " + $modelData.identityAddress + " => "
+ text)
} }
Text{ Text {
text: $modelData.registrationState == LinphoneEnums.RegistrationState.Ok text: $modelData.registrationState == LinphoneEnums.RegistrationState.Ok ? 'Online' : $modelData.registrationState
? 'Online' == LinphoneEnums.RegistrationState.Failed ? 'Error' : $modelData.registrationState
: $modelData.registrationState == LinphoneEnums.RegistrationState.Failed == LinphoneEnums.RegistrationState.Progress || $modelData.registrationState
? 'Error' == LinphoneEnums.RegistrationState.Refreshing ? 'Connecting' : 'Offline'
: $modelData.registrationState == LinphoneEnums.RegistrationState.Progress || $modelData.registrationState == LinphoneEnums.RegistrationState.Refreshing
? 'Connecting'
: 'Offline'
} }
} }
MouseArea{ MouseArea {
anchors.fill: parent anchors.fill: parent
property int clickCount : 0 property int clickCount: 0
onClicked: { onClicked: {
if(++clickCount % 2 == 0) if (++clickCount % 2 == 0)
$modelData.pictureUri = AppIcons.loginImage; $modelData.pictureUri = AppIcons.loginImage;
else else
$modelData.pictureUri = AppIcons.eyeShow; $modelData.pictureUri = AppIcons.eyeShow;
console.log(printObject($modelData)) console.log(printObject($modelData));
console.debug("[ProtoAccounts] Account Select: " +$modelData.contactAddress +" / "+$modelData.identityAddress + " / " +$modelData.pictureUri + " / " +$modelData.registrationState) console.debug("[ProtoAccounts] Account Select: " + $modelData.contactAddress + " / " + $modelData.identityAddress
+ " / " + $modelData.pictureUri + " / " + $modelData.registrationState);
} }
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show more