mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-19 12:28:08 +00:00
898 lines
28 KiB
QML
898 lines
28 KiB
QML
import QtQuick
|
|
import QtQuick.Effects
|
|
import QtQuick.Layouts
|
|
import QtQuick.Controls.Basic as Control
|
|
import Linphone
|
|
import UtilsCpp
|
|
import SettingsCpp
|
|
|
|
AbstractMainPage {
|
|
id: mainItem
|
|
noItemButtonText: qsTr("Nouvel appel")
|
|
emptyListText: qsTr("Aucun appel")
|
|
newItemIconSource: AppIcons.newCall
|
|
|
|
property var selectedRowHistoryGui
|
|
signal listViewUpdated()
|
|
|
|
onVisibleChanged: if (!visible) {
|
|
goToCallHistory()
|
|
}
|
|
|
|
//Group call properties
|
|
property ConferenceInfoGui confInfoGui
|
|
property AccountProxy accounts: AccountProxy {
|
|
id: accountProxy
|
|
sourceModel: AppCpp.accounts
|
|
}
|
|
property AccountGui account: accountProxy.defaultAccount
|
|
property var state: account && account.core?.registrationState || 0
|
|
property bool isRegistered: account ? account.core?.registrationState == LinphoneEnums.RegistrationState.Ok : false
|
|
property int selectedParticipantsCount
|
|
signal startGroupCallRequested()
|
|
signal createCallFromSearchBarRequested()
|
|
signal createContactRequested(string name, string address)
|
|
signal openNumPadRequest()
|
|
|
|
Connections {
|
|
enabled: confInfoGui
|
|
target: confInfoGui ? confInfoGui.core : null
|
|
function onConferenceSchedulerStateChanged() {
|
|
if (confInfoGui.core.schedulerState === LinphoneEnums.ConferenceSchedulerState.Ready) {
|
|
listStackView.pop()
|
|
}
|
|
}
|
|
}
|
|
|
|
onSelectedRowHistoryGuiChanged: {
|
|
if (selectedRowHistoryGui) rightPanelStackView.replace(contactDetailComp, Control.StackView.Immediate)
|
|
else rightPanelStackView.replace(emptySelection, Control.StackView.Immediate)
|
|
}
|
|
rightPanelStackView.initialItem: emptySelection
|
|
rightPanelStackView.width: 360 * DefaultStyle.dp
|
|
|
|
onNoItemButtonPressed: goToNewCall()
|
|
|
|
showDefaultItem: listStackView.currentItem && listStackView.currentItem.listView && listStackView.currentItem.listView.count === 0 && listStackView.currentItem.listView.model.sourceModel.count === 0 || false
|
|
|
|
function goToNewCall() {
|
|
if (listStackView.currentItem && listStackView.currentItem.objectName != "newCallItem") listStackView.push(newCallItem)
|
|
}
|
|
function goToCallHistory() {
|
|
if (listStackView.currentItem && listStackView.currentItem.objectName != "historyListItem") listStackView.replace(historyListItem)
|
|
}
|
|
|
|
Dialog {
|
|
id: deleteHistoryPopup
|
|
width: 278 * DefaultStyle.dp
|
|
text: qsTr("L'historique d'appel sera supprimé. Souhaitez-vous continuer ?")
|
|
}
|
|
Dialog {
|
|
id: deleteForUserPopup
|
|
width: 278 * DefaultStyle.dp
|
|
text: qsTr("L'historique d'appel de l'utilisateur sera supprimé. Souhaitez-vous continuer ?")
|
|
}
|
|
|
|
leftPanelContent: Item {
|
|
id: leftPanel
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
Loader {
|
|
id: titleLoader
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
asynchronous: false
|
|
onActiveFocusChanged:{
|
|
if(activeFocus && item){
|
|
item.forceActiveFocus()
|
|
}
|
|
}
|
|
}
|
|
|
|
Control.StackView {
|
|
id: listStackView
|
|
anchors.top: titleLoader.bottom
|
|
anchors.topMargin: 18 * DefaultStyle.dp
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: 45 * DefaultStyle.dp
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
clip: true
|
|
initialItem: historyListItem
|
|
focus: true
|
|
onActiveFocusChanged: if(activeFocus){
|
|
currentItem.forceActiveFocus()
|
|
}
|
|
}
|
|
|
|
Item {
|
|
anchors.bottom: parent.bottom
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
height: 402 * DefaultStyle.dp
|
|
NumericPadPopup {
|
|
id: numericPadPopup
|
|
width: parent.width
|
|
height: parent.height
|
|
visible: false
|
|
onLaunchCall: {
|
|
mainItem.createCallFromSearchBarRequested()
|
|
// TODO : auto completion instead of sip linphone
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: historyListTitle
|
|
FocusScope{
|
|
objectName: "historyListTitle"
|
|
width: parent.width
|
|
height: titleCallLayout.implicitHeight
|
|
RowLayout {
|
|
id: titleCallLayout
|
|
anchors.fill: parent
|
|
spacing: 16 * DefaultStyle.dp
|
|
Text {
|
|
text: qsTr("Appels")
|
|
Layout.leftMargin: 45 * DefaultStyle.dp
|
|
color: DefaultStyle.main2_700
|
|
font.pixelSize: 29 * DefaultStyle.dp
|
|
font.weight: 800 * DefaultStyle.dp
|
|
}
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
PopupButton {
|
|
id: removeHistory
|
|
width: 24 * DefaultStyle.dp
|
|
height: 24 * DefaultStyle.dp
|
|
focus: true
|
|
popup.x: 0
|
|
popup.padding: 20 * DefaultStyle.dp
|
|
KeyNavigation.right: newCallButton
|
|
KeyNavigation.down: listStackView
|
|
popup.contentItem: ColumnLayout {
|
|
IconLabelButton {
|
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
|
Layout.fillWidth: true
|
|
focus: visible
|
|
iconSize: 24 * DefaultStyle.dp
|
|
text: qsTr("Supprimer l'historique")
|
|
iconSource: AppIcons.trashCan
|
|
color: DefaultStyle.danger_500main
|
|
onClicked: {
|
|
removeHistory.close()
|
|
deleteHistoryPopup.open()
|
|
}
|
|
}
|
|
}
|
|
Connections {
|
|
target: deleteHistoryPopup
|
|
onAccepted: {
|
|
if (listStackView.currentItem.listView) listStackView.currentItem.listView.model.removeAllEntries()
|
|
}
|
|
}
|
|
}
|
|
Button {
|
|
id: newCallButton
|
|
background: Item {}
|
|
icon.source: AppIcons.newCall
|
|
Layout.preferredWidth: 28 * DefaultStyle.dp
|
|
Layout.preferredHeight: 28 * DefaultStyle.dp
|
|
Layout.rightMargin: 39 * DefaultStyle.dp
|
|
icon.width: 28 * DefaultStyle.dp
|
|
icon.height: 28 * DefaultStyle.dp
|
|
KeyNavigation.left: removeHistory
|
|
KeyNavigation.down: listStackView
|
|
onClicked: {
|
|
console.debug("[CallPage]User: create new call")
|
|
listStackView.push(newCallItem)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: historyListItem
|
|
FocusScope{
|
|
objectName: "historyListItem"
|
|
Control.StackView.onActivated: titleLoader.sourceComponent = historyListTitle
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
SearchBar {
|
|
id: searchBar
|
|
Layout.fillWidth: true
|
|
Layout.rightMargin: 39 * DefaultStyle.dp
|
|
placeholderText: qsTr("Rechercher un appel")
|
|
focus: true
|
|
KeyNavigation.up: titleLoader
|
|
KeyNavigation.down: historyListView
|
|
}
|
|
Item {
|
|
Layout.topMargin: 38 * DefaultStyle.dp
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
Control.Control {
|
|
id: listLayout
|
|
anchors.fill: parent
|
|
anchors.rightMargin: 39 * DefaultStyle.dp
|
|
|
|
background: Item{}
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
ColumnLayout {
|
|
Text {
|
|
visible: historyListView.count === 0
|
|
Layout.alignment: Qt.AlignHCenter
|
|
text: qsTr("Aucun appel")
|
|
font {
|
|
pixelSize: 16 * DefaultStyle.dp
|
|
weight: 800 * DefaultStyle.dp
|
|
}
|
|
Binding on text {
|
|
when: searchBar.text.length !== 0
|
|
value: qsTr("Aucun appel correspondant")
|
|
}
|
|
}
|
|
ListView {
|
|
id: historyListView
|
|
clip: true
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
model: CallHistoryProxy {
|
|
id: callHistoryProxy
|
|
filterText: searchBar.text
|
|
onFilterTextChanged: maxDisplayItems = initialDisplayItems
|
|
initialDisplayItems: historyListView.height / (56 * DefaultStyle.dp) + 5
|
|
displayItemsStep: initialDisplayItems / 2
|
|
}
|
|
cacheBuffer: contentHeight>0 ? contentHeight : 0// cache all items
|
|
flickDeceleration: 10000
|
|
spacing: 10 * DefaultStyle.dp
|
|
highlightFollowsCurrentItem: true
|
|
preferredHighlightBegin: height/2 - 10
|
|
preferredHighlightEnd: height/2 + 10
|
|
highlightRangeMode: ListView.ApplyRange
|
|
Keys.onPressed: (event) => {
|
|
if(event.key == Qt.Key_Escape){
|
|
console.log("Back")
|
|
searchBar.forceActiveFocus()
|
|
event.accepted = true
|
|
}
|
|
}
|
|
onActiveFocusChanged: if(activeFocus && currentIndex <0) currentIndex = 0
|
|
|
|
Connections {
|
|
target: deleteHistoryPopup
|
|
function onAccepted() {
|
|
historyListView.model.removeAllEntries()
|
|
}
|
|
}
|
|
onAtYEndChanged: if(atYEnd) callHistoryProxy.displayMore()
|
|
delegate: FocusScope {
|
|
width:historyListView.width
|
|
height: 56 * DefaultStyle.dp
|
|
anchors.topMargin: 5 * DefaultStyle.dp
|
|
anchors.bottomMargin: 5 * DefaultStyle.dp
|
|
visible: !!modelData
|
|
RowLayout {
|
|
z: 1
|
|
anchors.fill: parent
|
|
spacing: 10 * DefaultStyle.dp
|
|
Avatar {
|
|
id: historyAvatar
|
|
property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress)
|
|
contact: contactObj && contactObj.value || null
|
|
_address: modelData.core.remoteAddress
|
|
width: 45 * DefaultStyle.dp
|
|
height: 45 * DefaultStyle.dp
|
|
}
|
|
ColumnLayout {
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
spacing: 5 * DefaultStyle.dp
|
|
Text {
|
|
id: friendAddress
|
|
Layout.fillWidth: true
|
|
maximumLineCount: 1
|
|
text: modelData.core.displayName
|
|
font {
|
|
pixelSize: 14 * DefaultStyle.dp
|
|
weight: 400 * DefaultStyle.dp
|
|
capitalization: Font.Capitalize
|
|
}
|
|
}
|
|
RowLayout {
|
|
spacing: 6 * DefaultStyle.dp
|
|
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_500main
|
|
: modelData.core.isOutgoing
|
|
? DefaultStyle.info_500_main
|
|
: DefaultStyle.success_500main
|
|
Layout.preferredWidth: 12 * DefaultStyle.dp
|
|
Layout.preferredHeight: 12 * DefaultStyle.dp
|
|
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 === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
|
|
origin {
|
|
x: statusIcon.width/2
|
|
y: statusIcon.height/2
|
|
}
|
|
}
|
|
}
|
|
Text {
|
|
// text: modelData.core.date
|
|
text: UtilsCpp.formatDate(modelData.core.date)
|
|
font {
|
|
pixelSize: 12 * DefaultStyle.dp
|
|
weight: 300 * DefaultStyle.dp
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Button {
|
|
Layout.rightMargin: 5 * DefaultStyle.dp
|
|
padding: 0
|
|
background: Item {
|
|
visible: false
|
|
}
|
|
icon.source: AppIcons.phone
|
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
|
icon.width: 24 * DefaultStyle.dp
|
|
icon.height: 24 * DefaultStyle.dp
|
|
focus: true
|
|
activeFocusOnTab: false
|
|
onClicked: {
|
|
if (modelData.core.isConference) {
|
|
var callsWindow = UtilsCpp.getCallsWindow()
|
|
callsWindow.setupConference(modelData.core.conferenceInfo)
|
|
callsWindow.show()
|
|
}
|
|
else {
|
|
UtilsCpp.createCall(modelData.core.remoteAddress)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
MouseArea {
|
|
hoverEnabled: true
|
|
anchors.fill: parent
|
|
focus: true
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
opacity: 0.1
|
|
color: DefaultStyle.main2_500main
|
|
visible: parent.containsMouse
|
|
}
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
visible: historyListView.currentIndex === model.index
|
|
color: DefaultStyle.main2_100
|
|
}
|
|
onPressed: {
|
|
historyListView.currentIndex = model.index
|
|
historyListView.forceActiveFocus()
|
|
}
|
|
}
|
|
}
|
|
//}
|
|
//}
|
|
onCurrentIndexChanged: {
|
|
positionViewAtIndex(currentIndex, ListView.Visible)
|
|
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
|
|
}
|
|
onCountChanged: {
|
|
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
|
|
}
|
|
onVisibleChanged: {
|
|
if (!visible) currentIndex = -1
|
|
}
|
|
Control.ScrollBar.vertical: scrollbar
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ScrollBar {
|
|
id: scrollbar
|
|
anchors.top: parent.top
|
|
anchors.bottom: parent.bottom
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: 8 * DefaultStyle.dp
|
|
active: true
|
|
policy: Control.ScrollBar.AsNeeded
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: newCallTitle
|
|
FocusScope{
|
|
objectName: "newCallTitle"
|
|
width: parent.width
|
|
height: parent.height
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
Button {
|
|
Layout.leftMargin: 45 * DefaultStyle.dp
|
|
background: Item {
|
|
}
|
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
|
icon.source: AppIcons.leftArrow
|
|
icon.width: 24 * DefaultStyle.dp
|
|
icon.height: 24 * DefaultStyle.dp
|
|
focus: true
|
|
KeyNavigation.down: listStackView
|
|
onClicked: {
|
|
console.debug("[CallPage]User: return to call history")
|
|
listStackView.pop()
|
|
listStackView.forceActiveFocus()
|
|
}
|
|
}
|
|
Text {
|
|
text: qsTr("Nouvel appel")
|
|
color: DefaultStyle.main2_700
|
|
font.pixelSize: 29 * DefaultStyle.dp
|
|
font.weight: 800 * DefaultStyle.dp
|
|
}
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: newCallItem
|
|
FocusScope{
|
|
objectName: "newCallItem"
|
|
width: parent?.width
|
|
height: parent?.height
|
|
Control.StackView.onActivated:{
|
|
titleLoader.sourceComponent = newCallTitle
|
|
callContactsList.forceActiveFocus()
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
NewCallForm {
|
|
id: callContactsList
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
focus: true
|
|
numPadPopup: numericPadPopup
|
|
groupCallVisible: true
|
|
searchBarColor: DefaultStyle.grey_100
|
|
onContactClicked: (contact) => {
|
|
mainWindow.startCallWithContact(contact, false, callContactsList)
|
|
}
|
|
onGroupCallCreationRequested: {
|
|
console.log("groupe call requetsed")
|
|
listStackView.push(groupCallItem)
|
|
}
|
|
Connections {
|
|
target: mainItem
|
|
function onCreateCallFromSearchBarRequested(){ UtilsCpp.createCall(callContactsList.searchBar.text)}
|
|
function onOpenNumPadRequest(){ if (!callContactsList.searchBar.numericPadButton.checked) callContactsList.searchBar.numericPadButton.checked = true}
|
|
}
|
|
Binding {
|
|
target: numericPadPopup
|
|
property: "visible"
|
|
value: true
|
|
when: callContactsList.searchBar.numericPadButton.checked
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: groupCallTitle
|
|
FocusScope{
|
|
objectName: "groupCallTitle"
|
|
width: parent.width
|
|
height: parent.height
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 10 * DefaultStyle.dp
|
|
visible: !SettingsCpp.disableMeetingsFeature
|
|
Button {
|
|
id: backGroupCallButton
|
|
background: Item{}
|
|
icon.source: AppIcons.leftArrow
|
|
contentImageColor: DefaultStyle.main1_500_main
|
|
Layout.leftMargin: 21 * DefaultStyle.dp
|
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
|
icon.width: 24 * DefaultStyle.dp
|
|
icon.height: 24 * DefaultStyle.dp
|
|
KeyNavigation.down: listStackView
|
|
KeyNavigation.right: groupCallButton
|
|
KeyNavigation.left: groupCallButton
|
|
onClicked: {
|
|
listStackView.pop()
|
|
titleLoader.item.forceActiveFocus()
|
|
}
|
|
}
|
|
ColumnLayout {
|
|
spacing: 3 * DefaultStyle.dp
|
|
Text {
|
|
text: qsTr("Appel de groupe")
|
|
color: DefaultStyle.main1_500_main
|
|
maximumLineCount: 1
|
|
font {
|
|
pixelSize: 18 * DefaultStyle.dp
|
|
weight: 800 * DefaultStyle.dp
|
|
}
|
|
Layout.fillWidth: true
|
|
}
|
|
Text {
|
|
text: qsTr("%1 participant%2 sélectionné").arg(mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount > 1 ? "s" : "")
|
|
color: DefaultStyle.main2_500main
|
|
maximumLineCount: 1
|
|
font {
|
|
pixelSize: 12 * DefaultStyle.dp
|
|
weight: 300 * DefaultStyle.dp
|
|
}
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
Button {
|
|
id: groupCallButton
|
|
enabled: mainItem.selectedParticipantsCount.length != 0
|
|
Layout.rightMargin: 21 * DefaultStyle.dp
|
|
topPadding: 6 * DefaultStyle.dp
|
|
bottomPadding: 6 * DefaultStyle.dp
|
|
leftPadding: 12 * DefaultStyle.dp
|
|
rightPadding: 12 * DefaultStyle.dp
|
|
text: qsTr("Lancer")
|
|
textSize: 13 * DefaultStyle.dp
|
|
KeyNavigation.down: listStackView
|
|
KeyNavigation.left: backGroupCallButton
|
|
KeyNavigation.right: backGroupCallButton
|
|
onClicked: {
|
|
mainItem.startGroupCallRequested()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: groupCallItem
|
|
FocusScope{
|
|
objectName: "groupCallItem"
|
|
Control.StackView.onActivated: {
|
|
titleLoader.sourceComponent = groupCallTitle
|
|
addParticipantsLayout.forceActiveFocus()
|
|
}
|
|
ColumnLayout {
|
|
spacing: 5 * DefaultStyle.dp
|
|
anchors.fill: parent
|
|
RowLayout {
|
|
spacing: 0
|
|
Layout.rightMargin: 38 * DefaultStyle.dp
|
|
Text {
|
|
font.pixelSize: 13 * DefaultStyle.dp
|
|
font.weight: 700 * DefaultStyle.dp
|
|
text: qsTr("Nom du groupe")
|
|
}
|
|
Item{Layout.fillWidth: true}
|
|
Text {
|
|
font.pixelSize: 12 * DefaultStyle.dp
|
|
font.weight: 300 * DefaultStyle.dp
|
|
text: qsTr("Requis")
|
|
}
|
|
}
|
|
TextField {
|
|
id: groupCallName
|
|
Layout.fillWidth: true
|
|
Layout.rightMargin: 38 * DefaultStyle.dp
|
|
Layout.preferredHeight: 49 * DefaultStyle.dp
|
|
focus: true
|
|
KeyNavigation.down: addParticipantsLayout//participantList.count > 0 ? participantList : searchbar
|
|
}
|
|
AddParticipantsForm {
|
|
id: addParticipantsLayout
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
|
|
focus: true
|
|
Connections {
|
|
target: mainItem
|
|
function onStartGroupCallRequested() {
|
|
if (groupCallName.text.length === 0) {
|
|
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Un nom doit être donné à l'appel de groupe"), false)
|
|
} else if(!mainItem.isRegistered) {
|
|
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Vous n'etes pas connecté"), false)
|
|
} else {
|
|
mainItem.confInfoGui = Qt.createQmlObject('import Linphone
|
|
ConferenceInfoGui{
|
|
}', mainItem)
|
|
mainItem.confInfoGui.core.subject = groupCallName.text
|
|
mainItem.confInfoGui.core.isScheduled = false
|
|
mainItem.confInfoGui.core.addParticipants(addParticipantsLayout.selectedParticipants)
|
|
mainItem.confInfoGui.core.save()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component{
|
|
id: emptySelection
|
|
Item{objectName: "emptySelection"}
|
|
}
|
|
Component {
|
|
id: contactDetailComp
|
|
FocusScope{
|
|
objectName: "contactDetailComp"
|
|
width: parent?.width
|
|
height: parent?.height
|
|
ContactLayout {
|
|
id: contactDetail
|
|
anchors.fill: parent
|
|
anchors.topMargin: 45 * DefaultStyle.dp
|
|
anchors.bottomMargin: 45 * DefaultStyle.dp
|
|
visible: mainItem.selectedRowHistoryGui != undefined
|
|
property var contactObj: UtilsCpp.findFriendByAddress(contactAddress)
|
|
contact: contactObj && contactObj.value || null
|
|
conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null
|
|
specificAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || ""
|
|
|
|
buttonContent: PopupButton {
|
|
id: detailOptions
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: 30 * DefaultStyle.dp
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
popup.x: width
|
|
property var friendGuiObj: UtilsCpp.findFriendByAddress(contactDetail.contactAddress)
|
|
property var friendGui: friendGuiObj ? friendGuiObj.value : null
|
|
popup.contentItem: FocusScope {
|
|
implicitHeight: detailsButtons.implicitHeight
|
|
implicitWidth: detailsButtons.implicitWidth
|
|
Keys.onPressed: (event)=> {
|
|
if (event.key == Qt.Key_Left || event.key == Qt.Key_Escape) {
|
|
detailOptions.popup.close()
|
|
event.accepted = true;
|
|
}
|
|
}
|
|
ColumnLayout {
|
|
id: detailsButtons
|
|
anchors.fill: parent
|
|
Button {
|
|
text: detailOptions.friendGui ? qsTr("Voir le contact") : qsTr("Ajouter aux contacts")
|
|
icon.source: AppIcons.plusCircle
|
|
icon.width: 24 * DefaultStyle.dp
|
|
icon.height: 24 * DefaultStyle.dp
|
|
spacing: 10 * DefaultStyle.dp
|
|
textSize: 14 * DefaultStyle.dp
|
|
textWeight: 400 * DefaultStyle.dp
|
|
textColor: DefaultStyle.main2_500main
|
|
contentImageColor: DefaultStyle.main2_600
|
|
background: Item {}
|
|
onClicked: {
|
|
detailOptions.close()
|
|
if (detailOptions.friendGui) mainWindow.displayContactPage(contactDetail.contactAddress)
|
|
else mainItem.createContactRequested(contactDetail.contactName, contactDetail.contactAddress)
|
|
}
|
|
}
|
|
Button {
|
|
text: qsTr("Copier l'adresse SIP")
|
|
icon.source: AppIcons.copy
|
|
icon.width: 24 * DefaultStyle.dp
|
|
icon.height: 24 * DefaultStyle.dp
|
|
spacing: 10 * DefaultStyle.dp
|
|
textSize: 14 * DefaultStyle.dp
|
|
textWeight: 400 * DefaultStyle.dp
|
|
textColor: DefaultStyle.main2_500main
|
|
contentImageColor: DefaultStyle.main2_600
|
|
background: Item {}
|
|
|
|
onClicked: {
|
|
detailOptions.close()
|
|
var success = UtilsCpp.copyToClipboard(mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress)
|
|
if (success) UtilsCpp.showInformationPopup(qsTr("Copié"), qsTr("L'adresse a été copiée dans le presse-papier"), true)
|
|
else UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Erreur lors de la copie de l'adresse"), false)
|
|
}
|
|
}
|
|
// Button {
|
|
// background: Item {}
|
|
// enabled: false
|
|
// contentItem: IconLabel {
|
|
// text: qsTr("Bloquer")
|
|
// iconSource: AppIcons.empty
|
|
// }
|
|
// onClicked: console.debug("[CallPage.qml] TODO : block user")
|
|
// }
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 2 * DefaultStyle.dp
|
|
color: DefaultStyle.main2_400
|
|
}
|
|
|
|
Button {
|
|
text: qsTr("Supprimer l'historique")
|
|
icon.source: AppIcons.trashCan
|
|
icon.width: 24 * DefaultStyle.dp
|
|
icon.height: 24 * DefaultStyle.dp
|
|
spacing: 10 * DefaultStyle.dp
|
|
textSize: 14 * DefaultStyle.dp
|
|
textWeight: 400 * DefaultStyle.dp
|
|
textColor: DefaultStyle.danger_500main
|
|
contentImageColor: DefaultStyle.danger_500main
|
|
background: Item {}
|
|
|
|
Connections {
|
|
target: deleteForUserPopup
|
|
function onAccepted() {
|
|
detailListView.model.removeEntriesWithFilter()
|
|
mainItem.listViewUpdated()
|
|
}
|
|
}
|
|
onClicked: {
|
|
detailOptions.close()
|
|
deleteForUserPopup.open()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
detailContent: RoundedPane {
|
|
id: detailControl
|
|
Layout.preferredWidth: 360 * DefaultStyle.dp
|
|
implicitHeight: 430 * DefaultStyle.dp + topPadding + bottomPadding
|
|
|
|
background: Rectangle {
|
|
id: detailListBackground
|
|
width: parent.width
|
|
height: detailListView.height
|
|
color: DefaultStyle.grey_0
|
|
radius: 15 * DefaultStyle.dp
|
|
}
|
|
|
|
ListView {
|
|
id: detailListView
|
|
width: parent.width
|
|
height: Math.min(detailControl.implicitHeight, contentHeight)
|
|
|
|
spacing: 20 * DefaultStyle.dp
|
|
clip: true
|
|
|
|
model: CallHistoryProxy {
|
|
id: detailsHistoryProxy
|
|
filterText: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : ""
|
|
onFilterTextChanged: maxDisplayItems = initialDisplayItems
|
|
initialDisplayItems: detailListView.height / (56 * DefaultStyle.dp) + 5
|
|
displayItemsStep: initialDisplayItems / 2
|
|
}
|
|
onAtYEndChanged: if(atYEnd) detailsHistoryProxy.displayMore()
|
|
delegate: Item {
|
|
width:detailListView.width
|
|
height: 56 * DefaultStyle.dp
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
anchors.leftMargin: 20 * DefaultStyle.dp
|
|
anchors.rightMargin: 20 * DefaultStyle.dp
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
ColumnLayout {
|
|
Layout.alignment: Qt.AlignVCenter
|
|
RowLayout {
|
|
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_500main
|
|
: modelData.core.isOutgoing
|
|
? DefaultStyle.info_500_main
|
|
: DefaultStyle.success_500main
|
|
Layout.preferredWidth: 16 * DefaultStyle.dp
|
|
Layout.preferredHeight: 16 * DefaultStyle.dp
|
|
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 === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
|
|
origin {
|
|
x: statusIcon.width/2
|
|
y: statusIcon.height/2
|
|
}
|
|
}
|
|
}
|
|
Text {
|
|
text: modelData.core.status === LinphoneEnums.CallStatus.Missed
|
|
? qsTr("Appel manqué")
|
|
: modelData.core.isOutgoing
|
|
? qsTr("Appel sortant")
|
|
: qsTr("Appel entrant")
|
|
font {
|
|
pixelSize: 14 * DefaultStyle.dp
|
|
weight: 400 * DefaultStyle.dp
|
|
}
|
|
}
|
|
}
|
|
Text {
|
|
text: UtilsCpp.formatDate(modelData.core.date)
|
|
color: modelData.core.status === LinphoneEnums.CallStatus.Missed? DefaultStyle.danger_500main : DefaultStyle.main2_500main
|
|
font {
|
|
pixelSize: 12 * DefaultStyle.dp
|
|
weight: 300 * DefaultStyle.dp
|
|
}
|
|
}
|
|
}
|
|
Item {
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
}
|
|
Text {
|
|
text: UtilsCpp.formatElapsedTime(modelData.core.duration, false)
|
|
font {
|
|
pixelSize: 12 * DefaultStyle.dp
|
|
weight: 300 * DefaultStyle.dp
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Item{
|
|
Layout.fillHeight: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component IconLabel: RowLayout {
|
|
id: iconLabel
|
|
property string text
|
|
property string iconSource
|
|
property color colorizationColor: DefaultStyle.main2_500main
|
|
EffectImage {
|
|
imageSource: iconLabel.iconSource
|
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
|
fillMode: Image.PreserveAspectFit
|
|
colorizationColor: iconLabel.colorizationColor
|
|
}
|
|
Text {
|
|
text: iconLabel.text
|
|
color: iconLabel.colorizationColor
|
|
font {
|
|
pixelSize: 14 * DefaultStyle.dp
|
|
weight: 400 * DefaultStyle.dp
|
|
}
|
|
}
|
|
}
|
|
}
|