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

View file

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

View file

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

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts
import QtQuick.Effects
import QtQuick.Controls.Basic as Control
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 {
id: mainItem
@ -14,11 +14,7 @@ Button {
color: style?.color?.normal || 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
property color backgroundColor: hovered
? hoveredColor
: checked
? pressedColor
: color
property color backgroundColor: hovered ? hoveredColor : checked ? pressedColor : color
checkable: true
Accessible.role: Accessible.Button
icon.source: checkedIconUrl && mainItem.checked ? checkedIconUrl : iconUrl

View file

@ -53,7 +53,8 @@ Control.ComboBox {
}
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();
event.accepted = true;
}
@ -65,7 +66,9 @@ Control.ComboBox {
anchors.fill: parent
radius: Math.round(mainItem.height / 2)
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
}
MultiEffect {
@ -185,7 +188,9 @@ Control.ComboBox {
height: mainItem.height
// anchors.left: listView.left
// 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 {
anchors.fill: parent
EffectImage {
@ -209,14 +214,17 @@ Control.ComboBox {
pixelSize: mainItem.pixelSize
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 {
Layout.fillWidth: true
Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(flagItem.visble ? 5 : 25)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
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
maximumLineCount: 1
wrapMode: Text.WrapAnywhere

View file

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

View file

@ -3,7 +3,7 @@ import QtQuick.Effects
import QtQuick.Layouts
import Linphone
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 {
id: mainItem
@ -19,16 +19,16 @@ MouseArea {
height: content.implicitHeight
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
activeFocusOnTab: true
Keys.onPressed: (event) => {
if(event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return){
mainItem.clicked(undefined)
event.accepted = true
Keys.onPressed: event => {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
mainItem.clicked(undefined);
event.accepted = true;
}
}
RowLayout {
id: content
anchors.verticalCenter: parent.verticalCenter
anchors.fill:parent
anchors.fill: parent
EffectImage {
id: image
Layout.preferredWidth: mainItem.iconSize
@ -63,7 +63,9 @@ MouseArea {
font: Typography.p1
}
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
EffectImage {
id: arrowImage
visible: mainItem.arrowImageVisible

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
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
Button {
@ -18,11 +18,8 @@ Button {
background: Rectangle {
anchors.fill: parent
radius: mainItem.radius
color: mainItem.pressed
? mainItem.pressedColor
: mainItem.hovered || mainItem.hasNavigationFocus
? mainItem.hoveredColor
: mainItem.color
color: mainItem.pressed ? mainItem.pressedColor : mainItem.hovered || mainItem.hasNavigationFocus ? mainItem.hoveredColor :
mainItem.color
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
@ -31,11 +28,8 @@ Button {
imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed
? mainItem.pressedImageColor
: mainItem.hovered
? mainItem.hoveredImageColor
: mainItem.contentImageColor
colorizationColor: mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor :
mainItem.contentImageColor
Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height
}

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
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
Button {
@ -19,16 +19,13 @@ Button {
contentItem: RowLayout {
spacing: mainItem.spacing
layoutDirection: mainItem.inverseLayout ? Qt.RightToLeft: Qt.LeftToRight
layoutDirection: mainItem.inverseLayout ? Qt.RightToLeft : Qt.LeftToRight
EffectImage {
imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed
? mainItem.pressedImageColor
: mainItem.hovered
? mainItem.hoveredImageColor
: mainItem.contentImageColor
colorizationColor: mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor :
mainItem.contentImageColor
Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height
}
@ -41,18 +38,15 @@ Button {
wrapMode: Text.WrapAnywhere
text: mainItem.text
maximumLineCount: 1
color: pressed
? mainItem.pressedTextColor
: mainItem.hovered
? mainItem.hoveredTextColor
: mainItem.textColor
color: pressed ? mainItem.pressedTextColor : mainItem.hovered ? mainItem.hoveredTextColor : mainItem.textColor
font {
pixelSize: mainItem.textSize
weight: mainItem.textWeight
family: DefaultStyle.defaultFont
capitalization: mainItem.capitalization
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 {
@ -67,6 +61,8 @@ Button {
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.Layouts
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
ColumnLayout {

View file

@ -47,15 +47,18 @@ Button {
}
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) {
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) {
if (!content.visible) return null
if (!content.visible)
return null;
if (content.visibleChildren.length == 0 || !hasFocusableChild(content))
return null;
--index;

View file

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

View file

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

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls.Basic
import QtQuick.Layouts
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 {
id: mainItem
@ -14,16 +14,16 @@ ComboBox {
property alias entries: mainItem.model
oneLine: true
currentIndex: Utils.findIndex(model, function (entry) {
if(propertyOwnerGui)
return Utils.equalObject(entry,propertyOwnerGui.core[propertyName])
if (propertyOwnerGui)
return Utils.equalObject(entry, propertyOwnerGui.core[propertyName]);
else
return Utils.equalObject(entry,propertyOwner[propertyName])
return Utils.equalObject(entry, propertyOwner[propertyName]);
})
onCurrentValueChanged: {
if(propertyOwnerGui) {
binding.when = !Utils.equalObject(currentValue,propertyOwnerGui.core[propertyName])
}else{
binding.when = !Utils.equalObject(currentValue,propertyOwner[propertyName])
if (propertyOwnerGui) {
binding.when = !Utils.equalObject(currentValue, propertyOwnerGui.core[propertyName]);
} else {
binding.when = !Utils.equalObject(currentValue, propertyOwner[propertyName]);
}
}
Binding {

View file

@ -2,10 +2,10 @@ import QtQuick
import QtQuick.Controls.Basic
import QtQuick.Layouts
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 {
id:mainItem
id: mainItem
property string titleText
property string subTitleText
property string propertyName
@ -13,9 +13,9 @@ RowLayout {
property var propertyOwnerGui
property bool enabled: true
property alias checked: switchButton.checked
spacing : Utils.getSizeWithScreenRatio(20)
spacing: Utils.getSizeWithScreenRatio(20)
signal toggled()
signal toggled
ColumnLayout {
Layout.minimumHeight: Utils.getSizeWithScreenRatio(32)
@ -39,12 +39,12 @@ RowLayout {
Switch {
id: switchButton
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
checked: propertyOwnerGui ? propertyOwnerGui.core[mainItem.propertyName]
: propertyOwner ? propertyOwner[mainItem.propertyName] : false
checked: propertyOwnerGui ? propertyOwnerGui.core[mainItem.propertyName] : propertyOwner
? propertyOwner[mainItem.propertyName] : false
enabled: mainItem.enabled
onToggled: {
binding.when = true
mainItem.toggled()
binding.when = true;
mainItem.toggled();
}
implicitHeight: Utils.getSizeWithScreenRatio(30)
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 real borderWidth: 0
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
background: Item{
background: Item {
x: mainItem.leftPadding
y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2
implicitWidth: Utils.getSizeWithScreenRatio(200)
@ -35,8 +35,14 @@ Control.Slider {
height: parent.height
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.main1_300 }
GradientStop { position: 1.0; color: DefaultStyle.main1_500_main }
GradientStop {
position: 0.0
color: DefaultStyle.main1_300
}
GradientStop {
position: 1.0
color: DefaultStyle.main1_500_main
}
}
radius: Math.round(height / 2)
}

View file

@ -16,24 +16,21 @@ Item {
property alias call: allDevices.currentCall
property ConferenceGui conference: call && call.core.conference || null
property var callState: call && call.core.state || undefined
property string localAddress: call
? call.conference
? call.conference.core.me.core.sipAddress
: call.core.localAddress
: ""
property string localAddress: call ? call.conference ? call.conference.core.me.core.sipAddress :
call.core.localAddress : ""
property bool sideStickersVisible: sideStickers.visible
// currently speaking address (for hiding in list view)
property string activeSpeakerAddress
property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy {
property ParticipantDeviceProxy participantDevices: ParticipantDeviceProxy {
id: allDevices
qmlName: "AS"
onCountChanged: console.log("Device count changed : " +count)
Component.onCompleted: console.log("Loaded : " +allDevices)
onCountChanged: console.log("Device count changed : " + count)
Component.onCompleted: console.log("Loaded : " + allDevices)
}
RowLayout{
RowLayout {
anchors.fill: parent
anchors.rightMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(16)
@ -46,7 +43,8 @@ Item {
displayAll: !mainItem.conference
participantDevice: mainItem.conference && mainItem.conference.core.activeSpeakerDevice
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'
securityBreach: !mainItem.conference && mainItem.call?.core.isMismatch || false
displayPresence: false
@ -57,7 +55,7 @@ Item {
when: true
}
}
ListView{
ListView {
id: sideStickers
Layout.fillHeight: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(300)
@ -68,24 +66,26 @@ Item {
model: allDevices
snapMode: ListView.SnapOneItem
clip: true
delegate: Item{ // Spacing workaround
visible: $modelData && mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
&& ($modelData.core.address != activeSpeakerAddress || mainItem.conference?.core.isScreenSharingEnabled) || false
delegate: Item {
// Spacing workaround
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
width: Utils.getSizeWithScreenRatio(300)
Sticker {
previewEnabled: index == 0 // before anchors for priority initialization
anchors.fill: parent
anchors.bottomMargin: Utils.getSizeWithScreenRatio(15)// Spacing
qmlName: 'S_'+index
qmlName: 'S_' + index
visible: parent.visible
videoEnabled: (index === 0 && mainItem.call.core.cameraEnabled)
|| (!previewEnabled && call && call.core.remoteVideoEnabled)
|| (!previewEnabled && participantDevice && participantDevice.core.videoEnabled)
videoEnabled: (index === 0 && mainItem.call.core.cameraEnabled) || (!previewEnabled && call
&& call.core.remoteVideoEnabled) || (!previewEnabled && participantDevice
&& participantDevice.core.videoEnabled)
participantDevice: $modelData
displayAll: 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
// 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()
delegateModel: DelegateModel{
delegateModel: DelegateModel {
id: gridModel
property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy {
property ParticipantDeviceProxy participantDevices: ParticipantDeviceProxy {
id: allDevices
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]
delegate: Item{
model: grid.call && grid.call.core.isConference ? participantDevices : [0, 1]
delegate: Item {
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: {
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)
@ -40,14 +44,15 @@ Mosaic {
previewEnabled: index == 0
visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
anchors.fill: parent
qmlName: 'G_'+index
qmlName: 'G_' + index
call: grid.call && !grid.call.core.isConference ? grid.call : null
property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress)
account: (index == 0 && accountObj) ? accountObj.value : null
displayAll: false
displayPresence: false
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 UtilsCpp
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
ColumnLayout {
@ -20,12 +20,9 @@ ColumnLayout {
property bool isConference: conferenceInfo != undefined && conferenceInfo != null
property string contactAddress: specificAddress != "" ? specificAddress : contact && contact.core.defaultAddress || ""
property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress)
property string computedContactName: computedContactNameObj ? computedContactNameObj.value: ""
property string contactName: contact
? contact.core.fullName
: callHistoryGui
? callHistoryGui.core.displayName
: computedContactName
property string computedContactName: computedContactNameObj ? computedContactNameObj.value : ""
property string contactName: contact ? contact.core.fullName : callHistoryGui ? callHistoryGui.core.displayName :
computedContactName
// Set this property to get the security informations
// for a specific address and not for the entire contact
@ -34,8 +31,8 @@ ColumnLayout {
property alias buttonContent: rightButton.data
property alias detailContent: detailControl.data
signal conferenceChatDisplayRequested()
signal conferenceCallHistoryDisplayRequested()
signal conferenceChatDisplayRequested
signal conferenceCallHistoryDisplayRequested
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(13)
@ -119,9 +116,9 @@ ColumnLayout {
style: ButtonStyle.grey
onClicked: {
if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow()
callsWindow.setupConference(mainItem.conferenceInfo)
UtilsCpp.smartShowWindow(callsWindow)
var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow);
}
}
}
@ -142,9 +139,9 @@ ColumnLayout {
//: "Join"
label: qsTr("meeting_info_join_title")
button.onClicked: if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow()
callsWindow.setupConference(mainItem.conferenceInfo)
UtilsCpp.smartShowWindow(callsWindow)
var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow);
}
}
LabelButton {
@ -155,14 +152,16 @@ ColumnLayout {
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: button.checked ? AppIcons.callList : AppIcons.chatTeardropText
label: button.checked
label: button.checked ?
//: "Call history"
? qsTr("contact_call_history_action")
qsTr("contact_call_history_action") :
//: "Conversation"
: qsTr("contact_conversation_action")
qsTr("contact_conversation_action")
button.onCheckedChanged: {
if (button.checked) mainItem.conferenceChatDisplayRequested()
else mainItem.conferenceCallHistoryDisplayRequested()
if (button.checked)
mainItem.conferenceChatDisplayRequested();
else
mainItem.conferenceCallHistoryDisplayRequested();
}
}
}
@ -181,8 +180,10 @@ ColumnLayout {
//: "Appel"
label: qsTr("contact_call_action")
button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, false, mainItem)
else UtilsCpp.createCall(mainItem.specificAddress)
if (mainItem.specificAddress === "")
mainWindow.startCallWithContact(mainItem.contact, false, mainItem);
else
UtilsCpp.createCall(mainItem.specificAddress);
}
}
LabelButton {
@ -195,13 +196,12 @@ ColumnLayout {
//: "Message"
label: qsTr("contact_message_action")
button.onClicked: {
console.debug("[CallHistoryLayout.qml] Open conversation")
console.debug("[CallHistoryLayout.qml] Open conversation");
if (mainItem.specificAddress === "") {
mainWindow.sendMessageToContact(mainItem.contact)
}
else {
console.log("specific address", mainItem.specificAddress)
mainWindow.displayChatPage(mainItem.specificAddress)
mainWindow.sendMessageToContact(mainItem.contact);
} else {
console.log("specific address", mainItem.specificAddress);
mainWindow.displayChatPage(mainItem.specificAddress);
}
}
}
@ -215,8 +215,12 @@ ColumnLayout {
//: "Appel Video"
label: qsTr("contact_video_call_action")
button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, true, mainItem)
else UtilsCpp.createCall(mainItem.specificAddress, {'localVideoEnabled': true})
if (mainItem.specificAddress === "")
mainWindow.startCallWithContact(mainItem.contact, true, mainItem);
else
UtilsCpp.createCall(mainItem.specificAddress, {
'localVideoEnabled': true
});
}
}
}

View file

@ -16,53 +16,49 @@ Item {
property CallGui call
property ConferenceGui conference: call && call.core.conference
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
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 participantDeviceCount: conference ? conference.core.participantDeviceCount : -1
property int lastConfLayoutBeforeSharing: -1
property string localAddress: call
? call.conference
? call.conference.core.me.core.sipAddress
: call.core.localAddress
: ""
property string localAddress: call ? call.conference ? call.conference.core.me.core.sipAddress :
call.core.localAddress : ""
onParticipantDeviceCountChanged: {
setConferenceLayout()
setConferenceLayout();
}
Component.onCompleted: setConferenceLayout()
onConferenceLayoutChanged: {
console.log("CallLayout change : " +conferenceLayout)
setConferenceLayout()
console.log("CallLayout change : " + conferenceLayout);
setConferenceLayout();
}
Connections {
target: mainItem.conference? mainItem.conference.core : null
target: mainItem.conference ? mainItem.conference.core : null
function onIsScreenSharingEnabledChanged() {
setConferenceLayout()
setConferenceLayout();
}
function onIsLocalScreenSharingChanged() {
if (mainItem.conference.core.isLocalScreenSharing) {
mainItem.lastConfLayoutBeforeSharing = mainItem.conferenceLayout
mainItem.lastConfLayoutBeforeSharing = mainItem.conferenceLayout;
}
setConferenceLayout()
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 (mainItem.conference && !mainItem.conference.core.isLocalScreenSharing && mainItem.lastConfLayoutBeforeSharing !== -1) {
mainItem.conferenceLayout = mainItem.lastConfLayoutBeforeSharing
mainItem.lastConfLayoutBeforeSharing = -1
if (mainItem.conference && !mainItem.conference.core.isLocalScreenSharing && mainItem.lastConfLayoutBeforeSharing !==
-1) {
mainItem.conferenceLayout = mainItem.lastConfLayoutBeforeSharing;
mainItem.lastConfLayoutBeforeSharing = -1;
}
callLayout.sourceComponent = conference
? conference.core.isScreenSharingEnabled || (mainItem.conferenceLayout == LinphoneEnums.ConferenceLayout.ActiveSpeaker && participantDeviceCount > 1)
? activeSpeakerComponent
: participantDeviceCount <= 1
? waitingForOthersComponent
: gridComponent
: activeSpeakerComponent
callLayout.sourceComponent = conference ? conference.core.isScreenSharingEnabled || (mainItem.conferenceLayout
== LinphoneEnums.ConferenceLayout.ActiveSpeaker && participantDeviceCount > 1)
? activeSpeakerComponent : participantDeviceCount <= 1 ? waitingForOthersComponent : gridComponent :
activeSpeakerComponent;
}
Text {
@ -71,17 +67,15 @@ Item {
anchors.top: parent.top
anchors.topMargin: Utils.getSizeWithScreenRatio(25)
z: 1
visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error || mainItem.callState === LinphoneEnums.CallState.Released
text: mainItem.conference
visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error
|| mainItem.callState === LinphoneEnums.CallState.Released
text: mainItem.conference ?
//: "Vous avez quitté la conférence"
? qsTr("meeting_event_conference_destroyed")
: mainItem.callTerminatedByUser
qsTr("meeting_event_conference_destroyed") : mainItem.callTerminatedByUser ?
//: "Vous avez terminé l'appel"
? qsTr("call_ended_by_user")
: mainItem.callStarted
qsTr("call_ended_by_user") : mainItem.callStarted ?
//: "Votre correspondant a terminé l'appel"
? qsTr("call_ended_by_remote")
: call && call.core.lastErrorMessage || ""
qsTr("call_ended_by_remote") : call && call.core.lastErrorMessage || ""
color: DefaultStyle.grey_0
font {
pixelSize: Utils.getSizeWithScreenRatio(22)
@ -89,23 +83,20 @@ Item {
}
}
Loader{
Loader {
id: callLayout
anchors.fill: parent
sourceComponent: mainItem.participantDeviceCount === 0
? waitingForOthersComponent
: activeSpeakerComponent
sourceComponent: mainItem.participantDeviceCount === 0 ? waitingForOthersComponent : activeSpeakerComponent
}
Sticker {
id: preview
qmlName: 'P'
previewEnabled: true
visible: (callLayout.sourceComponent === activeSpeakerComponent || callLayout.sourceComponent === waitingForOthersComponent)
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingProgress
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingRinging
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingInit
&& !mainItem.conference?.core.isScreenSharingEnabled
visible: (callLayout.sourceComponent === activeSpeakerComponent || callLayout.sourceComponent
=== waitingForOthersComponent) && mainItem.callState !== LinphoneEnums.CallState.OutgoingProgress
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingRinging && mainItem.callState
!== LinphoneEnums.CallState.OutgoingInit && !mainItem.conference?.core.isScreenSharingEnabled
&& mainItem.participantDeviceCount <= 2
height: Utils.getSizeWithScreenRatio(180)
width: Utils.getSizeWithScreenRatio(300)
@ -113,7 +104,7 @@ Item {
anchors.bottom: mainItem.bottom
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
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)
account: accountObj && accountObj.value || null
call: mainItem.call
@ -125,19 +116,19 @@ Item {
anchors.fill: parent
movableArea: mainItem
margin: Utils.getSizeWithScreenRatio(10)
function resetPosition(){
preview.anchors.right = mainItem.right
preview.anchors.bottom = mainItem.bottom
preview.anchors.rightMargin = previewMouseArea.margin
preview.anchors.bottomMargin = previewMouseArea.margin
function resetPosition() {
preview.anchors.right = mainItem.right;
preview.anchors.bottom = mainItem.bottom;
preview.anchors.rightMargin = previewMouseArea.margin;
preview.anchors.bottomMargin = previewMouseArea.margin;
}
onVisibleChanged: if(!visible){
resetPosition()
onVisibleChanged: if (!visible) {
resetPosition();
}
drag.target: preview
onDraggingChanged: if(dragging) {
preview.anchors.right = undefined
preview.anchors.bottom = undefined
onDraggingChanged: if (dragging) {
preview.anchors.right = undefined;
preview.anchors.bottom = undefined;
}
onRequestResetPosition: resetPosition()
}
@ -178,10 +169,10 @@ Item {
textColor: DefaultStyle.main2_400
onClicked: {
if (mainItem.conference) {
UtilsCpp.copyToClipboard(mainItem.conference.core.uri)
UtilsCpp.copyToClipboard(mainItem.conference.core.uri);
showInformationPopup(qsTr("copied"),
//: 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
ActiveSpeakerLayout{
ActiveSpeakerLayout {
id: activeSpeaker
Layout.fillWidth: true
Layout.fillHeight: true
call: mainItem.call
}
}
Component{
Component {
id: gridComponent
CallGridLayout{
CallGridLayout {
Layout.fillWidth: true
Layout.fillHeight: true
call: mainItem.call

View file

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

View file

@ -16,7 +16,7 @@ ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(61)
function goToSlide(index) {
carouselStackLayout.goToSlideAtIndex(index)
carouselStackLayout.goToSlideAtIndex(index);
}
StackLayout {
@ -26,15 +26,18 @@ ColumnLayout {
currentIndex: 0
function goToSlideAtIndex(index) {
carouselStackLayout.previousIndex = carouselStackLayout.currentIndex
carouselStackLayout.currentIndex = index
carouselStackLayout.previousIndex = carouselStackLayout.currentIndex;
carouselStackLayout.currentIndex = index;
}
onCurrentIndexChanged: {
var currentItem = children[currentIndex]
var crossFaderAnim = crossFader.createObject(parent, {fadeInTarget: currentItem, mirrored: (previousIndex > currentIndex)})
crossFaderAnim.restart()
mainItem.currentIndex = currentIndex
var currentItem = children[currentIndex];
var crossFaderAnim = crossFader.createObject(parent, {
fadeInTarget: currentItem,
mirrored: (previousIndex > currentIndex)
});
crossFaderAnim.restart();
mainItem.currentIndex = currentIndex;
}
Component {
@ -56,7 +59,7 @@ ColumnLayout {
XAnimator {
target: fadeInTarget
from: (mirrored ? -1 : 1) * fadeInTarget.width/3.
from: (mirrored ? -1 : 1) * fadeInTarget.width / 3.
to: 0
duration: 300
easing.type: Easing.OutCubic
@ -73,8 +76,13 @@ ColumnLayout {
radius: Utils.getSizeWithScreenRatio(30)
color: DefaultStyle.main1_500_main
z: 1
x: mainItem.currentIndex >= 0 && mainItem.currentItem ? mainItem.currentItem.x - width/2 + mainItem.currentItem.width/2 : 0
Behavior on x { NumberAnimation {duration: 100}}
x: mainItem.currentIndex >= 0 && mainItem.currentItem ? mainItem.currentItem.x - width / 2
+ mainItem.currentItem.width / 2 : 0
Behavior on x {
NumberAnimation {
duration: 100
}
}
}
RowLayout {
id: carouselButtonsLayout
@ -96,12 +104,13 @@ ColumnLayout {
anchors.fill: parent
}
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)
columns: optimalColumns
property int optimalColumns: {
let maxCols = Math.floor(maxWidth / itemWidth);
let bestCols = 1;
@ -30,10 +29,7 @@ GridLayout {
let rows = Math.ceil(itemCount / cols);
let emptySlots = cols * rows - itemCount;
if (
rows < minRows ||
(rows === minRows && emptySlots < minEmptySlots)
) {
if (rows < minRows || (rows === minRows && emptySlots < minEmptySlots)) {
bestCols = cols;
minRows = rows;
minEmptySlots = emptySlots;

View file

@ -5,7 +5,7 @@ import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
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
ColumnLayout {
@ -48,13 +48,25 @@ ColumnLayout {
radius: Utils.getSizeWithScreenRatio(15)
borderGradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_100 }
GradientStop { position: 1.0; color: DefaultStyle.main2_200 }
GradientStop {
position: 0.0
color: DefaultStyle.grey_100
}
GradientStop {
position: 1.0
color: DefaultStyle.main2_200
}
}
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_0 }
GradientStop { position: 1.0; color: DefaultStyle.grey_100 }
GradientStop {
position: 0.0
color: DefaultStyle.grey_0
}
GradientStop {
position: 1.0
color: DefaultStyle.grey_100
}
}
}
contentItem: RowLayout {
@ -90,7 +102,7 @@ ColumnLayout {
}
}
Rectangle {
Layout.fillWidth:true
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(79)
color: 'transparent'
visible: contact && contact.core.presenceNote.length > 0 && !mainItem.useVerticalLayout

View file

@ -5,7 +5,7 @@ import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
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
Rectangle {

View file

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

View file

@ -5,7 +5,7 @@ import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
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
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/Control/Tool/Helper/utils.js" as Utils
FocusScope{
FocusScope {
id: mainItem
property alias contentItem: contentItem.data
property string label: ""
@ -21,24 +21,23 @@ FocusScope{
implicitHeight: layout.implicitHeight
function clearErrorText() {
errorText.clear()
errorText.clear();
}
onErrorMessageChanged: if (errorMessage.length > 0) {
var item = mainItem
var item = mainItem;
do {
var parentItem = item.parent
var parentItem = item.parent;
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) {
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;
}
}
item = parentItem
} while(item.parent != undefined && parentItem.contentItem === undefined)
item = parentItem;
} while (item.parent != undefined && parentItem.contentItem === undefined)
}
ColumnLayout {
@ -63,7 +62,9 @@ FocusScope{
weight: Typography.p2.weight
}
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
PopupButton {
visible: mainItem.tooltip !== ""
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
@ -99,6 +100,5 @@ FocusScope{
color: DefaultStyle.danger_500_main
}
}
}
}

View file

@ -6,7 +6,7 @@ import QtQuick.Effects
import Linphone
import UtilsCpp
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
FocusScope {
@ -17,8 +17,8 @@ FocusScope {
property string formTitle
property string createGroupButtonText
property int selectedParticipantsCount
signal returnRequested()
signal groupCreationRequested()
signal returnRequested
signal groupCreationRequested
ColumnLayout {
spacing: 0
@ -39,7 +39,7 @@ FocusScope {
//: Return
Accessible.name: qsTr("return_accessible_name")
onClicked: {
mainItem.returnRequested()
mainItem.returnRequested();
}
}
Text {
@ -62,7 +62,7 @@ FocusScope {
KeyNavigation.left: backGroupCallButton
KeyNavigation.right: backGroupCallButton
onClicked: {
mainItem.groupCreationRequested()
mainItem.groupCreationRequested();
}
}
}
@ -93,7 +93,6 @@ FocusScope {
Layout.topMargin: Utils.getSizeWithScreenRatio(15)
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
focus: true
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -6,7 +6,7 @@ import Linphone
import QtQml
import SettingsCpp
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
ListView {
@ -33,11 +33,8 @@ ListView {
width: mainItem.width
height: Utils.getSizeWithScreenRatio(45)
property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress)
property var callName : (modelData && !SettingsCpp.disableMeetingsFeature && modelData.core.isConference)
? modelData.core.conference.core.subject
: remoteNameObj
? remoteNameObj.value
: ""
property var callName: (modelData && !SettingsCpp.disableMeetingsFeature && modelData.core.isConference)
? modelData.core.conference.core.subject : remoteNameObj ? remoteNameObj.value : ""
Avatar {
id: delegateAvatar
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
@ -59,41 +56,41 @@ ListView {
Text {
id: callStateText
//: "Réunion
property string type: modelData.core.isConference ? qsTr("meeting")
property string type: modelData.core.isConference ? qsTr("meeting") :
//: "Appel"
: qsTr("call")
qsTr("call")
Layout.rightMargin: Utils.getSizeWithScreenRatio(2)
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
text: modelData.core.state === LinphoneEnums.CallState.Paused || modelData.core.state
=== LinphoneEnums.CallState.PausedByRemote ?
//: "%1 en pause"
? qsTr("paused_call_or_meeting").arg(type)
qsTr("paused_call_or_meeting").arg(type) :
//: "%1 en cours"
: qsTr("ongoing_call_or_meeting").arg(type)
qsTr("ongoing_call_or_meeting").arg(type)
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
Button {
id: transferButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.alignment: Qt.AlignVCenter
visible: mainItem.isTransferList
&& (mainItem.currentRemoteAddress !== modelData.core.remoteAddress)
&& modelData.core.state !== LinphoneEnums.CallState.IncomingReceived
&& modelData.core.state !== LinphoneEnums.CallState.PushIncomingReceived
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingInit
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingProgress
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingRinging
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingEarlyMedia
&& modelData.core.state !== LinphoneEnums.CallState.IncomingEarlyMedia
visible: mainItem.isTransferList && (mainItem.currentRemoteAddress !== modelData.core.remoteAddress)
&& modelData.core.state !== LinphoneEnums.CallState.IncomingReceived && modelData.core.state
!== LinphoneEnums.CallState.PushIncomingReceived && modelData.core.state !== LinphoneEnums.CallState.OutgoingInit
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingProgress && modelData.core.state
!== LinphoneEnums.CallState.OutgoingRinging && modelData.core.state
!== LinphoneEnums.CallState.OutgoingEarlyMedia && modelData.core.state
!== LinphoneEnums.CallState.IncomingEarlyMedia
icon.source: AppIcons.transferCall
style: ButtonStyle.noBackground
onClicked: {
mainItem.transferCallToAnotherRequested(modelData)
mainItem.transferCallToAnotherRequested(modelData);
}
//: Transfer call %1
Accessible.name: qsTr("transfer_call_name_accessible_name").arg(callInformationItem.callName)
@ -126,8 +123,7 @@ ListView {
//: Resume %1 call
qsTr("resume_call_name_accessible_name") :
//: Pause %1 call
qsTr("pause_call_name_accessible_name")
).arg(callInformationItem.callName)
qsTr("pause_call_name_accessible_name")).arg(callInformationItem.callName)
}
SmallButton {
id: endCallButton
@ -140,8 +136,8 @@ ListView {
icon.width: Utils.getSizeWithScreenRatio(18)
icon.height: Utils.getSizeWithScreenRatio(18)
onClicked: {
mainWindow.callTerminatedByUser = true
mainWindow.endCall(modelData)
mainWindow.callTerminatedByUser = true;
mainWindow.endCall(modelData);
}
TextMetrics {
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 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
// The FileView file does not allow that as it is a Loader and the image
@ -23,7 +22,7 @@ AnimatedImage {
mipmap: false//SettingsModel.mipmapEnabled
autoTransform: true
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.height: implicitHeight
states: State {
@ -38,19 +37,21 @@ AnimatedImage {
// Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case
onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
else UtilsCpp.restoreGlobalCursor()
mainItem.state = containsMouse ? 'hovered' : ''
if (containsMouse)
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
mainItem.state = containsMouse ? 'hovered' : '';
}
onPressed: (mouse) => {
mouse.accepted = true
onPressed: mouse => {
mouse.accepted = true;
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile()
mainItem.contentGui.core.lOpenFile();
}
}
}

View file

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

View file

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

View file

@ -17,14 +17,14 @@ Control.Control {
property ChatMessageGui chatMessage
property ChatGui chat
property string searchedTextPart
property string ownReaction: chatMessage? chatMessage.core.ownReaction : ""
property string fromAddress: chatMessage? chatMessage.core.fromAddress : ""
property bool isRemoteMessage: chatMessage? chatMessage.core.isRemoteMessage : false
property bool isFromChatGroup: chatMessage? chatMessage.core.isFromChatGroup : false
property bool isReply: chatMessage? chatMessage.core.isReply : false
property bool isForward: chatMessage? chatMessage.core.isForward : false
property string replyText: chatMessage? chatMessage.core.replyText : ""
property string replyMessageId: chatMessage? chatMessage.core.replyMessageId : ""
property string ownReaction: chatMessage ? chatMessage.core.ownReaction : ""
property string fromAddress: chatMessage ? chatMessage.core.fromAddress : ""
property bool isRemoteMessage: chatMessage ? chatMessage.core.isRemoteMessage : false
property bool isFromChatGroup: chatMessage ? chatMessage.core.isFromChatGroup : false
property bool isReply: chatMessage ? chatMessage.core.isReply : false
property bool isForward: chatMessage ? chatMessage.core.isForward : false
property string replyText: chatMessage ? chatMessage.core.replyText : ""
property string replyMessageId: chatMessage ? chatMessage.core.replyMessageId : ""
property var msgState: chatMessage ? chatMessage.core.messageState : LinphoneEnums.ChatMessageState.StateIdle
hoverEnabled: true
property bool linkHovered: false
@ -32,15 +32,15 @@ Control.Control {
leftPadding: isRemoteMessage ? Utils.getSizeWithScreenRatio(5) : 0
signal messageDeletionRequested()
signal messageEditionRequested()
signal messageDeletionRequested
signal messageEditionRequested
signal isFileHoveringChanged(bool isFileHovering)
signal showReactionsForMessageRequested()
signal showImdnStatusForMessageRequested()
signal replyToMessageRequested()
signal forwardMessageRequested()
signal endOfVoiceRecordingReached()
signal requestAutoPlayVoiceRecording()
signal showReactionsForMessageRequested
signal showImdnStatusForMessageRequested
signal replyToMessageRequested
signal forwardMessageRequested
signal endOfVoiceRecordingReached
signal requestAutoPlayVoiceRecording
signal searchMessageByIdRequested(string id)
onRequestAutoPlayVoiceRecording: chatBubbleContent.requestAutoPlayVoiceRecording()
@ -51,8 +51,8 @@ Control.Control {
onTriggered: highlightRectangle.opacity = 0
}
function requestHighlight() {
highlightRectangle.opacity = 0.8
hightlightTimer.start()
highlightRectangle.opacity = 0.8;
hightlightTimer.start();
}
background: Item {
@ -61,7 +61,7 @@ Control.Control {
function handleDefaultMouseEvent(event) {
if (event.button === Qt.RightButton) {
optionsMenu.open()
optionsMenu.open();
}
}
@ -87,7 +87,7 @@ Control.Control {
spacing: Utils.getSizeWithScreenRatio(8)
visible: mainItem.isForward
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 {
imageSource: AppIcons.forward
colorizationColor: DefaultStyle.main2_500_main
@ -123,18 +123,18 @@ Control.Control {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(12)
}
Text {
Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft: Qt.AlignRight
text: mainItem.isRemoteMessage
? mainItem.chatMessage.core.repliedToName !== ""
Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft : Qt.AlignRight
text: mainItem.isRemoteMessage ? mainItem.chatMessage.core.repliedToName !== "" ?
//: %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
: qsTr("chat_message_remote_replied").arg(mainItem.chatMessage.core.fromName)
: mainItem.chatMessage.core.repliedToName !== ""
qsTr("chat_message_remote_replied").arg(mainItem.chatMessage.core.fromName) :
mainItem.chatMessage.core.repliedToName !== "" ?
//: 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
: qsTr("chat_message_user_replied")
qsTr("chat_message_user_replied")
color: DefaultStyle.main2_600
font {
pixelSize: Typography.p4.pixelSize
@ -160,7 +160,7 @@ Control.Control {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
mainItem.searchMessageByIdRequested(mainItem.replyMessageId)
mainItem.searchMessageByIdRequested(mainItem.replyMessageId);
}
}
}
@ -175,7 +175,9 @@ Control.Control {
}
}
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
}
RowLayout {
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
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: (mouse) => mainItem.handleDefaultMouseEvent(mouse)
onClicked: mouse => mainItem.handleDefaultMouseEvent(mouse)
}
background: Item {
@ -275,8 +277,8 @@ Control.Control {
searchedTextPart: mainItem.searchedTextPart
chatMessageGui: mainItem.chatMessage
maxWidth: mainItem.maxWidth
onMouseEvent: (event) => {
mainItem.handleDefaultMouseEvent(event)
onMouseEvent: event => {
mainItem.handleDefaultMouseEvent(event);
}
onEndOfVoiceRecordingReached: mainItem.endOfVoiceRecordingReached()
}
@ -336,24 +338,21 @@ Control.Control {
Layout.preferredHeight: visible ? 14 : 0
Layout.alignment: Qt.AlignVCenter
colorizationColor: DefaultStyle.main1_500_main
imageSource: mainItem.msgState === LinphoneEnums.ChatMessageState.StateDelivered
? AppIcons.envelope
: mainItem.msgState === LinphoneEnums.ChatMessageState.StateDeliveredToUser
? AppIcons.check
: mainItem.msgState === LinphoneEnums.ChatMessageState.StateNotDelivered
? AppIcons.warningCircle
: mainItem.msgState === LinphoneEnums.ChatMessageState.StateDisplayed
? AppIcons.checks
: mainItem.msgState === LinphoneEnums.ChatMessageState.StatePendingDelivery
? AppIcons.hourglass
: ""
imageSource: mainItem.msgState === LinphoneEnums.ChatMessageState.StateDelivered ? AppIcons.envelope :
mainItem.msgState === LinphoneEnums.ChatMessageState.StateDeliveredToUser
? AppIcons.check : mainItem.msgState
=== LinphoneEnums.ChatMessageState.StateNotDelivered ? AppIcons.warningCircle :
mainItem.msgState === LinphoneEnums.ChatMessageState.StateDisplayed
? AppIcons.checks : mainItem.msgState
=== LinphoneEnums.ChatMessageState.StatePendingDelivery
? AppIcons.hourglass : ""
BusyIndicator {
anchors.fill: parent
Layout.preferredWidth: visible ? 14 : 0
Layout.preferredHeight: visible ? 14 : 0
visible: mainItem.msgState === LinphoneEnums.ChatMessageState.StateIdle
|| mainItem.msgState === LinphoneEnums.ChatMessageState.StateInProgress
|| mainItem.msgState === LinphoneEnums.ChatMessageState.StateFileTransferInProgress
visible: mainItem.msgState === LinphoneEnums.ChatMessageState.StateIdle || mainItem.msgState
=== LinphoneEnums.ChatMessageState.StateInProgress || mainItem.msgState
=== LinphoneEnums.ChatMessageState.StateFileTransferInProgress
}
}
}
@ -419,7 +418,8 @@ Control.Control {
}
RowLayout {
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.rightMargin: Utils.getSizeWithScreenRatio(8)
Layout.alignment: Qt.AlignVCenter
@ -440,7 +440,7 @@ Control.Control {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: {
mainItem.chatMessage.lSend()
mainItem.chatMessage.lSend();
}
}
IconLabelButton {
@ -451,8 +451,8 @@ Control.Control {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: {
mainItem.showImdnStatusForMessageRequested()
optionsMenu.close()
mainItem.showImdnStatusForMessageRequested();
optionsMenu.close();
}
}
IconLabelButton {
@ -464,8 +464,8 @@ Control.Control {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: {
mainItem.messageEditionRequested()
optionsMenu.close()
mainItem.messageEditionRequested();
optionsMenu.close();
}
}
IconLabelButton {
@ -477,29 +477,31 @@ Control.Control {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: {
mainItem.replyToMessageRequested()
optionsMenu.close()
mainItem.replyToMessageRequested();
optionsMenu.close();
}
}
IconLabelButton {
inverseLayout: true
visible: !mainItem.chatMessage.core.isRetracted
text: chatBubbleContent.selectedText != ""
text: chatBubbleContent.selectedText != "" ?
//: "Copy selection"
? qsTr("chat_message_copy_selection")
qsTr("chat_message_copy_selection") :
//: "Copy"
: qsTr("chat_message_copy")
qsTr("chat_message_copy")
icon.source: AppIcons.copy
// spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
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
if (success) UtilsCpp.showInformationPopup(qsTr("chat_message_copied_to_clipboard_title"),
if (success)
UtilsCpp.showInformationPopup(qsTr("chat_message_copied_to_clipboard_title"),
//: "to clipboard"
qsTr("chat_message_copied_to_clipboard_toast"))
optionsMenu.close()
qsTr("chat_message_copied_to_clipboard_toast"));
optionsMenu.close();
}
}
IconLabelButton {
@ -511,8 +513,8 @@ Control.Control {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: {
mainItem.forwardMessageRequested()
optionsMenu.close()
mainItem.forwardMessageRequested();
optionsMenu.close();
}
}
Rectangle {
@ -529,8 +531,8 @@ Control.Control {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
onClicked: {
mainItem.messageDeletionRequested()
optionsMenu.close()
mainItem.messageDeletionRequested();
optionsMenu.close();
}
style: ButtonStyle.hoveredBackgroundRed
}
@ -553,11 +555,13 @@ Control.Control {
visible: mainItem.ownReaction === modelData
}
onClicked: {
if(modelData) {
if (mainItem.ownReaction === modelData) mainItem.chatMessage.core.lRemoveReaction()
else mainItem.chatMessage.core.lSendReaction(modelData)
if (modelData) {
if (mainItem.ownReaction === 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.contentItem: EmojiPicker {
id: emojiPicker
onEmojiClicked: (emoji) => {
onEmojiClicked: emoji => {
if (mainItem.chatMessage) {
if (mainItem.ownReaction === emoji) mainItem.chatMessage.core.lRemoveReaction()
else mainItem.chatMessage.core.lSendReaction(emoji)
if (mainItem.ownReaction === emoji)
mainItem.chatMessage.core.lRemoveReaction();
else
mainItem.chatMessage.core.lSendReaction(emoji);
}
emojiPickerButton.close()
emojiButton.close()
emojiPickerButton.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 {
id: mainItem
property ChatMessageGui chatMessageGui: null
property bool isRemoteMessage: chatMessageGui? chatMessageGui.core.isRemoteMessage : false
property bool isRemoteMessage: chatMessageGui ? chatMessageGui.core.isRemoteMessage : false
property ChatGui chatGui: null
signal isFileHoveringChanged(bool isFileHovering)
signal lastSelectedTextChanged(string selectedText)
// signal conferenceIcsCopied()
signal mouseEvent(MouseEvent event)
signal endOfVoiceRecordingReached()
signal requestAutoPlayVoiceRecording()
signal endOfVoiceRecordingReached
signal requestAutoPlayVoiceRecording
property string selectedText
property color textColor
property string searchedTextPart
property int fileBorderWidth : 0
property int fileBorderWidth: 0
property int maxWidth
spacing: Utils.getSizeWithScreenRatio(5)
@ -57,7 +57,7 @@ ColumnLayout {
Connections {
target: mainItem
function onRequestAutoPlayVoiceRecording() {
audioContent.requestPlaying()
audioContent.requestPlaying();
}
}
// width: conferenceList.width
@ -68,14 +68,14 @@ ColumnLayout {
Repeater {
id: conferenceList
visible: count > 0
model: ChatMessageContentProxy{
model: ChatMessageContentProxy {
filterType: ChatMessageContentProxy.FilterContentType.Conference
chatMessageGui: mainItem.chatMessageGui
}
delegate: ChatMessageInvitationBubble {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(490)
conferenceInfoGui: modelData.core.conferenceInfo
onMouseEvent: (event) => mainItem.mouseEvent(event)
onMouseEvent: event => mainItem.mouseEvent(event)
}
}
// SINGLE FILE
@ -83,9 +83,7 @@ ColumnLayout {
id: singleImageFile
cache: false
visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isImage(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
fillMode: Image.PreserveAspectFit
@ -93,9 +91,7 @@ ColumnLayout {
AnimatedImageFileView {
id: singleAnimatedImageFile
visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isAnimatedImage(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
Layout.fillWidth: true
Layout.preferredHeight: paintedHeight
Layout.alignment: Qt.AlignHCenter
@ -107,22 +103,20 @@ ColumnLayout {
onStatusChanged: {
if (status == Image.Ready) {
if (singleAnimatedImageFile.initialization) {
initialSourceWidth = sourceSize.width
initialSourceHeight = sourceSize.height
singleAnimatedImageFile.initialization = false
initialSourceWidth = sourceSize.width;
initialSourceHeight = sourceSize.height;
singleAnimatedImageFile.initialization = false;
}
var sourceW = Math.min(initialSourceWidth, mainItem.maxWidth)
sourceSize.height = Math.round((sourceW/initialSourceWidth) * initialSourceHeight)
sourceSize.width = sourceW
var sourceW = Math.min(initialSourceWidth, mainItem.maxWidth);
sourceSize.height = Math.round((sourceW / initialSourceWidth) * initialSourceHeight);
sourceSize.width = sourceW;
}
}
}
VideoFileView {
id: singleVideoFile
visible: mainItem.filescontentProxy.count === 1 && UtilsCpp.isVideo(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
Layout.fillWidth: true
width: Math.min(Utils.getSizeWithScreenRatio(285), mainItem.maxWidth)
height: Math.min(Utils.getSizeWithScreenRatio(285), mainItem.maxWidth)
@ -135,13 +129,11 @@ ColumnLayout {
// FILES
ChatFilesGridLayout {
id: messageFilesList
visible: mainItem.filescontentProxy.count > 0
&& !singleImageFile.visible
&& !singleAnimatedImageFile.visible
&& !singleVideoFile.visible
visible: mainItem.filescontentProxy.count > 0 && !singleImageFile.visible && !singleAnimatedImageFile.visible &&
!singleVideoFile.visible
Layout.fillWidth: visible
Layout.fillHeight: visible
maxWidth: Utils.getSizeWithScreenRatio(115*3)
maxWidth: Utils.getSizeWithScreenRatio(115 * 3)
// Layout.fillHeight: true
proxyModel: visible ? mainItem.filescontentProxy : null
// 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
ColumnLayout {
spacing: 0
id: mainItem
spacing: 0
width: Utils.getSizeWithScreenRatio(490)
property ConferenceInfoGui conferenceInfoGui
@ -36,9 +35,8 @@ ColumnLayout {
let offsetHours = Math.floor(offsetMinutes / 60);
let timeZone = "UTC" + (offsetHours >= 0 ? "+" : "") + offsetHours;
timeRangeText =
qsTr("ics_bubble_meeting_from") + startTime +
qsTr("ics_bubble_meeting_to") + endTime + " (" + timeZone + ")";
timeRangeText = qsTr("ics_bubble_meeting_from") + startTime + qsTr("ics_bubble_meeting_to") + endTime + " ("
+ timeZone + ")";
}
Control.Control {
@ -56,22 +54,18 @@ ColumnLayout {
}
contentItem: ColumnLayout {
Text {
visible: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated
|| conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled
text: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated
visible: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated || conferenceInfo.state
== LinphoneEnums.ConferenceInfoState.Cancelled
text: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ?
//: Meeting has been updated
? qsTr("ics_bubble_meeting_modified") + " :"
: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled
qsTr("ics_bubble_meeting_modified") + " :" : conferenceInfo.state
== LinphoneEnums.ConferenceInfoState.Cancelled ?
//: Meeting has been canceled
? qsTr("ics_bubble_meeting_cancelled") + " :"
: ""
qsTr("ics_bubble_meeting_cancelled") + " :" : ""
font: Typography.p2
color: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.New ?
DefaultStyle.main2_600 :
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ?
DefaultStyle.warning_600 :
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled ?
DefaultStyle.danger_500_main :
color: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.New ? DefaultStyle.main2_600 : conferenceInfo.state
== LinphoneEnums.ConferenceInfoState.Updated ? DefaultStyle.warning_600 : conferenceInfo.state
== LinphoneEnums.ConferenceInfoState.Cancelled ? DefaultStyle.danger_500_main :
DefaultStyle.main2_600
}
@ -170,18 +164,16 @@ ColumnLayout {
style: ButtonStyle.noBackground
icon.source: AppIcons.calendarPlus
onClicked: {
conferenceInfo.exportConferenceToICS()
conferenceInfo.exportConferenceToICS();
}
}
}
Text {
//: from %1 to %2 (UTC%3)
property string offsetFromUtc: conferenceInfo.timeZoneModel.offsetFromUtc > 0
? "+" + conferenceInfo.timeZoneModel.offsetFromUtc/3600
: conferenceInfo.timeZoneModel.offsetFromUtc/3600
text: qsTr("").arg(
conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(
conferenceInfo.endDateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(offsetFromUtc)
property string offsetFromUtc: conferenceInfo.timeZoneModel.offsetFromUtc > 0 ? "+" + conferenceInfo.timeZoneModel.offsetFromUtc
/ 3600 : conferenceInfo.timeZoneModel.offsetFromUtc / 3600
text: qsTr("").arg(conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(conferenceInfo.endDateTime.toLocaleString(
Qt.locale(), "hh:mm")).arg(offsetFromUtc)
color: DefaultStyle.main2_500_main
font: Typography.p4
}
@ -196,7 +188,6 @@ ColumnLayout {
}
}
Rectangle {
visible: conferenceInfo.description.length > 0 || conferenceInfo.participantCount > 0
Layout.fillWidth: true
@ -225,7 +216,7 @@ ColumnLayout {
MouseArea {
anchors.fill: parent
cursorShape: mainItem.linkHovered ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: (mouse) => mouseEvent(mouse)
onClicked: mouse => mouseEvent(mouse)
acceptedButtons: Qt.AllButtons // Send all to parent
}
@ -259,14 +250,14 @@ ColumnLayout {
maximumLineCount: 3
elide: Text.ElideRight
visible: conferenceInfo.description.length > 0
onLinkActivated: (link) => {
onLinkActivated: link => {
if (link.startsWith('sip'))
UtilsCpp.createCall(link)
UtilsCpp.createCall(link);
else
Qt.openUrlExternally(link)
Qt.openUrlExternally(link);
}
onHoveredLinkChanged: {
mainItem.linkHovered = hoveredLink !== ""
mainItem.linkHovered = hoveredLink !== "";
}
}
}
@ -297,9 +288,9 @@ ColumnLayout {
text: qsTr("ics_bubble_join")
visible: !SettingsCpp.disableMeetingsFeature && conferenceInfo.state != LinphoneEnums.ConferenceInfoState.Cancelled
onClicked: {
var callsWindow = UtilsCpp.getOrCreateCallsWindow()
callsWindow.setupConference(mainItem.conferenceInfoGui)
UtilsCpp.smartShowWindow(callsWindow)
var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfoGui);
UtilsCpp.smartShowWindow(callsWindow);
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -4,11 +4,10 @@ import QtQuick.Layouts
import Linphone
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
// 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
// Use override cursor for this case
onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
else UtilsCpp.restoreGlobalCursor()
if (containsMouse)
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
}
onPressed: (mouse) => {
mouse.accepted = true
onPressed: mouse => {
mouse.accepted = true;
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile()
mainItem.contentGui.core.lOpenFile();
}
}
}

View file

@ -5,7 +5,7 @@ import QtQuick.Layouts
import Linphone
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 {
@ -60,12 +60,14 @@ Rectangle {
// Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case
onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
else UtilsCpp.restoreGlobalCursor()
if (containsMouse)
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
}
onPressed: (mouse) => {
mouse.accepted = true
mainItem.contentGui.core.lOpenFile()
onPressed: mouse => {
mouse.accepted = true;
mainItem.contentGui.core.lOpenFile();
}
}
EffectImage {

View file

@ -63,130 +63,128 @@ Flickable {
signal contactSelected(FriendGui contact)
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) {
contactsList.selectIndex(index)
contactsList.selectIndex(index);
}
return index
return index;
}
function addContactToSelection(address) {
if (multiSelectionEnabled) {
var indexInSelection = selectedContacts.indexOf(address)
var indexInSelection = selectedContacts.indexOf(address);
if (indexInSelection == -1) {
selectedContacts.push(address)
contactAddedToSelection(address)
selectedContacts.push(address);
contactAddedToSelection(address);
}
}
}
function removeContactFromSelection(indexInSelection) {
var addressToRemove = selectedContacts[indexInSelection]
var addressToRemove = selectedContacts[indexInSelection];
if (indexInSelection != -1) {
selectedContacts.splice(indexInSelection, 1)
contactRemovedFromSelection(addressToRemove)
selectedContacts.splice(indexInSelection, 1);
contactRemovedFromSelection(addressToRemove);
}
}
function removeSelectedContactByAddress(address) {
var index = selectedContacts.indexOf(address)
var index = selectedContacts.indexOf(address);
if (index != -1) {
selectedContacts.splice(index, 1)
contactRemovedFromSelection(address)
selectedContacts.splice(index, 1);
contactRemovedFromSelection(address);
}
}
function haveAddress(address) {
var index = magicSearchProxy.findFriendIndexByAddress(address)
return index != -1
var index = magicSearchProxy.findFriendIndexByAddress(address);
return index != -1;
}
function getFirstContact() {
if (mainItem.showFavorites) {
var firstContact = favoritesList.itemAtIndex(0)
if (firstContact !== null) return firstContact
var firstContact = favoritesList.itemAtIndex(0);
if (firstContact !== null)
return firstContact;
}
var firstContact = contactsList.itemAtIndex(0)
if (firstContact !== null) return firstContact
var firstContact = contactsList.itemAtIndex(0);
if (firstContact !== null)
return firstContact;
if (!mainItem.hideSuggestions) {
var firstContact = suggestionsList.itemAtIndex(0)
if (firstContact !== null) return firstContact
var firstContact = suggestionsList.itemAtIndex(0);
if (firstContact !== null)
return firstContact;
}
return null
return null;
}
function resetSelections() {
mainItem.highlightedContact = null
favoritesList.currentIndex = -1
contactsList.currentIndex = -1
suggestionsList.currentIndex = -1
mainItem.highlightedContact = null;
favoritesList.currentIndex = -1;
contactsList.currentIndex = -1;
suggestionsList.currentIndex = -1;
}
function findNextList(item, count, direction) {
if (count == 3)
return null
var nextItem
return null;
var nextItem;
switch (item) {
case suggestionsList:
nextItem = (direction > 0 ? favoritesList : contactsList)
break
nextItem = (direction > 0 ? favoritesList : contactsList);
break;
case contactsList:
nextItem = (direction > 0 ? suggestionsList : favoritesList)
break
nextItem = (direction > 0 ? suggestionsList : favoritesList);
break;
case favoritesList:
nextItem = (direction > 0 ? contactsList : suggestionsList)
break
nextItem = (direction > 0 ? contactsList : suggestionsList);
break;
default:
return null
return null;
}
if (nextItem.model.count > 0)
return nextItem
return nextItem;
else
return findNextList(nextItem, count + 1, direction)
return findNextList(nextItem, count + 1, direction);
}
function updatePosition(list) {
Utils.updatePosition(mainItem, list)
Utils.updatePosition(mainItem, list);
}
onHighlightedContactChanged: {
favoritesList.highlightedContact = highlightedContact
contactsList.highlightedContact = highlightedContact
suggestionsList.highlightedContact = highlightedContact
favoritesList.highlightedContact = highlightedContact;
contactsList.highlightedContact = highlightedContact;
suggestionsList.highlightedContact = highlightedContact;
}
onSearchBarTextChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText
searchText = searchBarText.length === 0 ? "*" : searchBarText;
}
}
onPauseSearchChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText
searchText = searchBarText.length === 0 ? "*" : searchBarText;
}
}
onSearchTextChanged: {
loading = true
loading = true;
}
Keys.onPressed: event => {
if (!event.accepted) {
if (event.key == Qt.Key_Up
|| event.key == Qt.Key_Down) {
var newItem
var direction = (event.key == Qt.Key_Up ? -1 : 1)
if (event.key == Qt.Key_Up || event.key == Qt.Key_Down) {
var newItem;
var direction = (event.key == Qt.Key_Up ? -1 : 1);
if (suggestionsList.activeFocus)
newItem = findNextList(suggestionsList, 0,
direction)
newItem = findNextList(suggestionsList, 0, direction);
else if (contactsList.activeFocus)
newItem = findNextList(contactsList, 0,
direction)
newItem = findNextList(contactsList, 0, direction);
else if (favoritesList.activeFocus)
newItem = findNextList(favoritesList, 0,
direction)
newItem = findNextList(favoritesList, 0, direction);
else
newItem = findNextList(suggestionsList, 0,
direction)
newItem = findNextList(suggestionsList, 0, direction);
if (newItem) {
newItem.selectIndex(
direction > 0 ? -1 : newItem.model.count - 1, direction > 0 ? Qt.BacktabFocusReason : Qt.TabFocusReason)
event.accepted = true
newItem.selectIndex(direction > 0 ? -1 : newItem.model.count - 1, direction > 0 ? Qt.BacktabFocusReason :
Qt.TabFocusReason);
event.accepted = true;
}
}
}
@ -194,8 +192,7 @@ Flickable {
Component.onCompleted: {
if (confInfoGui) {
for (var i = 0; i < confInfoGui.core.participants.length; ++i) {
selectedContacts.push(
confInfoGui.core.getParticipantAddressAt(i))
selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i));
}
}
}
@ -204,7 +201,7 @@ Flickable {
target: SettingsCpp
onLdapConfigChanged: {
if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate()
magicSearchProxy.forceUpdate();
}
}
@ -214,29 +211,28 @@ Flickable {
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
sourceFlags: mainItem.sourceFlags
onModelReset: {
mainItem.resetSelections()
mainItem.resetSelections();
}
onResultsProcessed: {
mainItem.loading = false
mainItem.contentY = 0
mainItem.loading = false;
mainItem.contentY = 0;
}
onInitialized: {
if (mainItem.searchOnEmpty || searchText != '') {
mainItem.loading = true
forceUpdate()
mainItem.loading = true;
forceUpdate();
}
}
}
onAtYEndChanged: if (atYEnd) {
if (favoritesProxy.haveMore && favoritesList.expanded && mainItem.showFavorites)
favoritesProxy.displayMore()
favoritesProxy.displayMore();
else if (contactsProxy.haveMore && contactsList.expanded) {
contactsProxy.displayMore()
}
else
suggestionsProxy.displayMore()
contactsProxy.displayMore();
} else
suggestionsProxy.displayMore();
}
Behavior on contentY {
NumberAnimation {
@ -292,19 +288,17 @@ Flickable {
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui)
mainItem.contactSelected(contactGui);
}
onUpdatePosition: mainItem.updatePosition(favoritesList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(
contact)
mainItem.contactDeletionRequested(contact);
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address)
mainItem.addContactToSelection(address);
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(
index)
mainItem.removeContactFromSelection(index);
}
property MagicSearchProxy proxy: MagicSearchProxy {
@ -313,9 +307,7 @@ Flickable {
showMe: mainItem.showMe
filterType: MagicSearchProxy.FilteringTypes.Favorites
}
model: mainItem.showFavorites
&& (mainItem.searchBarText == ''
|| mainItem.searchBarText == '*') ? proxy : []
model: mainItem.showFavorites && (mainItem.searchBarText == '' || mainItem.searchBarText == '*') ? proxy : []
}
ContactListView {
@ -339,32 +331,29 @@ Flickable {
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui)
mainItem.contactSelected(contactGui);
}
onUpdatePosition: mainItem.updatePosition(contactsList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(
contact)
mainItem.contactDeletionRequested(contact);
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address)
mainItem.addContactToSelection(address);
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(
index)
mainItem.removeContactFromSelection(index);
}
model: MagicSearchProxy {
id: contactsProxy
parentProxy: mainItem.mainModel
filterType: MagicSearchProxy.FilteringTypes.App
| (mainItem.searchText != '*'
&& mainItem.searchText != ''
|| SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap | MagicSearchProxy.FilteringTypes.CardDAV : 0)
filterType: MagicSearchProxy.FilteringTypes.App | (mainItem.searchText != '*' && mainItem.searchText != ''
|| SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap
| MagicSearchProxy.FilteringTypes.CardDAV : 0)
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
displayItemsStep: 3 * initialDisplayItems / 2
onLocalFriendCreated: (index) => {
contactsList.selectIndex(index)
onLocalFriendCreated: index => {
contactsList.selectIndex(index);
}
}
}
@ -390,27 +379,24 @@ Flickable {
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui)
mainItem.contactSelected(contactGui);
}
onUpdatePosition: mainItem.updatePosition(suggestionsList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(
contact)
mainItem.contactDeletionRequested(contact);
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address)
mainItem.addContactToSelection(address);
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(
index)
mainItem.removeContactFromSelection(index);
}
model: MagicSearchProxy {
id: suggestionsProxy
parentProxy: mainItem.mainModel
filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other
initialDisplayItems: contactsProxy.haveMore && contactsList.expanded
? 0
: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
initialDisplayItems: contactsProxy.haveMore && contactsList.expanded ? 0 : Math.max(20, Math.round(2
* mainItem.height / Utils.getSizeWithScreenRatio(63)))
onInitialDisplayItemsChanged: maxDisplayItems = initialDisplayItems
displayItemsStep: 3 * initialDisplayItems / 2
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
// Initials will be displayed if there isn't any avatar.
// TODO : get FriendGui from Call.
Loader{
Loader {
id: mainItem
property AccountGui account: null
property FriendGui contact: null
property CallGui call: null
property bool isConference: false
property bool shadowEnabled: true
property var _address: account
? account.core?.identityAddress || ""
: call
? call.core.remoteAddress
: contact
? contact.core.defaultAddress
: ''
property var _address: account ? account.core?.identityAddress || "" : call ? call.core.remoteAddress : contact
? contact.core.defaultAddress : ''
readonly property var address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_address) : _address
property var displayNameObj: UtilsCpp.getDisplayName(_address)
property var displayNameVal: account && account.core.displayName
? account.core.displayName
: contact && contact.core.fullName
? contact.core.fullName
: displayNameObj
? displayNameObj.value
: ""
property bool haveAvatar: account
? account.core.pictureUri
: contact
? contact.core.pictureUri
: computedAvatarUri.length != 0
property var displayNameVal: account && account.core.displayName ? account.core.displayName : contact && contact.core.fullName
? contact.core.fullName : displayNameObj ? displayNameObj.value : ""
property bool haveAvatar: account ? account.core.pictureUri : contact ? contact.core.pictureUri :
computedAvatarUri.length != 0
property var avatarObj: UtilsCpp.findAvatarByAddress(_address)
property string computedAvatarUri: avatarObj ? avatarObj.value : ''
@ -51,17 +38,15 @@ Loader{
// override it as secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address)
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
? call.core.tokenVerified
: contact
? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount === contact.core.devices.length
: false
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp ? call.core.tokenVerified :
contact ? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount
=== contact.core.devices.length : false
property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe
property bool displayPresence: true
asynchronous: true
sourceComponent: Component{
sourceComponent: Component {
Item {
anchors.fill: parent
@ -81,10 +66,11 @@ Loader{
initialItem: mainItem.haveAvatar ? avatar : initials
anchors.fill: parent
Connections{
Connections {
target: mainItem
onHaveAvatarChanged: {
stackView.replace(mainItem.haveAvatar ? avatar : initials, StackView.Immediate)}
stackView.replace(mainItem.haveAvatar ? avatar : initials, StackView.Immediate);
}
}
Rectangle {
@ -104,13 +90,12 @@ Loader{
height: width
imageSource: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted
fillMode: Image.PreserveAspectFit
}
}
Image {
visible: mainItem.displayPresence
width: stackView.width/4.5
width: stackView.width / 4.5
height: width
sourceSize.width: width
sourceSize.height: width
@ -119,13 +104,8 @@ Loader{
anchors.right: parent.right
anchors.rightMargin: stackView.width / 15
z: 1
source: account
? (account.core?.registrationState !== LinphoneEnums.RegistrationState.Ok
? account.core?.registrationIcon
: account.core?.presenceIcon)
: (contact
? contact.core?.presenceIcon
: "")
source: account ? (account.core?.registrationState !== LinphoneEnums.RegistrationState.Ok ? account.core?.registrationIcon :
account.core?.presenceIcon) : (contact ? contact.core?.presenceIcon : "")
RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
direction: RotationAnimator.Clockwise
@ -135,10 +115,9 @@ Loader{
duration: 10000
}
}
}
Component{
Component {
id: initials
Item {
id: avatarItem
@ -146,7 +125,8 @@ Loader{
width: height
Rectangle {
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
color: DefaultStyle.main2_200
height: stackView.height
@ -167,7 +147,7 @@ Loader{
EffectImage {
id: initialImg
visible: initialItem.initials === "" || initialItem.initials[0] === "+"
width: stackView.width/2
width: stackView.width / 2
height: width
colorizationColor: DefaultStyle.main2_600
imageSource: mainItem.isConference ? AppIcons.videoconference : AppIcons.profile
@ -188,7 +168,7 @@ Loader{
}
}
}
Component{
Component {
id: avatar
Item {
id: avatarItem
@ -204,11 +184,8 @@ Loader{
sourceSize.height: avatarItem.height
fillMode: Image.PreserveAspectCrop
anchors.centerIn: parent
source: mainItem.account
? mainItem.account.core.pictureUri
: mainItem.contact
? mainItem.contact.core.pictureUri
: computedAvatarUri
source: mainItem.account ? mainItem.account.core.pictureUri : mainItem.contact ? mainItem.contact.core.pictureUri :
computedAvatarUri
mipmap: true
layer.enabled: true
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import Linphone
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
Column {
@ -42,10 +42,10 @@ Column {
text: mainItem.accountGui.core.presenceNote
onTextChanged: {
if (statusMessage.text.length > accountGui.core.maxPresenceNoteSize) {
statusMessage.text = previoustext
statusMessage.cursorPosition = statusMessage.text.length
statusMessage.text = previoustext;
statusMessage.cursorPosition = statusMessage.text.length;
} else {
previoustext = statusMessage.text
previoustext = statusMessage.text;
}
}
}
@ -71,8 +71,8 @@ Column {
text: qsTr("contact_presence_button_save_custom_status")
enabled: statusMessage.text.length > 0
onClicked: {
mainItem.accountGui.core.presenceNote = statusMessage.text
mainItem.isSet()
mainItem.accountGui.core.presenceNote = statusMessage.text;
mainItem.isSet();
}
}
}

View file

@ -3,16 +3,15 @@ import QtQuick.Controls
import QtQuick.Layouts
import Linphone
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
IconLabelButton {
id: mainItem
property var accountGui
property var presence
signal click()
signal click
style: ButtonStyle.hoveredBackgroundBis
height: Utils.getSizeWithScreenRatio(22)
@ -29,7 +28,7 @@ IconLabelButton {
padding: 0
onClicked: {
mainItem.accountGui.core.presence = mainItem.presence
mainItem.click()
mainItem.accountGui.core.presence = mainItem.presence;
mainItem.click();
}
}

View file

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

View file

@ -52,7 +52,7 @@ Item {
source: effect
maskSource: effect
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
MultiEffect {

View file

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

View file

@ -2,9 +2,9 @@ import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
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
Layout.fillWidth: true
color: DefaultStyle.main2_500_main

View file

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

View file

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

View file

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

View file

@ -4,7 +4,7 @@ import QtQuick.Controls.Basic as Control
import Linphone
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
ListView {
@ -26,7 +26,7 @@ ListView {
property ConferenceInfoGui confInfoGui
signal addParticipantRequested()
signal addParticipantRequested
Control.ScrollBar.vertical: ScrollBar {
id: scrollbar
@ -67,11 +67,14 @@ ListView {
maximumLineCount: 1
Layout.fillWidth: true
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
RowLayout {
Layout.alignment: Qt.AlignRight
property bool isMe: modelData.core.isMe
onIsMeChanged: if (isMe) mainItem.me = modelData
onIsMeChanged: if (isMe)
mainItem.me = modelData
spacing: Utils.getSizeWithScreenRatio(26)
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
@ -88,7 +91,8 @@ ListView {
}
Switch {
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)
onToggled: participantModel.setParticipantAdminStatus(modelData.core, position === 1)
}

View file

@ -12,11 +12,11 @@ Control.ProgressBar {
property color innerColor: DefaultStyle.info_500_main
property color innerTextColor: centeredText ? DefaultStyle.info_500_main : DefaultStyle.grey_0
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 bool centeredText: textSize.width >= barWidth
TextMetrics{
TextMetrics {
id: textSize
text: mainItem.innerText
font {

View file

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

View file

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

View file

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

View file

@ -9,14 +9,14 @@ Text {
color: DefaultStyle.danger_500_main
property bool isVisible: text.length > 0
function clear() {
autoHideErrorMessage.stop()
text = ""
autoHideErrorMessage.stop();
text = "";
}
function setText(text) {
if (text.length === 0) {
clear()
clear();
} else {
mainItem.text = text
mainItem.text = text;
}
}
font {
@ -27,9 +27,10 @@ Text {
id: autoHideErrorMessage
interval: 5000
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 {
id: background
anchors.fill: parent
radius: width/2
radius: width / 2
color: DefaultStyle.danger_500_main
}
MultiEffect {

View file

@ -25,9 +25,18 @@ FocusScope {
spacing: 0
Repeater {
model: [
{text: qsTr("conference_layout_grid"), imgUrl: AppIcons.layout},
{text: qsTr("conference_layout_active_speaker"), imgUrl: AppIcons.pip},
{text: qsTr("conference_layout_audio_only"), imgUrl: AppIcons.waveform}
{
text: qsTr("conference_layout_grid"),
imgUrl: AppIcons.layout
},
{
text: qsTr("conference_layout_active_speaker"),
imgUrl: AppIcons.pip
},
{
text: qsTr("conference_layout_audio_only"),
imgUrl: AppIcons.waveform
}
]
RadioButton {
id: radiobutton
@ -37,12 +46,11 @@ FocusScope {
indicatorSize: Utils.getSizeWithScreenRatio(20)
leftPadding: indicator.width + spacing
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.
checked: index == 0
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid
: index == 1
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker
: mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.AudioOnly
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.
checked: index == 0 ? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid : index == 1
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker : mainItem.conferenceLayout
=== LinphoneEnums.ConferenceLayout.AudioOnly
onClicked: mainItem.changeLayoutRequested(index)
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 Linphone
import ConstantsCpp 1.0
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/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ColumnLayout {
id: mainItem
@ -52,12 +52,11 @@ ColumnLayout {
target: LoginPageCpp
function onErrorMessageChanged() {
if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0)
errorText.setText(LoginPageCpp.errorMessage)
errorText.setText(LoginPageCpp.errorMessage);
}
}
}
}
}
RowLayout {
@ -92,34 +91,34 @@ ColumnLayout {
target: LoginPageCpp
function onRegistrationStateChanged() {
if (LoginPageCpp.registrationState != LinphoneEnums.RegistrationState.Progress) {
connectionButton.enabled = true
connectionButtonContent.currentIndex = 0
connectionButton.enabled = true;
connectionButtonContent.currentIndex = 0;
}
}
function onErrorMessageChanged() {
connectionButton.enabled = true
connectionButtonContent.currentIndex = 0
connectionButton.enabled = true;
connectionButtonContent.currentIndex = 0;
}
}
}
function trigger() {
username.errorMessage = ""
password.errorMessage = ""
errorText.text = ""
username.errorMessage = "";
password.errorMessage = "";
errorText.text = "";
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) {
if (usernameEdit.text.length == 0)
//: "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)
//: "Veuillez saisir un mot de passe"
password.errorMessage = qsTr("assistant_account_login_missing_password")
return
password.errorMessage = qsTr("assistant_account_login_missing_password");
return;
}
LoginPageCpp.login(usernameEdit.text, passwordEdit.text)
connectionButton.enabled = false
connectionButtonContent.currentIndex = 1
LoginPageCpp.login(usernameEdit.text, passwordEdit.text);
connectionButton.enabled = false;
connectionButtonContent.currentIndex = 1;
}
onPressed: connectionButton.trigger()
@ -132,6 +131,5 @@ ColumnLayout {
underline: true
onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl)
}
}
}

View file

@ -3,12 +3,12 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts
import Linphone
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
ColumnLayout {
id: mainItem
signal encryptionValidationRequested()
signal encryptionValidationRequested
property var call
RoundedPane {
Layout.fillWidth: true
@ -31,7 +31,8 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(7)
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
text: qsTr("call_stats_media_encryption").arg(mainItem.call.core.encryptionString)
Layout.alignment: Qt.AlignHCenter
@ -53,7 +54,8 @@ ColumnLayout {
}
Text {
//: "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
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
@ -91,9 +93,13 @@ ColumnLayout {
}
}
}
Item{Layout.fillHeight: true}
Item {
Layout.fillHeight: true
}
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
//: "Validation chiffrement"
text: qsTr("call_zrtp_validation_button_label")

View file

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

View file

@ -4,7 +4,7 @@ import QtQuick.Effects
import QtQuick.Controls.Basic as Control
import Linphone
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
ColumnLayout {
@ -12,12 +12,15 @@ ColumnLayout {
property CallGui call
property ConferenceGui conference: call.core.conference
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)
spacing: Utils.getSizeWithScreenRatio(12)
onIsLocalScreenSharingChanged: {if(isLocalScreenSharing) mainItem.call.core.videoSourceDescriptor = mainItem.desc }
onIsLocalScreenSharingChanged: {
if (isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc;
}
Text {
Layout.fillWidth: true
//: "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
}
TabBar {
Layout.fillWidth: true
id: bar
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(40)
pixelSize: Utils.getSizeWithScreenRatio(16)
//: "Ecran entier"
@ -37,7 +40,7 @@ ColumnLayout {
}
component ScreenPreviewLayout: Control.Control {
id: screenPreview
signal clicked()
signal clicked
property var screenSource
property int screenIndex
property bool selected: false
@ -58,32 +61,32 @@ ColumnLayout {
MouseArea {
anchors.fill: parent
onClicked: {
screenPreview.clicked()
screenPreview.clicked();
}
}
}
contentItem: ColumnLayout {
spacing: 0
Item{
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Image {
anchors.centerIn: parent
//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.height: parent.height
cache: false
}
}
RowLayout{
RowLayout {
Layout.topMargin: Utils.getSizeWithScreenRatio(6)
spacing: Utils.getSizeWithScreenRatio(5)
Image{
Image {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(15)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(15)
visible: !!$modelData?.windowId
source: visible ? "image://window_icon/"+ $modelData.windowId : ''
source: visible ? "image://window_icon/" + $modelData.windowId : ''
sourceSize.width: width
sourceSize.height: height
cache: false
@ -91,7 +94,7 @@ ColumnLayout {
Text {
Layout.fillWidth: true
//: "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
font.pixelSize: Utils.getSizeWithScreenRatio(displayScreen ? 14 : 10)
elide: Text.ElideRight
@ -103,49 +106,54 @@ ColumnLayout {
StackLayout {
id: stacklayout
currentIndex: bar.currentIndex
ListView{
ListView {
id: screensLayout
spacing: Utils.getSizeWithScreenRatio(16)
clip: true
Layout.fillWidth: true
height: visible ? contentHeight : 0
currentIndex: -1
model: ScreenProxy{
model: ScreenProxy {
id: screensList
mode: ScreenList.SCREENS
}
onVisibleChanged: {
if(visible) screensList.update()
else currentIndex = -1
if (visible)
screensList.update();
else
currentIndex = -1;
}
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
height: Utils.getSizeWithScreenRatio(219)
screenIndex: index
onClicked: {//screensLayout.selectedIndex = index
screensLayout.currentIndex = index
mainItem.desc.core.screenSharingIndex = index
if( mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc
onClicked: {
//screensLayout.selectedIndex = index
screensLayout.currentIndex = index;
mainItem.desc.core.screenSharingIndex = index;
if (mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc;
}
selected: mainItem.desc.core.screenSharingIndex === index
}
}
GridView{
GridView {
id: windowsLayout
//property int selectedIndex
Layout.preferredHeight: visible ? contentHeight : 0
Layout.fillWidth: true
model: ScreenProxy{
model: ScreenProxy {
id: windowsList
mode: ScreenList.WINDOWS
}
currentIndex: -1
onVisibleChanged: {
if(visible) windowsList.update()
else currentIndex = -1
if (visible)
windowsList.update();
else
currentIndex = -1;
}
cellWidth: width / 2
cellHeight: Utils.getSizeWithScreenRatio(112 + 15)
@ -159,10 +167,10 @@ ColumnLayout {
displayScreen: false
screenIndex: index
onClicked: {
windowsLayout.currentIndex = index
mainItem.desc.core.windowId = $modelData.windowId
if( mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc
windowsLayout.currentIndex = index;
mainItem.desc.core.windowId = $modelData.windowId;
if (mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc;
}
selected: mainItem.desc.core.windowId == $modelData.windowId
}
@ -174,13 +182,13 @@ ColumnLayout {
height: implicitHeight
visible: mainItem.screenSharingAvailable$
enabled: mainItem.isLocalScreenSharing || windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1
text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing
text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing ?
//: "Stop
? qsTr("stop")
qsTr("stop") :
//: "Partager"
: qsTr("share")
qsTr("share")
onClicked: {
mainItem.conference.core.lToggleScreenSharing()
mainItem.conference.core.lToggleScreenSharing();
}
style: ButtonStyle.main
}

View file

@ -6,7 +6,7 @@ import QtQuick.Effects
import Linphone
import ConstantsCpp 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
ListView {
@ -33,11 +33,12 @@ ListView {
to: UtilsCpp.addYears(new Date(), 5)
}
delegate: FocusScope{
delegate: FocusScope {
width: mainItem.width
height: mainItem.height
property bool isCurrentIndex: index == mainItem.currentIndex
onIsCurrentIndexChanged: if( isCurrentIndex) monthGrid.forceActiveFocus()
onIsCurrentIndexChanged: if (isCurrentIndex)
monthGrid.forceActiveFocus()
ColumnLayout {
anchors.fill: parent
property int currentMonth: model.month
@ -46,7 +47,9 @@ ListView {
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(38)
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 {
pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight
@ -64,7 +67,8 @@ ListView {
icon.height: height
style: ButtonStyle.noBackground
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 {
id: nextButton
@ -74,7 +78,8 @@ ListView {
icon.height: height
style: ButtonStyle.noBackground
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)
delegate: FocusScope {
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
objectName: 'focusDay'
activeFocusOnTab: true
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) {
monthGrid.clicked(model.date)
monthGrid.clicked(model.date);
event.accepted = true;
}else if(event.key == Qt.Key_Left){
var previous = nextItemInFocusChain(false)
if( previous.objectName != 'focusDay'){
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 if (event.key == Qt.Key_Left) {
var previous = nextItemInFocusChain(false);
if (previous.objectName != 'focusDay') {
previousButton.clicked(undefined);
} 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
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton
// onEntered: focusDay.forceActiveFocus()
onPressed: (event) =>{
focusDay.forceActiveFocus()
event.accepted = false
onPressed: event => {
focusDay.forceActiveFocus();
event.accepted = false;
}
}
@ -152,26 +159,22 @@ ListView {
radius: Utils.getSizeWithScreenRatio(50)
color: isSelectedDay ? DefaultStyle.main1_500_main : "transparent"
border.width: focusDay.activeFocus || hoveringArea.containsMouse ? 1 : 0
}
Text {
anchors.centerIn: parent
text: UtilsCpp.toDateDayString(model.date)
color: isSelectedDay
? DefaultStyle.grey_0
: UtilsCpp.isCurrentDay(model.date)
? DefaultStyle.main1_500_main
: UtilsCpp.dateisInMonth(model.date, mainItem.currentMonth, mainItem.currentYear)
? DefaultStyle.main2_700
: DefaultStyle.main2_400
color: isSelectedDay ? DefaultStyle.grey_0 : UtilsCpp.isCurrentDay(model.date) ? DefaultStyle.main1_500_main : UtilsCpp.dateisInMonth(
model.date, mainItem.currentMonth, mainItem.currentYear) ? DefaultStyle.main2_700 :
DefaultStyle.main2_400
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
onClicked: (date) => {
if (UtilsCpp.daysOffset(new Date(), date) >= 0) mainItem.selectedDate = date
onClicked: date => {
if (UtilsCpp.daysOffset(new Date(), date) >= 0)
mainItem.selectedDate = date;
}
}
}

View file

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

View file

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

View file

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

View file

@ -10,7 +10,7 @@ ColumnLayout {
property string label: ""
property alias errorMessage: errorText.text
property string placeholderText : ""
property string placeholderText: ""
property bool mandatory: false
property bool enableErrorText: true
property real textInputWidth: width
@ -44,11 +44,8 @@ ColumnLayout {
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(63)
color: DefaultStyle.grey_100
border.color: mainItem.errorMessage.length > 0
? DefaultStyle.danger_500_main
: (textField.activeFocus || combobox.activeFocus)
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200
border.color: mainItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : (textField.activeFocus
|| combobox.activeFocus) ? DefaultStyle.main1_500_main : DefaultStyle.grey_200
border.width: mainItem.borderWidth
}
contentItem: RowLayout {
@ -80,7 +77,9 @@ ColumnLayout {
border.width: mainItem.keyboardFocusedBorderWidth
}
initialText: initialPhoneNumber
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/}
validator: RegularExpressionValidator {
regularExpression: /[0-9]+/
}
//: %1 number
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 Linphone
import CustomControls 1.0
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/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
FocusScope {
id: mainItem
property bool magnifierVisible: true
property var validator: RegularExpressionValidator{}
property var validator: RegularExpressionValidator {}
property var numericPadPopup
property alias numericPadButton: dialerButton
readonly property bool hasActiveFocus: textField.activeFocus
@ -28,31 +28,33 @@ FocusScope {
property real textInputWidth: Utils.getSizeWithScreenRatio(350)
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() {
textField.text = ""
textField.text = "";
}
Connections {
enabled: numericPadPopup != undefined && handleNumericPadPopupButtonsPressed
target: numericPadPopup ? numericPadPopup : null
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
implicitHeight: Utils.getSizeWithScreenRatio(50)
Rectangle{
Rectangle {
id: backgroundItem
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(28)
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
}
EffectImage {
@ -98,17 +100,18 @@ FocusScope {
color: DefaultStyle.main2_500_main
width: Utils.getSizeWithScreenRatio(1)
}
Timer{
Timer {
id: delayTimer
interval: 300
repeat: false
onTriggered: textField.searchText = textField.text
}
Keys.onPressed: (event) => {
event.accepted = false
if (mainItem.numericPadPopup && mainItem.numericPadPopup.opened && (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return)) {
mainItem.numericPadPopup.keyPadKeyPressed(event)
event.accepted = true
Keys.onPressed: event => {
event.accepted = false;
if (mainItem.numericPadPopup && mainItem.numericPadPopup.opened && (event.modifiers & Qt.KeypadModifier
|| event.key === Qt.Key_Return)) {
mainItem.numericPadPopup.keyPadKeyPressed(event);
event.accepted = true;
}
}
}
@ -130,10 +133,11 @@ FocusScope {
//: "Open dialer"
Accessible.name: qsTr("open_dialer_acccessibility_label")
onClicked: {
if(!checked){
mainItem.openNumericPadRequested()
mainItem.numericPadPopup.open()
} else mainItem.numericPadPopup.close()
if (!checked) {
mainItem.openNumericPadRequested();
mainItem.numericPadPopup.open();
} else
mainItem.numericPadPopup.close();
}
}
Button {
@ -150,7 +154,7 @@ FocusScope {
//: "Clear text input"
Accessible.name: qsTr("clear_text_input_acccessibility_label")
onClicked: {
textField.clear()
textField.clear();
}
}
}

View file

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

View file

@ -3,7 +3,7 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts
import Linphone
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
Control.TextField {
@ -12,16 +12,15 @@ Control.TextField {
width: Utils.getSizeWithScreenRatio(customWidth ? customWidth - 1 : 360)
height: Utils.getSizeWithScreenRatio(49)
leftPadding: Utils.getSizeWithScreenRatio(15)
rightPadding: eyeButton.visible
? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin
: Utils.getSizeWithScreenRatio(15)
rightPadding: eyeButton.visible ? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin :
Utils.getSizeWithScreenRatio(15)
echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
// Workaround for Windows slowness when first typing a password
// due to Qt not initializing the Password echo mode before the first letter is typed
Component.onCompleted: {
text = "workaround"
resetText()
text = "workaround";
resetText();
}
verticalAlignment: TextInput.AlignVCenter
@ -68,54 +67,54 @@ Control.TextField {
property var propertyOwnerGui
property var initialReading: true
property var isValid: function (text) {
return true
return true;
}
property bool toValidate: false
property int idleTimeOut: 200
property bool empty: propertyOwnerGui
? mainItem.propertyOwnerGui.core != undefined && mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0
: mainItem.propertyOwner != undefined && mainItem.propertyOwner[mainItem.propertyName]?.length == 0
property bool empty: propertyOwnerGui ? mainItem.propertyOwnerGui.core != undefined
&& mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0 : mainItem.propertyOwner != undefined
&& mainItem.propertyOwner[mainItem.propertyName]?.length == 0
property bool canBeEmpty: true
signal validationChecked(bool valid)
function resetText() {
text = initialText
text = initialText;
}
signal enterPressed
onAccepted: {
// No need to process changing focus because of TextEdited callback.
idleTimer.stop()
updateText()
idleTimer.stop();
updateText();
}
onTextChanged: {
if (mainItem.toValidate) {
idleTimer.restart()
idleTimer.restart();
}
}
function updateText() {
mainItem.empty = text.length == 0
mainItem.empty = text.length == 0;
if (initialReading) {
initialReading = false
initialReading = false;
}
if (mainItem.empty && !mainItem.canBeEmpty) {
mainItem.validationChecked(false)
return
mainItem.validationChecked(false);
return;
}
if (mainItem.propertyName && isValid(text)) {
if (mainItem.propertyOwnerGui) {
if (mainItem.propertyOwnerGui.core[mainItem.propertyName] != text) {
mainItem.propertyOwnerGui.core[mainItem.propertyName] = text
mainItem.propertyOwnerGui.core[mainItem.propertyName] = text;
}
} else {
if (mainItem.propertyOwner[mainItem.propertyName] != text)
mainItem.propertyOwner[mainItem.propertyName] = text
mainItem.propertyOwner[mainItem.propertyName] = text;
}
mainItem.validationChecked(true)
mainItem.validationChecked(true);
} else
mainItem.validationChecked(false)
mainItem.validationChecked(false);
}
// Validation textfield functions
Timer {
@ -124,7 +123,7 @@ Control.TextField {
interval: mainItem.idleTimeOut
repeat: false
onTriggered: {
mainItem.accepted()
mainItem.accepted();
}
}
@ -134,7 +133,9 @@ Control.TextField {
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(79)
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
}
@ -169,24 +170,21 @@ Control.TextField {
}
onStopped: {
cursor.visible = false
cursor.visible = false;
}
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Control)
mainItem.controlIsDown = true
if (event.key === Qt.Key_Enter
|| event.key === Qt.Key_Return) {
enterPressed()
if (mainItem.controlIsDown) {
}
mainItem.controlIsDown = true;
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
enterPressed();
if (mainItem.controlIsDown) {}
}
}
Keys.onReleased: event => {
if (event.jey == Qt.Key_Control)
mainItem.controlIsDown = false
mainItem.controlIsDown = false;
}
Button {
@ -210,8 +208,7 @@ Control.TextField {
//: Hide %1
qsTr("hide_accessible_name") :
//: Show %1
qsTr("show_accessible_name")
).arg(mainItem.Accessible.name)
qsTr("show_accessible_name")).arg(mainItem.Accessible.name)
}
Button {
id: customButton
@ -229,6 +226,7 @@ Control.TextField {
anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
onClicked: mainItem.customCallback()
//: %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: {
if (minTime != undefined) {
if (UtilsCpp.timeOffset(minTime, selectedDateTime) < 0)
selectedDateTime = minTime
selectedDateTime = minTime;
}
if (maxTime != undefined) {
if (UtilsCpp.timeOffset(maxTime, selectedDateTime) > 0)
selectedDateTime = maxTime
selectedDateTime = maxTime;
}
}
readonly property string selectedTimeString: Qt.formatDateTime(selectedDateTime, "hh:mm")
property int selectedHour: input.hour*1
property int selectedMin: input.min*1
property int selectedHour: input.hour * 1
property int selectedMin: input.min * 1
property alias contentText: input
property var minTime
property var maxTime
@ -31,12 +31,12 @@ ComboBox {
popup.closePolicy: Popup.PressOutsideParent | Popup.CloseOnPressOutside
onCurrentTextChanged: input.text = currentText
popup.onOpened: {
input.forceActiveFocus()
input.forceActiveFocus();
}
contentItem: TextInput {
id: input
validator: IntValidator{}
validator: IntValidator {}
// activeFocusOnPress: false
inputMask: "00:00"
verticalAlignment: TextInput.AlignVCenter
@ -46,10 +46,10 @@ ComboBox {
color: DefaultStyle.main2_600
onActiveFocusChanged: {
if (activeFocus) {
selectAll()
selectAll();
} else {
listView.currentIndex = -1
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min)
listView.currentIndex = -1;
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
}
}
font {
@ -57,20 +57,20 @@ ComboBox {
weight: Typography.p2l.weight
}
text: mainItem.selectedTimeString
Keys.onPressed: (event) => {
Keys.onPressed: event => {
if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
focus = false
focus = false;
}
}
onFocusChanged: if (!focus) {
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min)
console.log("set time", hour, min)
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
console.log("set time", hour, min);
}
}
listView.delegate: Text {
id: hourDelegate
property int hour: modelData /2
property int min: modelData%2 === 0 ? 0 : 30
property int hour: modelData / 2
property int min: modelData % 2 === 0 ? 0 : 30
property var currentDateTime: UtilsCpp.createDateTime(new Date(), hour, min)
text: Qt.formatDateTime(currentDateTime, "hh:mm")
width: mainItem.width
@ -88,9 +88,9 @@ ComboBox {
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
// mainItem.text = parent.text
mainItem.listView.currentIndex = index
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min)
mainItem.popup.close()
mainItem.listView.currentIndex = index;
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
mainItem.popup.close();
}
Rectangle {
visible: parent.containsMouse

View file

@ -17,14 +17,14 @@ Window {
default property alias _content: content.data
property bool _isOpen: false
signal isOpened()
signal isClosed()
signal dataChanged()
signal isOpened
signal isClosed
signal dataChanged
on_ContentChanged: dataChanged(_content)
// ---------------------------------------------------------------------------
function open () {
function open() {
_isOpen = true;
isOpened();
}
@ -37,24 +37,24 @@ Window {
// ---------------------------------------------------------------------------
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
// flags: Qt.WindowDoesNotAcceptFocus | Qt.BypassWindowManagerHint | (showAsTool?Qt.Tool:Qt.WindowStaysOnTopHint) | Qt.Window | Qt.FramelessWindowHint;
flags: Qt.SplashScreen | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint // | Qt.WindowStaysOnTopHint
opacity: 1.0
height: _content[0] != null ? _content[0].height : 0
width: _content[0] != null ? _content[0].width : 0
visible:true
visible: true
Item {
id: content
anchors.fill:parent
anchors.fill: parent
focus: false
property var $parent: mainItem
}
// ---------------------------------------------------------------------------
/*
/*
states: State {
name: 'opening'
when: _isOpen

View file

@ -7,7 +7,7 @@ import QtQuick.Dialogs
import Linphone
import UtilsCpp
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
Dialog {
@ -27,15 +27,17 @@ Dialog {
closePolicy: Popup.NoAutoClose
onAccepted: {
if( callback) callback.cb(password)
close()
if (callback)
callback.cb(password);
close();
}
onRejected: close()
Component.onDestruction: if(callback) callback.destroy()
Component.onDestruction: if (callback)
callback.destroy()
content: ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(20)
id: contentLayout
spacing: Utils.getSizeWithScreenRatio(20)
Text {
Layout.fillWidth: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(250)
@ -99,13 +101,13 @@ Dialog {
KeyNavigation.up: passwordEdit
KeyNavigation.right: cancelButton
onClicked: {
passwordItem.errorMessage = ""
passwordItem.errorMessage = "";
if (passwordEdit.text.length == 0) {
//: Veuillez saisir un mot de passe
passwordItem.errorMessage = qsTr("assistant_account_login_missing_password")
return
passwordItem.errorMessage = qsTr("assistant_account_login_missing_password");
return;
}
mainItem.accepted()
mainItem.accepted();
}
}
]

View file

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

View file

@ -4,7 +4,7 @@ import QtQuick.Effects
import Linphone
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
// =============================================================================
@ -19,7 +19,8 @@ Dialog {
closePolicy: Popup.NoAutoClose
property var call
onCallChanged: if(!call) close()
onCallChanged: if (!call)
close()
property bool isTokenVerified: call && call.core.tokenVerified || false
property bool isCaseMismatch: call && call.core.isMismatch || false
property bool securityError: false
@ -32,11 +33,9 @@ Dialog {
anchors.fill: parent
width: mainItem.width
height: mainItem.implicitHeight
color: mainItem.securityError
? DefaultStyle.danger_500_main
: mainItem.isCaseMismatch
? DefaultStyle.warning_600
: DefaultStyle.info_500_main
color: mainItem.securityError ? DefaultStyle.danger_500_main : mainItem.isCaseMismatch ? DefaultStyle.warning_600 :
DefaultStyle.info_500_main
radius: mainItem.radius
Layout.ColumnLayout {
anchors.top: parent.top
@ -76,7 +75,9 @@ Dialog {
weight: Typography.p2l.weight
}
}
Item{Layout.Layout.fillHeight: true}
Item {
Layout.Layout.fillHeight: true
}
}
SmallButton {
visible: !mainItem.securityError
@ -92,8 +93,8 @@ Dialog {
pressedTextColor: DefaultStyle.grey_200
underline: true
onClicked: {
call.core.lSkipZrtpAuthentication()
mainItem.close()
call.core.lSkipZrtpAuthentication();
mainItem.close();
}
}
}
@ -129,11 +130,11 @@ Dialog {
Layout.Layout.preferredWidth: Utils.getSizeWithScreenRatio(343)
Layout.Layout.alignment: Qt.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 :"
? 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 : "
: qsTr("call_dialog_zrtp_validate_trust_message")
qsTr("call_dialog_zrtp_validate_trust_message")
wrapMode: Text.WordWrap
font.pixelSize: Utils.getSizeWithScreenRatio(14)
}
@ -199,8 +200,9 @@ Dialog {
radius: Utils.getSizeWithScreenRatio(71)
textColor: DefaultStyle.main2_600
onClicked: {
console.log("CHECK TOKEN", modelData)
if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(modelData)
console.log("CHECK TOKEN", modelData);
if (mainItem.call)
mainItem.call.core.lCheckAuthenticationTokenSelected(modelData);
}
}
}
@ -249,7 +251,8 @@ Dialog {
textColor: DefaultStyle.danger_500_main
visible: !mainItem.securityError
onClicked: {
if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(" ")
if (mainItem.call)
mainItem.call.core.lCheckAuthenticationTokenSelected(" ");
}
}
MediumButton {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Layouts
import QtQuick.Controls.Basic
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
Popup {
@ -14,10 +14,10 @@ Popup {
signal closePopup(int index)
onClosed: closePopup(index)
onAboutToShow: {
autoClosePopup.restart()
autoClosePopup.restart();
}
closePolicy: Popup.NoAutoClose
x : parent.x + parent.width - width
x: parent.x + parent.width - width
// y : parent.y + parent.height - height
rightMargin: Utils.getSizeWithScreenRatio(20)
bottomMargin: Utils.getSizeWithScreenRatio(20)
@ -27,14 +27,16 @@ Popup {
focus: true
onHoveredChanged: {
if (hovered) autoClosePopup.stop()
else autoClosePopup.restart()
if (hovered)
autoClosePopup.stop();
else
autoClosePopup.restart();
}
Timer {
id: autoClosePopup
interval: 5000
onTriggered: {
mainItem.close()
mainItem.close();
}
}
contentItem: RowLayout {

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Layouts
import QtQuick.Controls.Basic
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
Popup {
@ -21,7 +21,7 @@ Popup {
spacing: Utils.getSizeWithScreenRatio(15)
// width: childrenRect.width
// height: childrenRect.height
BusyIndicator{
BusyIndicator {
Layout.alignment: Qt.AlignHCenter
width: Utils.getSizeWithScreenRatio(33)
height: width
@ -42,8 +42,9 @@ Popup {
text: qsTr("cancel")
style: ButtonStyle.main
onClicked: {
if (callback) mainItem.callback()
mainItem.close()
if (callback)
mainItem.callback();
mainItem.close();
}
}
}

View file

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

View file

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Layouts
import Linphone
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
// =============================================================================
@ -21,13 +21,13 @@ Notification {
property var status: call.core.status
property var conference: call.core.conference
onStateChanged:{
if (state != LinphoneEnums.CallState.IncomingReceived){
close()
onStateChanged: {
if (state != LinphoneEnums.CallState.IncomingReceived) {
close();
}
}
onStatusChanged:{
console.log("status", status)
onStatusChanged: {
console.log("status", status);
}
Popup {
@ -38,7 +38,7 @@ Notification {
topPadding: Utils.getSizeWithScreenRatio(9)
bottomPadding: Utils.getSizeWithScreenRatio(18)
anchors.centerIn: parent
background: Item{}
background: Item {}
contentItem: ColumnLayout {
anchors.verticalCenter: parent.verticalCenter
spacing: Utils.getSizeWithScreenRatio(9)
@ -119,9 +119,9 @@ Notification {
textSize: Utils.getSizeWithScreenRatio(14)
textWeight: Utils.getSizeWithScreenRatio(500)
onClicked: {
console.debug("[NotificationReceivedCall] Accept click")
UtilsCpp.openCallsWindow(mainItem.call)
mainItem.call.core.lAccept(false)
console.debug("[NotificationReceivedCall] Accept click");
UtilsCpp.openCallsWindow(mainItem.call);
mainItem.call.core.lAccept(false);
}
}
Button {
@ -137,13 +137,12 @@ Notification {
textSize: Utils.getSizeWithScreenRatio(14)
textWeight: Utils.getSizeWithScreenRatio(500)
onClicked: {
console.debug("[NotificationReceivedCall] Decline click")
mainItem.call.core.lDecline()
console.debug("[NotificationReceivedCall] Decline click");
mainItem.call.core.lDecline();
}
}
}
}
}
}
}

View file

@ -3,7 +3,7 @@ import QtQuick.Layouts
import Linphone
import UtilsCpp
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
// =============================================================================
@ -28,7 +28,7 @@ Notification {
enabled: chat
target: chat ? chat.core : null
function onMessageOpen() {
close()
close();
}
}
@ -69,7 +69,9 @@ Notification {
anchors.rightMargin: Utils.getSizeWithScreenRatio(12)
padding: 0
z: mousearea.z + 1
background: Item{anchors.fill: parent}
background: Item {
anchors.fill: parent
}
icon.source: AppIcons.closeX
width: Utils.getSizeWithScreenRatio(14)
height: Utils.getSizeWithScreenRatio(14)
@ -77,15 +79,15 @@ Notification {
icon.height: Utils.getSizeWithScreenRatio(14)
contentImageColor: DefaultStyle.grey_0
onPressed: {
mainItem.close()
mainItem.close();
}
}
MouseArea {
id: mousearea
anchors.fill: parent
onClicked: {
UtilsCpp.openChat(mainItem.chat)
mainItem.close()
UtilsCpp.openChat(mainItem.chat);
mainItem.close();
}
}
}
@ -139,5 +141,4 @@ Notification {
}
}
}
}

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts as Layout
import QtQuick.Effects
import Linphone
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
Control.Popup {
@ -21,11 +21,11 @@ Control.Popup {
onOpened: numPad.forceActiveFocus()
signal buttonPressed(string text)
signal keyPadKeyPressed(KeyEvent event)
onKeyPadKeyPressed: (event) => {
numPad.handleKeyPadEvent(event)
onKeyPadKeyPressed: event => {
numPad.handleKeyPadEvent(event);
}
signal launchCall()
signal wipe()
signal launchCall
signal wipe
background: Item {
anchors.fill: parent
@ -73,12 +73,12 @@ Control.Popup {
Accessible.name: qsTr("close_numeric_pad_accessible_name")
}
}
contentItem: NumericPad{
contentItem: NumericPad {
id: numPad
lastRowVisible: mainItem.lastRowVisible
currentCall: mainItem.currentCall
onButtonPressed: (text) => {
mainItem.buttonPressed(text)
onButtonPressed: text => {
mainItem.buttonPressed(text);
}
onLaunchCall: mainItem.launchCall()
onWipe: mainItem.wipe()

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,28 +1,29 @@
import QtQuick
MouseArea{
MouseArea {
id: mainItem
property var movableArea: mainItem.Window.contentItem
signal requestResetPosition()
signal requestResetPosition
property bool dragging: drag.active
onDraggingChanged: {
if(dragging){
xClicked = mouseX
yClicked = mouseY
if (dragging) {
xClicked = mouseX;
yClicked = mouseY;
}
}
property real margin: 0
// Position buffer
property int xClicked : 0
property int yClicked : 0
// Scaling buffer
// Position buffer
property int xClicked: 0
property int yClicked: 0
// Scaling buffer
property int heightOrigin
property int widthOrigin
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 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.
cursorShape: dragging ? Qt.DragMoveCursor : undefined
@ -30,51 +31,53 @@ MouseArea{
propagateComposedEvents: true
hoverEnabled: true
function updateScale(){// Avoid scaling if leading outside movableArea.
drag.target.height = Math.max(0, Math.min(movableArea.height, heightOrigin * mScale))
drag.target.width = Math.max(0, Math.min(movableArea.width, widthOrigin * mScale))
updatePosition(0,0)
function updateScale() {// Avoid scaling if leading outside movableArea.
drag.target.height = Math.max(0, Math.min(movableArea.height, heightOrigin * mScale));
drag.target.width = Math.max(0, Math.min(movableArea.width, widthOrigin * mScale));
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 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.y = Math.max(parentTLBounds.y + margin, Math.min(parentBRBounds.y - drag.target.height - margin, drag.target.y + y - margin))
drag.target.x = Math.max(parentTLBounds.x + margin, Math.min(parentBRBounds.x - drag.target.width - 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()
onPositionChanged: (mouse) => {
if(dragging){
updatePosition(mouse.x - xClicked, mouse.y - yClicked)
onPositionChanged: mouse => {
if (dragging) {
updatePosition(mouse.x - xClicked, mouse.y - yClicked);
}
mouse.accepted = false
mouse.accepted = false;
}
onWheel: (wheel) => {
if(!scaled){
scaled = true
heightOrigin = drag.target.height
widthOrigin = drag.target.width
onWheel: wheel => {
if (!scaled) {
scaled = true;
heightOrigin = drag.target.height;
widthOrigin = drag.target.width;
}
var acceleration = 0.01; // Try to make smoother the scaling from wheel
if(startTime == 0){
if (startTime == 0) {
startTime = new Date().getTime();
}else{
} else {
var delay = new Date().getTime() - startTime;
if(delay > 0)
acceleration = Math.max(0.01, Math.min(1, 4/delay));
if (delay > 0)
acceleration = Math.max(0.01, Math.min(1, 4 / delay));
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();
}
onClicked: (mouse) => {
if(mouse.button == Qt.RightButton){
if(scaled) {
scaled = false
mScale = 1.0
}else
requestResetPosition()
onClicked: mouse => {
if (mouse.button == Qt.RightButton) {
if (scaled) {
scaled = false;
mScale = 1.0;
} else
requestResetPosition();
}
mouse.accepted = false
mouse.accepted = false;
}
}

View file

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