mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-02-07 15:08:24 +00:00
Set dummy conference info as a null core. Load new items in case of chaning dates. Allow gui to load until current date. Fix video direction on screensharing. Update SDK for tone indication on meetings. Clean
348 lines
12 KiB
QML
348 lines
12 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts
|
|
import QtQuick.Controls.Basic as Control
|
|
|
|
import Linphone
|
|
import UtilsCpp 1.0
|
|
import ConstantsCpp 1.0
|
|
import SettingsCpp
|
|
|
|
Flickable{
|
|
id: mainItem
|
|
|
|
property bool showInitials: true // Display Initials of Display name.
|
|
property bool showDefaultAddress: true // Display address below display name.
|
|
property bool showActions: false // Display actions layout (call buttons)
|
|
property bool showContactMenu: true // Display the dot menu for contacts.
|
|
property bool showFavorites: true // Display the favorites in the header
|
|
property bool hideSuggestions: false // Hide not stored contacts (not suggestions)
|
|
property string highlightText: searchText // Bold characters in Display name.
|
|
property var sourceFlags: LinphoneEnums.MagicSearchSource.All
|
|
|
|
property bool displayNameCapitalization: true // Capitalize display name.
|
|
|
|
property bool selectionEnabled: true // Contact can be selected
|
|
property bool multiSelectionEnabled: false //Multiple items can be selected.
|
|
property list<string> selectedContacts // List of default address on selected contacts.
|
|
//property FriendGui selectedContact//: model.getAt(currentIndex) || null
|
|
property FriendGui highlightedContact
|
|
|
|
property bool searchOnEmpty: true
|
|
property bool loading: false
|
|
property bool pauseSearch: false // true = don't search on text change
|
|
|
|
// Model properties
|
|
// set searchBarText without specifying a model to bold
|
|
// matching names
|
|
property string searchBarText
|
|
property string searchText// Binding is done on searchBarTextChanged
|
|
property ConferenceInfoGui confInfoGui
|
|
|
|
property bool haveFavorites: false
|
|
property bool haveContacts: count > 0
|
|
property int sectionsPixelSize: 16 * DefaultStyle.dp
|
|
property int sectionsWeight: 800 * DefaultStyle.dp
|
|
property int sectionsSpacing: 18 * DefaultStyle.dp
|
|
|
|
property int itemsRightMargin: 39 * DefaultStyle.dp
|
|
property int count: contactsList.count + suggestionsList.count + favoritesList.count
|
|
|
|
signal resultsReceived()
|
|
signal contactStarredChanged()
|
|
signal contactDeletionRequested(FriendGui contact)
|
|
signal contactAddedToSelection(string address)
|
|
signal contactRemovedFromSelection(string address)
|
|
signal contactSelected(FriendGui contact)
|
|
|
|
contentWidth: width
|
|
contentHeight: contentsLayout.height
|
|
|
|
|
|
function selectContact(address) {
|
|
var index = contactsProxy.loadUntil(address)// Be sure to have this address in proxy if it exists
|
|
if (index != -1) {
|
|
contactsList.selectIndex(index)
|
|
}
|
|
return index
|
|
|
|
}
|
|
function addContactToSelection(address) {
|
|
if (multiSelectionEnabled) {
|
|
var indexInSelection = selectedContacts.indexOf(address)
|
|
if (indexInSelection == -1) {
|
|
selectedContacts.push(address)
|
|
contactAddedToSelection(address)
|
|
}
|
|
}
|
|
}
|
|
function removeContactFromSelection(indexInSelection) {
|
|
var addressToRemove = selectedContacts[indexInSelection]
|
|
if (indexInSelection != -1) {
|
|
selectedContacts.splice(indexInSelection, 1)
|
|
contactRemovedFromSelection(addressToRemove)
|
|
}
|
|
}
|
|
function removeSelectedContactByAddress(address) {
|
|
var index = selectedContacts.indexOf(address)
|
|
if (index != -1) {
|
|
selectedContacts.splice(index, 1)
|
|
contactRemovedFromSelection(address)
|
|
}
|
|
}
|
|
function haveAddress(address){
|
|
var index = magicSearchProxy.findFriendIndexByAddress(address)
|
|
return index != -1
|
|
}
|
|
|
|
function resetSelections(){
|
|
mainItem.highlightedContact = null
|
|
favoritesList.currentIndex = -1
|
|
contactsList.currentIndex = -1
|
|
suggestionsList.currentIndex = -1
|
|
}
|
|
|
|
function findNextList(item, count, direction){
|
|
if(count == 3) return null
|
|
var nextItem
|
|
switch(item){
|
|
case suggestionsList:nextItem=(direction > 0 ? favoritesList : contactsList);break;
|
|
case contactsList:nextItem=(direction > 0 ? suggestionsList : favoritesList);break;
|
|
case favoritesList:nextItem=(direction > 0 ? contactsList : suggestionsList);break;
|
|
default: return null
|
|
}
|
|
if( nextItem.model.count > 0) return nextItem
|
|
else return findNextList(nextItem, count+1, direction)
|
|
}
|
|
|
|
function updatePosition(list){
|
|
var item = list.itemAtIndex(list.currentIndex)
|
|
var centerItemPos = 0
|
|
if( item && list.expanded){
|
|
// For debugging just in case
|
|
//var listPosition = item.mapToItem(favoriteList, item.x, item.y)
|
|
//var newPosition = favoriteList.mapToItem(mainItem, listPosition.x, listPosition.y)
|
|
//console.log("item pos: " +item.x + " / " +item.y)
|
|
//console.log("fav pos: " +favoriteList.x + " / " +favoriteList.y)
|
|
//console.log("fav content: " +favoriteList.contentX + " / " +favoriteList.contentY)
|
|
//console.log("main pos: " +mainItem.x + " / " +mainItem.y)
|
|
//console.log("main content: " +mainItem.contentX + " / " +mainItem.contentY)
|
|
//console.log("list pos: " +listPosition.x + " / " +listPosition.y)
|
|
//console.log("new pos: " +newPosition.x + " / " +newPosition.y)
|
|
//console.log("header pos: " +headerItem.x + " / " +headerItem.y)
|
|
//console.log("Moving to " + (headerItem.y+item.y))
|
|
centerItemPos = item.y + list.y + list.headerHeight +item.height/2
|
|
}
|
|
var centerPos = centerItemPos - height/2
|
|
mainItem.contentY = Math.max(0, Math.min(centerPos, height, contentHeight-height))
|
|
}
|
|
|
|
onHighlightedContactChanged:{
|
|
favoritesList.highlightedContact = highlightedContact
|
|
contactsList.highlightedContact = highlightedContact
|
|
suggestionsList.highlightedContact = highlightedContact
|
|
}
|
|
|
|
onResultsReceived: {
|
|
loading = false
|
|
mainItem.contentY = 0
|
|
}
|
|
onSearchBarTextChanged: {
|
|
if(!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
|
|
searchText = searchBarText.length === 0 ? "*" : searchBarText
|
|
}
|
|
}
|
|
onPauseSearchChanged: {
|
|
if(!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')){
|
|
searchText = searchBarText.length === 0 ? "*" : searchBarText
|
|
}
|
|
}
|
|
onSearchTextChanged: loading = true
|
|
onAtYEndChanged: if(atYEnd) {
|
|
if( (contactsProxy.haveMore && contactList.expanded ) || mainItem.hideSuggestions) contactsProxy.displayMore()
|
|
else suggestionsProxy.displayMore()
|
|
}
|
|
Behavior on contentY{
|
|
NumberAnimation {
|
|
duration: 500
|
|
easing.type: Easing.OutExpo
|
|
}
|
|
}
|
|
Keys.onPressed: (event)=> {
|
|
if(!event.accepted){
|
|
if(event.key == Qt.Key_Up || event.key == Qt.Key_Down){
|
|
var newItem
|
|
var direction = (event.key == Qt.Key_Up ? -1 : 1)
|
|
if(suggestionsList.activeFocus) newItem = findNextList(suggestionsList, 0, direction)
|
|
else if(contactsList.activeFocus) newItem = findNextList(contactsList, 0, direction)
|
|
else if(favoritesList.activeFocus) newItem = findNextList(favoritesList, 0, direction)
|
|
else newItem = findNextList(suggestionsList, 0, direction)
|
|
if(newItem){
|
|
newItem.selectIndex(direction > 0 ? -1 : newItem.model.count - 1)
|
|
event.accepted = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component.onCompleted: {
|
|
if (confInfoGui) {
|
|
for(var i = 0; i < confInfoGui.core.participants.length; ++i) {
|
|
selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: SettingsCpp
|
|
onLdapConfigChanged: {
|
|
if (SettingsCpp.syncLdapContacts)
|
|
magicSearchProxy.forceUpdate()
|
|
}
|
|
}
|
|
|
|
property MagicSearchProxy mainModel: MagicSearchProxy {
|
|
id: magicSearchProxy
|
|
searchText: mainItem.searchText
|
|
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
|
|
sourceFlags: mainItem.sourceFlags
|
|
onModelReset: {
|
|
mainItem.resetSelections()
|
|
mainItem.resultsReceived()
|
|
}
|
|
|
|
onInitialized: {
|
|
if(mainItem.searchOnEmpty || searchText != '' ) {
|
|
mainItem.loading = true
|
|
forceUpdate()
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Control.ScrollBar.vertical: ScrollBar {
|
|
id: scrollbar
|
|
rightPadding: 8 * DefaultStyle.dp
|
|
topPadding: mainItem.haveFavorites ? 24 * DefaultStyle.dp : 0 // Avoid to be on top of collapse button
|
|
|
|
active: true
|
|
interactive: true
|
|
policy: mainItem.contentHeight > mainItem.height ? Control.ScrollBar.AlwaysOn : Control.ScrollBar.AlwaysOff
|
|
}
|
|
|
|
|
|
ColumnLayout{
|
|
id: contentsLayout
|
|
width: parent.width
|
|
spacing: 0
|
|
BusyIndicator {
|
|
Layout.alignment: Qt.AlignCenter
|
|
Layout.preferredHeight: visible ? 60 * DefaultStyle.dp : 0
|
|
Layout.preferredWidth: 60 * DefaultStyle.dp
|
|
indicatorHeight: 60 * DefaultStyle.dp
|
|
indicatorWidth: 60 * DefaultStyle.dp
|
|
visible: mainItem.loading
|
|
indicatorColor: DefaultStyle.main1_500_main
|
|
}
|
|
|
|
ContactListView{
|
|
id: favoritesList
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: implicitHeight
|
|
interactive: false
|
|
highlightText: mainItem.highlightText
|
|
showActions: mainItem.showActions
|
|
showInitials: mainItem.showInitials
|
|
showContactMenu: mainItem.showContactMenu
|
|
showDefaultAddress: mainItem.showDefaultAddress
|
|
selectionEnabled: mainItem.selectionEnabled
|
|
multiSelectionEnabled: mainItem.multiSelectionEnabled
|
|
selectedContacts: mainItem.selectedContacts
|
|
title: qsTr('Favoris')
|
|
|
|
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
|
|
onContactSelected: (contactGui) => {
|
|
mainItem.contactSelected(contactGui)
|
|
}
|
|
onUpdatePosition: mainItem.updatePosition(favoritesList)
|
|
onContactDeletionRequested: (contact) => {mainItem.contactDeletionRequested(contact)}
|
|
onAddContactToSelection: (address) => {mainItem.addContactToSelection(address)}
|
|
onRemoveContactFromSelection: (index) => {mainItem.removeContactFromSelection(index)}
|
|
|
|
property MagicSearchProxy proxy: MagicSearchProxy {
|
|
parentProxy: mainItem.mainModel
|
|
filterType: MagicSearchProxy.FilteringTypes.Favorites
|
|
}
|
|
model : mainItem.showFavorites && (mainItem.searchBarText == ''|| mainItem.searchBarText == '*')? proxy : []
|
|
}
|
|
|
|
ContactListView{
|
|
id: contactsList
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: implicitHeight
|
|
Layout.topMargin: favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0
|
|
interactive: false
|
|
highlightText: mainItem.highlightText
|
|
showActions: mainItem.showActions
|
|
showInitials: mainItem.showInitials
|
|
showContactMenu: mainItem.showContactMenu
|
|
showDefaultAddress: mainItem.showDefaultAddress
|
|
selectionEnabled: mainItem.selectionEnabled
|
|
multiSelectionEnabled: mainItem.multiSelectionEnabled
|
|
selectedContacts: mainItem.selectedContacts
|
|
title: qsTr('Contacts')
|
|
|
|
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
|
|
onContactSelected: (contactGui) => {
|
|
mainItem.contactSelected(contactGui)
|
|
}
|
|
onUpdatePosition: mainItem.updatePosition(contactsList)
|
|
onContactDeletionRequested: (contact) => {mainItem.contactDeletionRequested(contact)}
|
|
onAddContactToSelection: (address) => {mainItem.addContactToSelection(address)}
|
|
onRemoveContactFromSelection: (index) => {mainItem.removeContactFromSelection(index)}
|
|
|
|
model:MagicSearchProxy {
|
|
id: contactsProxy
|
|
parentProxy: mainItem.mainModel
|
|
filterType: MagicSearchProxy.FilteringTypes.App | (mainItem.searchText != '*' && mainItem.searchText != '' || SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap : 0)
|
|
initialDisplayItems: 20
|
|
displayItemsStep: 5
|
|
onLocalFriendCreated: (index) => {
|
|
contactsList.selectIndex(index)
|
|
}
|
|
}
|
|
}
|
|
ContactListView{
|
|
id: suggestionsList
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: implicitHeight
|
|
Layout.topMargin: contactsList.height + favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0
|
|
interactive: false
|
|
showInitials: false
|
|
highlightText: mainItem.highlightText
|
|
showActions: mainItem.showActions
|
|
showContactMenu: mainItem.showContactMenu
|
|
showDefaultAddress: mainItem.showDefaultAddress
|
|
selectionEnabled: mainItem.selectionEnabled
|
|
multiSelectionEnabled: mainItem.multiSelectionEnabled
|
|
selectedContacts: mainItem.selectedContacts
|
|
title: qsTr('Suggestions')
|
|
|
|
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
|
|
onContactSelected: (contactGui) => {
|
|
mainItem.contactSelected(contactGui)
|
|
}
|
|
onUpdatePosition: mainItem.updatePosition(suggestionsList)
|
|
onContactDeletionRequested: (contact) => {mainItem.contactDeletionRequested(contact)}
|
|
onAddContactToSelection: (address) => {mainItem.addContactToSelection(address)}
|
|
onRemoveContactFromSelection: (index) => {mainItem.removeContactFromSelection(index)}
|
|
model:MagicSearchProxy {
|
|
id: suggestionsProxy
|
|
parentProxy: mainItem.mainModel
|
|
filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other
|
|
initialDisplayItems: contactsProxy.haveMore && contactsList.expanded ? 0 : 20
|
|
onInitialDisplayItemsChanged: maxDisplayItems = initialDisplayItems
|
|
displayItemsStep: 5
|
|
onModelReset: maxDisplayItems = initialDisplayItems
|
|
}
|
|
}
|
|
}
|
|
}
|