To enable it in a commercial projet, please contact us.
" } Button { + Layout.alignment: Qt.AlignCenter Layout.topMargin: 18 * DefaultStyle.dp text: "linphone.org/contact" textSize: 13 * DefaultStyle.dp @@ -109,7 +110,7 @@ LoginLayout { } Button { Layout.topMargin: 85 * DefaultStyle.dp - Layout.preferredWidth: 360 * DefaultStyle.dp + Layout.fillWidth: true inversedColors: true text: qsTr("I prefer creating an account") leftPadding: 20 * DefaultStyle.dp @@ -123,7 +124,7 @@ LoginLayout { } Button { Layout.topMargin: 20 * DefaultStyle.dp - Layout.preferredWidth: 360 * DefaultStyle.dp + Layout.fillWidth: true text: qsTr("I understand") leftPadding: 20 * DefaultStyle.dp rightPadding: 20 * DefaultStyle.dp @@ -229,7 +230,6 @@ LoginLayout { anchors.topMargin: 70 * DefaultStyle.dp anchors.leftMargin: 127 * DefaultStyle.dp width: 361 * DefaultStyle.dp - clip: true }, Image { z: -1 diff --git a/Linphone/view/Page/Main/AbstractMainPage.qml b/Linphone/view/Page/Main/AbstractMainPage.qml index e2a720c50..104410a16 100644 --- a/Linphone/view/Page/Main/AbstractMainPage.qml +++ b/Linphone/view/Page/Main/AbstractMainPage.qml @@ -9,7 +9,7 @@ import QtQuick.Controls as Control import Linphone import UtilsCpp -Item { +FocusScope { id: mainItem property string noItemButtonText property string newItemIconSource @@ -209,6 +209,8 @@ Item { } Control.StackView { id: rightPanelStackView + Layout.fillWidth: true + Layout.fillHeight: true } } } diff --git a/Linphone/view/Page/Main/AbstractMasterDetailPage.qml b/Linphone/view/Page/Main/AbstractMasterDetailPage.qml index 2866940d1..4033f09c2 100644 --- a/Linphone/view/Page/Main/AbstractMasterDetailPage.qml +++ b/Linphone/view/Page/Main/AbstractMasterDetailPage.qml @@ -33,17 +33,19 @@ AbstractMainPage { Layout.rightMargin: leftPanel.sideMargin spacing: 5 * DefaultStyle.dp Button { + id: backButton Layout.preferredHeight: 24 * DefaultStyle.dp Layout.preferredWidth: 24 * DefaultStyle.dp icon.source: AppIcons.leftArrow width: 24 * DefaultStyle.dp height: 24 * DefaultStyle.dp - background: Item { - anchors.fill: parent - } + focus: true onClicked: { mainItem.goBack() } + background: Item { + anchors.fill: parent + } } Text { text: titleText @@ -63,11 +65,13 @@ AbstractMainPage { Layout.topMargin: 41 * DefaultStyle.dp Layout.leftMargin: leftPanel.sideMargin property int selectedIndex: 0 + activeFocusOnTab: true delegate: MasterDetailFamily { titleText: modelData.title visible: modelData.visible != undefined ? modelData.visible : true isSelected: familiesList.selectedIndex == index + focus: index == 0 onSelected: { familiesList.selectedIndex = index rightPanelStackView.clear() @@ -78,6 +82,8 @@ AbstractMainPage { Component.onCompleted: { let initialEntry = mainItem.families[familiesList.selectedIndex] rightPanelStackView.push(layoutUrl(initialEntry.layout), { titleText: initialEntry.title, model: initialEntry.model, container: rightPanelStackView}) + familiesList.currentIndex = familiesList.selectedIndex + backButton.forceActiveFocus() } } } diff --git a/Linphone/view/Page/Main/CallPage.qml b/Linphone/view/Page/Main/CallPage.qml index a4eab2c80..3057f70bc 100644 --- a/Linphone/view/Page/Main/CallPage.qml +++ b/Linphone/view/Page/Main/CallPage.qml @@ -69,23 +69,32 @@ AbstractMainPage { 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 - clip: true - initialItem: historyListItem 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 { @@ -107,42 +116,53 @@ AbstractMainPage { Component { id: historyListTitle - RowLayout { - 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 - popup.x: 0 - popup.padding: 10 * DefaultStyle.dp - popup.contentItem: Button { - background: Item{} - contentItem: RowLayout { - EffectImage { - imageSource: AppIcons.trashCan - width: 24 * DefaultStyle.dp - height: 24 * DefaultStyle.dp - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - fillMode: Image.PreserveAspectFit - colorizationColor: DefaultStyle.danger_500main - } - Text { - text: qsTr("Supprimer l’historique") - color: DefaultStyle.danger_500main - font { - pixelSize: 14 * DefaultStyle.dp - weight: 400 * DefaultStyle.dp + FocusScope{ + 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: 10 * DefaultStyle.dp + KeyNavigation.right: newCallButton + KeyNavigation.down: listStackView + popup.contentItem: Button { + color: removeHistory.popupBackgroundColor + borderColor: removeHistory.popupBackgroundColor + inversedColors: true + contentItem: RowLayout { + EffectImage { + imageSource: AppIcons.trashCan + width: 24 * DefaultStyle.dp + height: 24 * DefaultStyle.dp + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + fillMode: Image.PreserveAspectFit + colorizationColor: DefaultStyle.danger_500main + } + Text { + text: qsTr("Supprimer l’historique") + color: DefaultStyle.danger_500main + font { + pixelSize: 14 * DefaultStyle.dp + weight: 400 * DefaultStyle.dp + } } } } @@ -151,235 +171,262 @@ AbstractMainPage { deleteHistoryPopup.open() } } - } - Button { - 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 - onClicked: { - console.debug("[CallPage]User: create new call") - listStackView.push(newCallItem) + 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 - ColumnLayout { + FocusScope{ + width: parent.width + height: parent.height Control.StackView.onActivated: titleLoader.sourceComponent = historyListTitle - property alias listView: historyListView - SearchBar { - id: searchBar - Layout.fillWidth: true - Layout.rightMargin: 39 * DefaultStyle.dp - placeholderText: qsTr("Rechercher un appel") - } - 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 { + 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 { - Text { - text: qsTr("Aucun appel") - font { - pixelSize: 16 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - visible: historyListView.count === 0 - Layout.alignment: Qt.AlignHCenter - Binding on text { - when: searchBar.text.length !== 0 - value: qsTr("Aucun appel correspondant") - restoreMode: Binding.RestoreBindingOrValue - } - } - ListView { - id: historyListView - clip: true - Layout.fillWidth: true - Layout.fillHeight: true - model: CallHistoryProxy { - filterText: searchBar.text - } - - currentIndex: -1 - flickDeceleration: 10000 - spacing: 10 * DefaultStyle.dp - - Connections { - target: deleteHistoryPopup - function onAccepted() { - historyListView.model.removeAllEntries() + 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") + restoreMode: Binding.RestoreBindingOrValue } } - - delegate: Item { - width:historyListView.width - height: 56 * DefaultStyle.dp - anchors.topMargin: 5 * DefaultStyle.dp - anchors.bottomMargin: 5 * DefaultStyle.dp - RowLayout { - z: 1 - anchors.fill: parent - Item { - Layout.preferredWidth: historyAvatar.width - Layout.preferredHeight: historyAvatar.height - Layout.leftMargin: 5 * DefaultStyle.dp - MultiEffect { - source: historyAvatar - anchors.fill: historyAvatar - shadowEnabled: true - shadowBlur: 1 - shadowColor: DefaultStyle.grey_900 - shadowOpacity: 0.1 - } - Avatar { - id: historyAvatar - address: modelData.core.remoteAddress - width: 45 * DefaultStyle.dp - height: 45 * DefaultStyle.dp - } + ListView { + id: historyListView + clip: true + Layout.fillWidth: true + Layout.fillHeight: true + model: CallHistoryProxy { + filterText: searchBar.text + } + + currentIndex: -1 + 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 } - 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 + } + onActiveFocusChanged: if(activeFocus && currentIndex <0) currentIndex = 0 + + Connections { + target: deleteHistoryPopup + function onAccepted() { + historyListView.model.removeAllEntries() + } + } + + delegate: FocusScope { + width:historyListView.width + height: 56 * DefaultStyle.dp + anchors.topMargin: 5 * DefaultStyle.dp + anchors.bottomMargin: 5 * DefaultStyle.dp + RowLayout { + z: 1 + anchors.fill: parent + Item { + Layout.preferredWidth: historyAvatar.width + Layout.preferredHeight: historyAvatar.height + Layout.leftMargin: 5 * DefaultStyle.dp + MultiEffect { + source: historyAvatar + anchors.fill: historyAvatar + shadowEnabled: true + shadowBlur: 1 + shadowColor: DefaultStyle.grey_900 + shadowOpacity: 0.1 + } + Avatar { + id: historyAvatar + address: modelData.core.remoteAddress + width: 45 * DefaultStyle.dp + height: 45 * DefaultStyle.dp } } - RowLayout { - spacing: 3 * 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 + 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 + } + } + RowLayout { + spacing: 3 * 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.formatDateElapsedTime(modelData.core.date) + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp } } } - Text { - // text: modelData.core.date - text: UtilsCpp.formatDateElapsedTime(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) } } } } - Button { - Layout.rightMargin: 5 * DefaultStyle.dp - padding: 0 - background: Item { - visible: false + MouseArea { + hoverEnabled: true + anchors.fill: parent + focus: true + Rectangle { + anchors.fill: parent + opacity: 0.1 + color: DefaultStyle.main2_500main + visible: parent.containsMouse } - icon.source: AppIcons.phone - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - onClicked: { - if (modelData.core.isConference) { - var callsWindow = UtilsCpp.getCallsWindow() - callsWindow.setupConference(modelData.core.conferenceInfo) - callsWindow.show() - } - else { - UtilsCpp.createCall(modelData.core.remoteAddress) - } + Rectangle { + anchors.fill: parent + visible: historyListView.currentIndex === model.index + color: DefaultStyle.main2_100 + } + onPressed: { + historyListView.currentIndex = model.index + historyListView.forceActiveFocus() + } } } - MouseArea { - hoverEnabled: true - anchors.fill: parent - 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 + onCurrentIndexChanged: { + positionViewAtIndex(currentIndex, ListView.Visible) + mainItem.selectedRowHistoryGui = model.getAt(currentIndex) + } + onCountChanged: mainItem.selectedRowHistoryGui = model.getAt(currentIndex) + onVisibleChanged: { + if (!visible) currentIndex = -1 + } + + Connections { + target: mainItem + function onListViewUpdated() { + historyListView.model.updateView() } } + Control.ScrollBar.vertical: scrollbar } - onCurrentIndexChanged: { - positionViewAtIndex(currentIndex, ListView.Visible) - mainItem.selectedRowHistoryGui = model.getAt(currentIndex) - } - onCountChanged: mainItem.selectedRowHistoryGui = model.getAt(currentIndex) - onVisibleChanged: { - if (!visible) currentIndex = -1 - } - - Connections { - target: mainItem - function onListViewUpdated() { - historyListView.model.updateView() - } - } - 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 + 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 + } } } } @@ -387,51 +434,71 @@ AbstractMainPage { Component { id: newCallTitle - RowLayout { - Button { - Layout.leftMargin: 45 * DefaultStyle.dp - background: Item { + FocusScope{ + 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() + } } - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.source: AppIcons.leftArrow - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - onClicked: { - console.debug("[CallPage]User: return to call history") - listStackView.pop() + Text { + text: qsTr("Nouvel appel") + color: DefaultStyle.main2_700 + font.pixelSize: 29 * DefaultStyle.dp + font.weight: 800 * DefaultStyle.dp + } + Item { + Layout.fillWidth: true } - } - 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 - ColumnLayout { - Control.StackView.onActivated: titleLoader.sourceComponent = newCallTitle - CallContactsLists { - id: callContactsList - Layout.fillWidth: true - Layout.fillHeight: true - numPad: numericPad - groupCallVisible: true - searchBarColor: DefaultStyle.grey_100 - onSelectedContactChanged: mainWindow.startCallWithContact(selectedContact, false, callContactsList) - onGroupCallCreationRequested: { - console.log("groupe call requetsed") - listStackView.push(groupCallItem) - } - Connections { - target: mainItem - function onCreateCallFromSearchBarRequested(){ UtilsCpp.createCall(callContactsList.searchBar.text)} + FocusScope{ + width: parent?.width + height: parent?.height + Control.StackView.onActivated:{ + titleLoader.sourceComponent = newCallTitle + callContactsList.forceActiveFocus() + } + + ColumnLayout { + anchors.fill: parent + CallContactsLists { + id: callContactsList + Layout.fillWidth: true + Layout.fillHeight: true + focus: true + numPad: numericPad + groupCallVisible: true + searchBarColor: DefaultStyle.grey_100 + //onSelectedContactChanged: mainWindow.startCallWithContact(selectedContact, false, callContactsList) + onCallSelectedContact: mainWindow.startCallWithContact(selectedContact, false, callContactsList) + onCallButtonPressed: mainItem.createCallFromSearchBarRequested() + onGroupCallCreationRequested: { + console.log("groupe call requetsed") + listStackView.push(groupCallItem) + } + Connections { + target: mainItem + function onCreateCallFromSearchBarRequested(){ UtilsCpp.createCall(callContactsList.searchBar.text)} + } } } } @@ -439,54 +506,70 @@ AbstractMainPage { Component { id: groupCallTitle - RowLayout { - spacing: 10 * DefaultStyle.dp - visible: !SettingsCpp.disableMeetingsFeature - Button { - 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 - onClicked: listStackView.pop() - } - 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 + FocusScope{ + 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() } - 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 + 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 } - Layout.fillWidth: true } - } - Button { - 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 - onClicked: { - mainItem.startGroupCallRequested() + 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() + } } } } @@ -494,12 +577,19 @@ AbstractMainPage { Component { id: groupCallItem - // RowLayout { + FocusScope{ + width: parent?.width + height: parent?.height + Control.StackView.onActivated: { + titleLoader.sourceComponent = groupCallTitle + addParticipantsLayout.forceActiveFocus() + } AddParticipantsLayout { - Control.StackView.onActivated: titleLoader.sourceComponent = groupCallTitle id: addParticipantsLayout + anchors.fill: parent onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount nameGroupCall: true + focus: true Connections { target: mainItem function onStartGroupCallRequested() { @@ -519,7 +609,7 @@ AbstractMainPage { } } } - // } + } } Component{ @@ -528,194 +618,198 @@ AbstractMainPage { } Component { id: contactDetailComp - ContactLayout { - id: contactDetail - visible: mainItem.selectedRowHistoryGui != undefined - property var contactObj: UtilsCpp.findFriendByAddress(contactAddress) - contact: contactObj && contactObj.value || null - conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null - contactAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || "" - contactName: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.displayName : "" - anchors.top: rightPanelStackView.top - anchors.bottom: rightPanelStackView.bottom - anchors.topMargin: 45 * DefaultStyle.dp - anchors.bottomMargin: 45 * DefaultStyle.dp - 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: ColumnLayout { - Button { - background: Item {} - contentItem: IconLabel { - text: detailOptions.friendGui ? qsTr("Voir le contact") : qsTr("Ajouter aux contacts") - iconSource: AppIcons.plusCircle - } - onClicked: { - detailOptions.close() - if (detailOptions.friendGui) mainWindow.displayContactPage(contactDetail.contactAddress) - else mainItem.createContactRequested(contactDetail.contactName, contactDetail.contactAddress) - } - } - Button { - background: Item {} - contentItem: IconLabel { - text: qsTr("Copier l'adresse SIP") - iconSource: AppIcons.copy - } - 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 { - background: Item {} - contentItem: IconLabel { - text: qsTr("Supprimer l'historique") - iconSource: AppIcons.trashCan - colorizationColor: DefaultStyle.danger_500main - } - Connections { - target: deleteForUserPopup - function onAccepted() { - detailListView.model.removeEntriesWithFilter() - mainItem.listViewUpdated() + FocusScope{ + 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 + contactAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || "" + contactName: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.displayName : "" + + 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: ColumnLayout { + Button { + background: Item {} + contentItem: IconLabel { + text: detailOptions.friendGui ? qsTr("Voir le contact") : qsTr("Ajouter aux contacts") + iconSource: AppIcons.plusCircle + } + onClicked: { + detailOptions.close() + if (detailOptions.friendGui) mainWindow.displayContactPage(contactDetail.contactAddress) + else mainItem.createContactRequested(contactDetail.contactName, contactDetail.contactAddress) } } - onClicked: { - detailOptions.close() - deleteForUserPopup.open() + Button { + background: Item {} + contentItem: IconLabel { + text: qsTr("Copier l'adresse SIP") + iconSource: AppIcons.copy + } + 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 { + background: Item {} + contentItem: IconLabel { + text: qsTr("Supprimer l'historique") + iconSource: AppIcons.trashCan + colorizationColor: DefaultStyle.danger_500main + } + Connections { + target: deleteForUserPopup + function onAccepted() { + detailListView.model.removeEntriesWithFilter() + mainItem.listViewUpdated() + } + } + onClicked: { + detailOptions.close() + deleteForUserPopup.open() + } } } } - } - detailContent: RoundedBackgroundControl { - 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 { - filterText: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : "" + detailContent: RoundedBackgroundControl { + 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 } - - 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 + + ListView { + id: detailListView + width: parent.width + height: Math.min(detailControl.implicitHeight, contentHeight) + + spacing: 20 * DefaultStyle.dp + clip: true + + model: CallHistoryProxy { + filterText: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : "" + } + + 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: modelData.core.status === LinphoneEnums.CallStatus.Missed - ? qsTr("Appel manqué") - : modelData.core.isOutgoing - ? qsTr("Appel sortant") - : qsTr("Appel entrant") + text: UtilsCpp.formatDate(modelData.core.date) + color: modelData.core.status === LinphoneEnums.CallStatus.Missed? DefaultStyle.danger_500main : DefaultStyle.main2_500main font { - pixelSize: 14 * DefaultStyle.dp - weight: 400 * DefaultStyle.dp + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp } } } + Item { + Layout.fillHeight: true + Layout.fillWidth: true + } Text { - text: UtilsCpp.formatDate(modelData.core.date) - color: modelData.core.status === LinphoneEnums.CallStatus.Missed? DefaultStyle.danger_500main : DefaultStyle.main2_500main + text: UtilsCpp.formatElapsedTime(modelData.core.duration, false) 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 + Item{ + Layout.fillHeight: true + } } } } diff --git a/Linphone/view/Page/Main/ContactPage.qml b/Linphone/view/Page/Main/ContactPage.qml index 0fe2c9ae9..42b8b8f82 100644 --- a/Linphone/view/Page/Main/ContactPage.qml +++ b/Linphone/view/Page/Main/ContactPage.qml @@ -363,6 +363,8 @@ AbstractMainPage { Component { id: contactDetail Item { + width: parent?.width + height: parent?.height property string objectName: "contactDetail" Control.StackView.onActivated: mainItem.leftPanelEnabled = true Control.StackView.onDeactivated: mainItem.leftPanelEnabled = false @@ -791,6 +793,8 @@ AbstractMainPage { Component { id: contactEdition ContactEdition { + width: rightPanelStackView.width + height: rightPanelStackView.height property string objectName: "contactEdition" onCloseEdition: { if (rightPanelStackView.depth <= 1) rightPanelStackView.clear() @@ -798,4 +802,4 @@ AbstractMainPage { } } } -} \ No newline at end of file +} diff --git a/Linphone/view/Page/Main/MeetingPage.qml b/Linphone/view/Page/Main/MeetingPage.qml index 8c14fe872..6ca5974d6 100644 --- a/Linphone/view/Page/Main/MeetingPage.qml +++ b/Linphone/view/Page/Main/MeetingPage.qml @@ -28,19 +28,22 @@ AbstractMainPage { } } - onNoItemButtonPressed: editConference() + onNoItemButtonPressed: editConference() function editConference(confInfoGui = null) { var isCreation = !confInfoGui + var item if (isCreation) { confInfoGui = Qt.createQmlObject('import Linphone ConferenceInfoGui{ }', mainItem) mainItem.selectedConference = confInfoGui - leftPanelStackView.push(createConf, {"conferenceInfoGui": mainItem.selectedConference, "isCreation": isCreation}) + item = leftPanelStackView.push(createConf, {"conferenceInfoGui": mainItem.selectedConference, "isCreation": isCreation}) + item.forceActiveFocus() } else { mainItem.selectedConference = confInfoGui - overridenRightPanelStackView.push(editConf, {"conferenceInfoGui": mainItem.selectedConference, "isCreation": isCreation}) + item = overridenRightPanelStackView.push(editConf, {"conferenceInfoGui": mainItem.selectedConference, "isCreation": isCreation}) + item.forceActiveFocus() } } @@ -120,9 +123,9 @@ AbstractMainPage { Component { id: listLayout - ColumnLayout { - id: listLayoutIn - spacing: 0 + FocusScope{ + width: parent.width + height: listLayoutIn.implicitHeight property string objectName: "listLayout" Control.StackView.onDeactivated: { mainItem.selectedConference = null @@ -137,80 +140,97 @@ AbstractMainPage { value: conferenceList.count === 0 restoreMode: Binding.RestoreBindingOrValue } - RowLayout { - enabled: mainItem.leftPanelEnabled - Layout.rightMargin: 39 * DefaultStyle.dp + ColumnLayout { + id: listLayoutIn + anchors.fill: parent spacing: 0 + RowLayout { + enabled: mainItem.leftPanelEnabled + Layout.rightMargin: 39 * DefaultStyle.dp + spacing: 0 + Text { + Layout.fillWidth: true + text: qsTr("Réunions") + color: DefaultStyle.main2_700 + font.pixelSize: 29 * DefaultStyle.dp + font.weight: 800 * DefaultStyle.dp + } + Item{Layout.fillWidth: true} + Button { + background: Item { + } + icon.source: AppIcons.plusCircle + Layout.preferredWidth: 28 * DefaultStyle.dp + Layout.preferredHeight: 28 * DefaultStyle.dp + icon.width: 28 * DefaultStyle.dp + icon.height: 28 * DefaultStyle.dp + onClicked: { + mainItem.editConference() + } + } + } + SearchBar { + id: searchBar + Layout.topMargin: 18 * DefaultStyle.dp + // Layout.fillWidth: true + //Layout.topMargin: 18 * DefaultStyle.dp + placeholderText: qsTr("Rechercher une réunion") + Layout.preferredWidth: 331 * DefaultStyle.dp + KeyNavigation.up: conferenceList + KeyNavigation.down: conferenceList + } Text { - Layout.fillWidth: true - text: qsTr("Réunions") - color: DefaultStyle.main2_700 - font.pixelSize: 29 * DefaultStyle.dp - font.weight: 800 * DefaultStyle.dp - } - Item{Layout.fillWidth: true} - Button { - background: Item { - } - icon.source: AppIcons.plusCircle - Layout.preferredWidth: 28 * DefaultStyle.dp - Layout.preferredHeight: 28 * DefaultStyle.dp - icon.width: 28 * DefaultStyle.dp - icon.height: 28 * DefaultStyle.dp - onClicked: { - mainItem.editConference() - } - } - } - SearchBar { - id: searchBar - Layout.topMargin: 18 * DefaultStyle.dp - // Layout.fillWidth: true - //Layout.topMargin: 18 * DefaultStyle.dp - placeholderText: qsTr("Rechercher une réunion") - focusedBorderColor: DefaultStyle.main1_500_main - Layout.preferredWidth: 331 * DefaultStyle.dp - } - - Text { - Layout.topMargin: 38 * DefaultStyle.dp - Layout.fillHeight: true - Layout.alignment: Qt.AlignHCenter - text: mainItem.emptyListText - font { - pixelSize: 16 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - visible: mainItem.showDefaultItem - Binding on text { - when: searchBar.text.length !== 0 - value: qsTr("Aucune réunion correspondante") - restoreMode: Binding.RestoreBindingOrValue - } - } - - RowLayout { - // Remove 24 from first section padding because we cannot know that it is the first section. 24 is the margins between sections. - Layout.topMargin: 38 * DefaultStyle.dp - 24 * DefaultStyle.dp - spacing: 0 - MeetingList { - id: conferenceList - Layout.fillWidth: true + Layout.topMargin: 38 * DefaultStyle.dp Layout.fillHeight: true - visible: count != 0 - hoverEnabled: mainItem.leftPanelEnabled - searchBarText: searchBar.text - onSelectedConferenceChanged: { - mainItem.selectedConference = selectedConference + Layout.alignment: Qt.AlignHCenter + text: mainItem.emptyListText + font { + pixelSize: 16 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp } - Control.ScrollBar.vertical: ScrollBar { - id: meetingsScrollbar - anchors.right: parent.right - anchors.rightMargin: 8 * DefaultStyle.dp - active: true - interactive: true - policy: Control.ScrollBar.AsNeeded - + visible: mainItem.showDefaultItem + Binding on text { + when: searchBar.text.length !== 0 + value: qsTr("Aucune réunion correspondante") + restoreMode: Binding.RestoreBindingOrValue + } + } + RowLayout { + // Remove 24 from first section padding because we cannot know that it is the first section. 24 is the margins between sections. + Layout.topMargin: 38 * DefaultStyle.dp - 24 * DefaultStyle.dp + spacing: 0 + MeetingList { + id: conferenceList + Layout.fillWidth: true + Layout.fillHeight: true + visible: count != 0 + hoverEnabled: mainItem.leftPanelEnabled + highlightFollowsCurrentItem: true + preferredHighlightBegin: height/2 - 10 + preferredHighlightEnd: height/2 + 10 + highlightRangeMode: ListView.ApplyRange + searchBarText: searchBar.text + Keys.onPressed: (event) => { + if(event.key == Qt.Key_Escape){ + searchBar.forceActiveFocus() + event.accepted = true + }else if(event.key == Qt.Key_Right){ + overridenRightPanelStackView.currentItem.forceActiveFocus() + event.accepted = true + } + } + onSelectedConferenceChanged: { + mainItem.selectedConference = selectedConference + } + Control.ScrollBar.vertical: ScrollBar { + id: meetingsScrollbar + anchors.right: parent.right + anchors.rightMargin: 8 * DefaultStyle.dp + active: true + interactive: true + policy: Control.ScrollBar.AsNeeded + + } } } } @@ -219,101 +239,113 @@ AbstractMainPage { Component { id: createConf - ColumnLayout { + FocusScope{ id: createConfLayout property ConferenceInfoGui conferenceInfoGui property bool isCreation - spacing: 33 * DefaultStyle.dp - - RowLayout { - width: 320 * DefaultStyle.dp - Layout.rightMargin: 35 * DefaultStyle.dp - Button { - background: Item{} - icon.source: AppIcons.leftArrow - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - topPadding: 6 * DefaultStyle.dp - bottomPadding: 6 * DefaultStyle.dp - onClicked: { - meetingSetup.conferenceInfoGui.core.undo() - leftPanelStackView.pop() + ColumnLayout { + spacing: 33 * DefaultStyle.dp + + RowLayout { + width: 320 * DefaultStyle.dp + Layout.rightMargin: 35 * DefaultStyle.dp + spacing: 5 * DefaultStyle.dp + Button { + id: backButton + background: Item{} + icon.source: AppIcons.leftArrow + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + topPadding: 6 * DefaultStyle.dp + bottomPadding: 6 * DefaultStyle.dp + focus: true + KeyNavigation.right: createButton + KeyNavigation.down: meetingSetup + onClicked: { + meetingSetup.conferenceInfoGui.core.undo() + leftPanelStackView.pop() + } } - } - Text { - text: qsTr("Nouvelle réunion") - color: DefaultStyle.main2_700 - font { - pixelSize: 22 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - Layout.fillWidth: true - } - Button { - Layout.preferredWidth: 57 * DefaultStyle.dp - topPadding: 6 * DefaultStyle.dp - bottomPadding: 6 * DefaultStyle.dp - contentItem: Text { - text: qsTr("Créer") - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - + Text { + text: qsTr("Nouvelle réunion") + color: DefaultStyle.main2_700 font { - pixelSize: 13 * DefaultStyle.dp - weight: 600 * DefaultStyle.dp + pixelSize: 22 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp } - color: DefaultStyle.grey_0 + Layout.fillWidth: true } - onClicked: { - if (meetingSetup.conferenceInfoGui.core.subject.length === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) - } else if (meetingSetup.conferenceInfoGui.core.duration <= 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) - } else if (meetingSetup.conferenceInfoGui.core.participantCount === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) - } else { - meetingSetup.conferenceInfoGui.core.save() - mainWindow.showLoadingPopup(qsTr("Création de la réunion en cours ..."), true) - } - } - } - } - MeetingSetUp { - id: meetingSetup - conferenceInfoGui: parent.conferenceInfoGui - isCreation: parent.isCreation - Layout.rightMargin: 35 * DefaultStyle.dp - Connections { - target: meetingSetup.conferenceInfoGui ? meetingSetup.conferenceInfoGui.core : null - function onConferenceSchedulerStateChanged() { - var mainWin = UtilsCpp.getMainWindow() - if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending - || meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) { - mainWin.showLoadingPopup(qsTr("Création de la réunion en cours...")) - } else { - if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La création de la conférence a échoué"), false) + Button { + id: createButton + Layout.preferredWidth: 57 * DefaultStyle.dp + topPadding: 6 * DefaultStyle.dp + bottomPadding: 6 * DefaultStyle.dp + KeyNavigation.left: backButton + KeyNavigation.down: meetingSetup + contentItem: Text { + text: qsTr("Créer") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + font { + pixelSize: 13 * DefaultStyle.dp + weight: 600 * DefaultStyle.dp + } + color: DefaultStyle.grey_0 + } + onClicked: { + if (meetingSetup.conferenceInfoGui.core.subject.length === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) + } else if (meetingSetup.conferenceInfoGui.core.duration <= 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) + } else if (meetingSetup.conferenceInfoGui.core.participantCount === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) + } else { + meetingSetup.conferenceInfoGui.core.save() + mainWindow.showLoadingPopup(qsTr("Création de la réunion en cours ..."), true) } - mainWin.closeLoadingPopup() } - createConfLayout.enabled = meetingSetup.conferenceInfoGui.core.schedulerState != LinphoneEnums.ConferenceSchedulerState.AllocationPending } } - onSaveSucceed: { - leftPanelStackView.pop() - UtilsCpp.showInformationPopup(qsTr("Nouvelle réunion"), qsTr("Réunion planifiée avec succès"), true) - mainWindow.closeLoadingPopup() - } - onAddParticipantsRequested: { - leftPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": leftPanelStackView}) - } - Connections { - target: mainItem - function onAddParticipantsValidated(selectedParticipants) { - meetingSetup.conferenceInfoGui.core.resetParticipants(selectedParticipants) + MeetingSetUp { + id: meetingSetup + conferenceInfoGui: createConfLayout.conferenceInfoGui + isCreation: createConfLayout.isCreation + Layout.fillHeight: true + Layout.fillWidth: true + Layout.rightMargin: 35 * DefaultStyle.dp + Connections { + target: meetingSetup.conferenceInfoGui ? meetingSetup.conferenceInfoGui.core : null + function onConferenceSchedulerStateChanged() { + var mainWin = UtilsCpp.getMainWindow() + if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending + || meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) { + mainWin.showLoadingPopup(qsTr("Création de la réunion en cours...")) + } else { + if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La création de la conférence a échoué"), false) + } + mainWin.closeLoadingPopup() + } + createConfLayout.enabled = meetingSetup.conferenceInfoGui.core.schedulerState != LinphoneEnums.ConferenceSchedulerState.AllocationPending + } + } + onSaveSucceed: { leftPanelStackView.pop() + UtilsCpp.showInformationPopup(qsTr("Nouvelle réunion"), qsTr("Réunion planifiée avec succès"), true) + mainWindow.closeLoadingPopup() + } + onAddParticipantsRequested: { + leftPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": leftPanelStackView}) + } + Connections { + target: mainItem + onAddParticipantsValidated: (selectedParticipants) => { + meetingSetup.conferenceInfoGui.core.resetParticipants(selectedParticipants) + leftPanelStackView.pop() + } } } } @@ -322,83 +354,107 @@ AbstractMainPage { Component { id: editConf - ColumnLayout { + FocusScope{ + id: editFocusScope property bool isCreation property ConferenceInfoGui conferenceInfoGui - Section { - content: RowLayout { - spacing: 10 * DefaultStyle.dp - Button { - background: Item{} - icon.source: AppIcons.leftArrow - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - onClicked: { - conferenceEdit.conferenceInfoGui.core.undo() - overridenRightPanelStackView.pop() + width : parent.width + height: editLayout.implicitHeight + ColumnLayout { + id: editLayout + anchors.fill: parent + spacing: 0 + Section { + content: RowLayout { + spacing: 10 * DefaultStyle.dp + Button { + id: backButton + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + icon.source: AppIcons.leftArrow + KeyNavigation.left: saveButton + KeyNavigation.right: titleText + KeyNavigation.down: conferenceEdit + KeyNavigation.up: conferenceEdit + onClicked: { + conferenceEdit.conferenceInfoGui.core.undo() + overridenRightPanelStackView.pop() + } + background: Item{} } - } - - TextField { - Component.onCompleted: text = mainItem.selectedConference.core.subject - color: DefaultStyle.main2_600 - font { - pixelSize: 20 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp + + TextField { + id: titleText + Layout.fillWidth: true + color: DefaultStyle.main2_600 + font { + pixelSize: 20 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp + } + KeyNavigation.left: backButton + KeyNavigation.right: saveButton + KeyNavigation.down: conferenceEdit + KeyNavigation.up: conferenceEdit + onActiveFocusChanged: if(activeFocus==true) selectAll() + onEditingFinished: mainItem.selectedConference.core.subject = text + Component.onCompleted: text = mainItem.selectedConference.core.subject + background: Item{} } - background: Item{} - Layout.fillWidth: true - onActiveFocusChanged: if(activeFocus==true) selectAll() - onEditingFinished: mainItem.selectedConference.core.subject = text - } - Button { - topPadding: 6 * DefaultStyle.dp - bottomPadding: 6 * DefaultStyle.dp - leftPadding: 12 * DefaultStyle.dp - rightPadding: 12 * DefaultStyle.dp - text: qsTr("Save") - textSize: 13 * DefaultStyle.dp - onClicked: { - if (mainItem.selectedConference.core.subject.length === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) - } else if (mainItem.selectedConference.core.duration <= 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) - } else if (mainItem.selectedConference.core.participantCount === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) - } else { - mainItem.selectedConference.core.save() + Button { + id: saveButton + topPadding: 6 * DefaultStyle.dp + bottomPadding: 6 * DefaultStyle.dp + leftPadding: 12 * DefaultStyle.dp + rightPadding: 12 * DefaultStyle.dp + focus: true + text: qsTr("Save") + textSize: 13 * DefaultStyle.dp + KeyNavigation.left: titleText + KeyNavigation.right: backButton + KeyNavigation.down: conferenceEdit + KeyNavigation.up: conferenceEdit + onClicked: { + if (mainItem.selectedConference.core.subject.length === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) + } else if (mainItem.selectedConference.core.duration <= 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) + } else if (mainItem.selectedConference.core.participantCount === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) + } else { + mainItem.selectedConference.core.save() + } } } } } - } - MeetingSetUp { - id: conferenceEdit - property bool isCreation - isCreation: parent.isCreation - conferenceInfoGui: parent.conferenceInfoGui - onSaveSucceed: { - overridenRightPanelStackView.pop() - UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Réunion modifiée avec succès"), true) - } - onAddParticipantsRequested: { - overridenRightPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": overridenRightPanelStackView}) - } - Connections { - target: mainItem - function onAddParticipantsValidated(selectedParticipants) { - conferenceEdit.conferenceInfoGui.core.resetParticipants(selectedParticipants) + MeetingSetUp { + id: conferenceEdit + property bool isCreation + isCreation: editFocusScope.isCreation + conferenceInfoGui: editFocusScope.conferenceInfoGui + onSaveSucceed: { overridenRightPanelStackView.pop() + UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Réunion modifiée avec succès"), true) } - } - Connections { - target: conferenceEdit.conferenceInfoGui ? conferenceEdit.conferenceInfoGui.core : null - function onConferenceSchedulerStateChanged() { - var mainWin = UtilsCpp.getMainWindow() - if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("L'édition de la conférence a échoué"), false) + onAddParticipantsRequested: { + overridenRightPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": overridenRightPanelStackView}) + } + Connections { + target: mainItem + function onAddParticipantsValidated(selectedParticipants) { + conferenceEdit.conferenceInfoGui.core.resetParticipants(selectedParticipants) + overridenRightPanelStackView.pop() + } + } + Connections { + target: conferenceEdit.conferenceInfoGui ? conferenceEdit.conferenceInfoGui.core : null + function onConferenceSchedulerStateChanged() { + var mainWin = UtilsCpp.getMainWindow() + if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("L'édition de la conférence a échoué"), false) + } } } } @@ -411,56 +467,71 @@ AbstractMainPage { ColumnLayout { property Control.StackView container property ConferenceInfoGui conferenceInfoGui - RowLayout { - Button { - background: Item{} - icon.source: AppIcons.leftArrow - contentImageColor: DefaultStyle.main1_500_main - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - onClicked: container.pop() - } - ColumnLayout { - spacing: 3 * DefaultStyle.dp - Text { - text: qsTr("Ajouter des participants") - color: DefaultStyle.main1_500_main - maximumLineCount: 1 - font { - pixelSize: 18 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - Layout.fillWidth: true + FocusScope{ + Layout.fillWidth: true + Layout.preferredHeight: addParticipantsButtons.implicitHeight + RowLayout { + id: addParticipantsButtons + spacing: 5 * DefaultStyle.dp + Button { + id: removeButton + background: Item{} + icon.source: AppIcons.leftArrow + contentImageColor: DefaultStyle.main1_500_main + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + KeyNavigation.right: addButton + KeyNavigation.down: addParticipantLayout + onClicked: container.pop() } - Text { - text: qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "") - color: DefaultStyle.main2_500main - maximumLineCount: 1 - font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp + ColumnLayout { + spacing: 3 * DefaultStyle.dp + Text { + text: qsTr("Ajouter des participants") + 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é%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "") + color: DefaultStyle.main2_500main + maximumLineCount: 1 + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp + } + Layout.fillWidth: true } - Layout.fillWidth: true } - } - Button { - enabled: addParticipantLayout.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("Ajouter") - textSize: 13 * DefaultStyle.dp - onClicked: { - mainItem.addParticipantsValidated(addParticipantLayout.selectedParticipants) + Button { + id: addButton + enabled: addParticipantLayout.selectedParticipantsCount.length != 0 + Layout.rightMargin: 21 * DefaultStyle.dp + topPadding: 6 * DefaultStyle.dp + bottomPadding: 6 * DefaultStyle.dp + leftPadding: 12 * DefaultStyle.dp + rightPadding: 12 * DefaultStyle.dp + focus: enabled + text: qsTr("Ajouter") + textSize: 13 * DefaultStyle.dp + KeyNavigation.left: removeButton + KeyNavigation.down: addParticipantLayout + onClicked: { + mainItem.addParticipantsValidated(addParticipantLayout.selectedParticipants) + } } } } AddParticipantsLayout { id: addParticipantLayout + Layout.fillWidth: true + Layout.fillHeight: true conferenceInfoGui: parent.conferenceInfoGui } } @@ -468,48 +539,64 @@ AbstractMainPage { Component { id: meetingDetail - ColumnLayout { - visible: mainItem.selectedConference - spacing: 25 * DefaultStyle.dp - Section { - Layout.topMargin: 58 * DefaultStyle.dp + FocusScope{ + width: overridenRightPanelStackView.width + height: meetingDetailsLayout.implicitHeight + ColumnLayout { + id: meetingDetailsLayout + anchors.fill: parent visible: mainItem.selectedConference - content: RowLayout { - spacing: 8 * DefaultStyle.dp - Image { - source: AppIcons.usersThree - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - } - Text { - text: mainItem.selectedConference ? mainItem.selectedConference.core.subject : "" - font { - pixelSize: 20 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp + spacing: 25 * DefaultStyle.dp + Section { + Layout.topMargin: 58 * DefaultStyle.dp + visible: mainItem.selectedConference + content: RowLayout { + spacing: 8 * DefaultStyle.dp + Image { + source: AppIcons.usersThree + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp } - } - Item { - Layout.fillWidth: true - } - Button { - visible: mainItem.selectedConference && UtilsCpp.isMe(mainItem.selectedConference.core.organizerAddress) - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - icon.source: AppIcons.pencil - contentImageColor: DefaultStyle.main1_500_main - background: Item{} - onClicked: mainItem.editConference(mainItem.selectedConference) - } - PopupButton { - id: deletePopup - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - contentImageColor: DefaultStyle.main1_500_main - popup.contentItem: RowLayout { - Button { - background: Item{} + Text { + text: mainItem.selectedConference ? mainItem.selectedConference.core.subject : "" + font { + pixelSize: 20 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp + } + } + Item { + Layout.fillWidth: true + } + Button { + id: editButton + visible: mainItem.selectedConference && UtilsCpp.isMe(mainItem.selectedConference.core.organizerAddress) + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + icon.source: AppIcons.pencil + contentImageColor: DefaultStyle.main1_500_main + KeyNavigation.left: leftPanelStackView.currentItem + KeyNavigation.right: deletePopup + KeyNavigation.up: joinButton + KeyNavigation.down: shareNetworkButton + background: Item{} + onClicked: mainItem.editConference(mainItem.selectedConference) + } + PopupButton { + id: deletePopup + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + contentImageColor: DefaultStyle.main1_500_main + KeyNavigation.left: editButton.visible ? editButton : leftPanelStackView.currentItem + KeyNavigation.right: leftPanelStackView.currentItem + KeyNavigation.up: joinButton + KeyNavigation.down: shareNetworkButton + + popup.contentItem: Button { + color: deletePopup.popupBackgroundColor + borderColor: deletePopup.popupBackgroundColor + inversedColors: true contentItem: RowLayout { EffectImage { imageSource: AppIcons.trashCan @@ -550,186 +637,209 @@ AbstractMainPage { } } } - } - Section { - content: ColumnLayout { - spacing: 15 * DefaultStyle.dp - width: parent.width - RowLayout { - spacing: 8 * DefaultStyle.dp - Layout.fillWidth: true - Image { - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - source: AppIcons.videoCamera - } - Button { + Section { + content: ColumnLayout { + spacing: 15 * DefaultStyle.dp + width: parent.width + RowLayout { + spacing: 8 * DefaultStyle.dp Layout.fillWidth: true - text: mainItem.selectedConference ? mainItem.selectedConference.core.uri : "" - textSize: 14 * DefaultStyle.dp - textWeight: 400 * DefaultStyle.dp - underline: true - inversedColors: true - color: DefaultStyle.main2_600 - background: Item{} - onClicked: { - // TODO : voir si c'est en audio only quand on clique sur le lien - UtilsCpp.createCall(mainItem.selectedConference.core.uri) + Image { + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + source: AppIcons.videoCamera + } + Button { + id: linkButton + Layout.fillWidth: true + font.bold: shadowEnabled + text: mainItem.selectedConference ? mainItem.selectedConference.core.uri : "" + textSize: 14 * DefaultStyle.dp + textWeight: 400 * DefaultStyle.dp + underline: true + inversedColors: true + color: DefaultStyle.main2_600 + background: Item{} + Keys.onPressed: (event)=> { + if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { + clicked(undefined) + event.accepted = true; + } + } + KeyNavigation.left: shareNetworkButton + KeyNavigation.right: shareNetworkButton + KeyNavigation.up: deletePopup + KeyNavigation.down: joinButton + onClicked: { + // TODO : voir si c'est en audio only quand on clique sur le lien + UtilsCpp.createCall(mainItem.selectedConference.core.uri) + } + } + Button { + id: shareNetworkButton + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + background: Item{} + icon.source: AppIcons.shareNetwork + KeyNavigation.left: linkButton + KeyNavigation.right: linkButton + KeyNavigation.up: deletePopup + KeyNavigation.down: joinButton + onClicked: { + UtilsCpp.copyToClipboard(mainItem.selectedConference.core.uri) + UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Le lien de la réunion a été copié dans le presse-papiers")) + } } } - Button { - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - background: Item{} - icon.source: AppIcons.shareNetwork - onClicked: { - UtilsCpp.copyToClipboard(mainItem.selectedConference.core.uri) - UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Le lien de la réunion a été copié dans le presse-papiers")) - } - } - } - RowLayout { - spacing: 8 * DefaultStyle.dp - Image { - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - source: AppIcons.clock - } - Text { - text: mainItem.selectedConference - ? UtilsCpp.toDateString(mainItem.selectedConference.core.dateTimeUtc) - + " | " + UtilsCpp.toDateHourString(mainItem.selectedConference.core.dateTimeUtc) - + " - " - + UtilsCpp.toDateHourString(mainItem.selectedConference.core.endDateTime) - : '' - font { - pixelSize: 14 * DefaultStyle.dp - capitalization: Font.Capitalize - } - } - } - RowLayout { - spacing: 8 * DefaultStyle.dp - Image { - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - source: AppIcons.globe - } - Text { - text: qsTr("Time zone: ") + (mainItem.selectedConference ? (mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName) : "") - font { - pixelSize: 14 * DefaultStyle.dp - capitalization: Font.Capitalize - } - } - } - } - } - Section { - visible: mainItem.selectedConference && mainItem.selectedConference.core.description.length != 0 - content: RowLayout { - spacing: 8 * DefaultStyle.dp - EffectImage { - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - imageSource: AppIcons.note - colorizationColor: DefaultStyle.main2_600 - } - Text { - text: mainItem.selectedConference ? mainItem.selectedConference.core.description : "" - Layout.fillWidth: true - font { - pixelSize: 14 * DefaultStyle.dp - capitalization: Font.Capitalize - } - } - } - } - Section { - content: RowLayout { - spacing: 8 * DefaultStyle.dp - EffectImage { - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - imageSource: AppIcons.userRectangle - colorizationColor: DefaultStyle.main2_600 - } - Avatar { - Layout.preferredWidth: 45 * DefaultStyle.dp - Layout.preferredHeight: 45 * DefaultStyle.dp - address: mainItem.selectedConference ? mainItem.selectedConference.core.organizerAddress : "" - } - Text { - text: mainItem.selectedConference ? mainItem.selectedConference.core.organizerName : "" - font { - pixelSize: 14 * DefaultStyle.dp - capitalization: Font.Capitalize - } - } - } - } - Section { - content: RowLayout { - Layout.preferredHeight: participantList.height - width: 393 * DefaultStyle.dp - spacing: 8 * DefaultStyle.dp - Image { - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.topMargin: 20 * DefaultStyle.dp - source: AppIcons.usersTwo - } - ListView { - id: participantList - Layout.preferredHeight: Math.min(184 * DefaultStyle.dp, contentHeight) - Layout.fillWidth: true - model: mainItem.selectedConference ? mainItem.selectedConference.core.participants : [] - clip: true - delegate: RowLayout { - height: 56 * DefaultStyle.dp - width: participantList.width - Avatar { - Layout.preferredWidth: 45 * DefaultStyle.dp - Layout.preferredHeight: 45 * DefaultStyle.dp - address: modelData.address + RowLayout { + spacing: 8 * DefaultStyle.dp + Image { + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + source: AppIcons.clock } Text { - text: modelData.displayName - Layout.fillWidth: true + text: mainItem.selectedConference + ? UtilsCpp.toDateString(mainItem.selectedConference.core.dateTimeUtc) + + " | " + UtilsCpp.toDateHourString(mainItem.selectedConference.core.dateTimeUtc) + + " - " + + UtilsCpp.toDateHourString(mainItem.selectedConference.core.endDateTime) + : '' font { pixelSize: 14 * DefaultStyle.dp capitalization: Font.Capitalize } } + } + RowLayout { + spacing: 8 * DefaultStyle.dp + Image { + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + source: AppIcons.globe + } Text { - text: qsTr("Organizer") - visible: mainItem.selectedConference && mainItem.selectedConference.core.organizerAddress === modelData.address - color: DefaultStyle.main2_400 + text: qsTr("Time zone: ") + (mainItem.selectedConference ? (mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName) : "") font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp + pixelSize: 14 * DefaultStyle.dp + capitalization: Font.Capitalize } } } } } - } - Button { - Layout.fillWidth: true - text: qsTr("Rejoindre la réunion") - topPadding: 11 * DefaultStyle.dp - bottomPadding: 11 * DefaultStyle.dp - onClicked: { - console.log(mainItem.selectedConference.core.uri) - var callsWindow = UtilsCpp.getCallsWindow() - callsWindow.setupConference(mainItem.selectedConference) - callsWindow.show() + Section { + visible: mainItem.selectedConference && mainItem.selectedConference.core.description.length != 0 + content: RowLayout { + spacing: 8 * DefaultStyle.dp + EffectImage { + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + imageSource: AppIcons.note + colorizationColor: DefaultStyle.main2_600 + } + Text { + text: mainItem.selectedConference ? mainItem.selectedConference.core.description : "" + Layout.fillWidth: true + font { + pixelSize: 14 * DefaultStyle.dp + capitalization: Font.Capitalize + } + } + } } + Section { + content: RowLayout { + spacing: 8 * DefaultStyle.dp + EffectImage { + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + imageSource: AppIcons.userRectangle + colorizationColor: DefaultStyle.main2_600 + } + Avatar { + Layout.preferredWidth: 45 * DefaultStyle.dp + Layout.preferredHeight: 45 * DefaultStyle.dp + address: mainItem.selectedConference ? mainItem.selectedConference.core.organizerAddress : "" + } + Text { + text: mainItem.selectedConference ? mainItem.selectedConference.core.organizerName : "" + font { + pixelSize: 14 * DefaultStyle.dp + capitalization: Font.Capitalize + } + } + } + } + Section { + content: RowLayout { + Layout.preferredHeight: participantList.height + width: 393 * DefaultStyle.dp + spacing: 8 * DefaultStyle.dp + Image { + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.topMargin: 20 * DefaultStyle.dp + source: AppIcons.usersTwo + } + ListView { + id: participantList + Layout.preferredHeight: Math.min(184 * DefaultStyle.dp, contentHeight) + Layout.fillWidth: true + model: mainItem.selectedConference ? mainItem.selectedConference.core.participants : [] + clip: true + delegate: RowLayout { + height: 56 * DefaultStyle.dp + width: participantList.width + Avatar { + Layout.preferredWidth: 45 * DefaultStyle.dp + Layout.preferredHeight: 45 * DefaultStyle.dp + address: modelData.address + } + Text { + text: modelData.displayName + Layout.fillWidth: true + font { + pixelSize: 14 * DefaultStyle.dp + capitalization: Font.Capitalize + } + } + Text { + text: qsTr("Organizer") + visible: mainItem.selectedConference && mainItem.selectedConference.core.organizerAddress === modelData.address + color: DefaultStyle.main2_400 + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp + } + } + } + } + } + } + Button { + id: joinButton + Layout.fillWidth: true + text: qsTr("Rejoindre la réunion") + topPadding: 11 * DefaultStyle.dp + bottomPadding: 11 * DefaultStyle.dp + focus: true + KeyNavigation.up: shareNetworkButton + KeyNavigation.down: deletePopup + KeyNavigation.left: leftPanelStackView.currentItem + KeyNavigation.right: leftPanelStackView.currentItem + onClicked: { + console.log(mainItem.selectedConference.core.uri) + var callsWindow = UtilsCpp.getCallsWindow() + callsWindow.setupConference(mainItem.selectedConference) + callsWindow.show() + } + } + Item { Layout.fillHeight: true} } - Item { Layout.fillHeight: true} } } }