Fix addresses view on call and searchs

This commit is contained in:
Julien Wadel 2021-08-19 18:35:59 +02:00
parent 2307c7ba82
commit 07074d3aef
5 changed files with 135 additions and 126 deletions

View file

@ -28,64 +28,71 @@
class ContactModel;
class SipAddressObserver : public QObject {
friend class SipAddressesModel;
friend class SipAddressesModel;
Q_OBJECT;
Q_OBJECT;
Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT);
Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT);
Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT);
Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT);
Q_PROPERTY(ContactModel *contact READ getContact NOTIFY contactChanged);
Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged);
Q_PROPERTY(int unreadMessageCount READ getUnreadMessageCount NOTIFY unreadMessageCountChanged);
Q_PROPERTY(ContactModel *contact READ getContact NOTIFY contactChanged);
Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged);
Q_PROPERTY(int unreadMessageCount READ getUnreadMessageCount NOTIFY unreadMessageCountChanged);
Q_PROPERTY(bool isOneToOne MEMBER isOneToOne CONSTANT);
Q_PROPERTY(bool haveEncryption MEMBER haveEncryption CONSTANT);
Q_PROPERTY(int securityLevel MEMBER securityLevel CONSTANT);
public:
SipAddressObserver (const QString &peerAddress, const QString &localAddress);
SipAddressObserver (const QString &peerAddress, const QString &localAddress);
bool isOneToOne = true;
bool haveEncryption = false;
int securityLevel = 1;
signals:
void contactChanged (ContactModel *contact);
void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus);
void unreadMessageCountChanged (int unreadMessageCount);
void contactChanged (ContactModel *contact);
void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus);
void unreadMessageCountChanged (int unreadMessageCount);
private:
QString getPeerAddress () const {
return mPeerAddress;
}
QString getPeerAddress () const {
return mPeerAddress;
}
QString getLocalAddress () const {
return mLocalAddress;
}
QString getLocalAddress () const {
return mLocalAddress;
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
ContactModel *getContact () const {
return mContact;
}
ContactModel *getContact () const {
return mContact;
}
void setContact (ContactModel *contact);
void setContact (ContactModel *contact);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
Presence::PresenceStatus getPresenceStatus () const {
return mPresenceStatus;
}
Presence::PresenceStatus getPresenceStatus () const {
return mPresenceStatus;
}
void setPresenceStatus (const Presence::PresenceStatus &presenceStatus);
void setPresenceStatus (const Presence::PresenceStatus &presenceStatus);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
int getUnreadMessageCount () const {
return mUnreadMessageCount;
}
int getUnreadMessageCount () const {
return mUnreadMessageCount;
}
void setUnreadMessageCount (int unreadMessageCount);
void setUnreadMessageCount (int unreadMessageCount);
QString mPeerAddress;
QString mLocalAddress;
QString mPeerAddress;
QString mLocalAddress;
ContactModel *mContact = nullptr;
Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline;
int mUnreadMessageCount = 0;
ContactModel *mContact = nullptr;
Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline;
int mUnreadMessageCount = 0;
};
Q_DECLARE_METATYPE(SipAddressObserver *);

View file

@ -44,9 +44,7 @@ TimelineProxyModel::TimelineProxyModel (QObject *parent) : QSortFilterProxyModel
connect(model, &TimelineListModel::updated, this, &TimelineProxyModel::invalidate);
connect(model, &TimelineListModel::selectedChanged, this, &TimelineProxyModel::selectedChanged);
connect(model, &TimelineListModel::countChanged, this, &TimelineProxyModel::countChanged);
setSourceModel(model);
QObject::connect(accountSettingsModel, &AccountSettingsModel::defaultProxyChanged, this, [this]() {
dynamic_cast<TimelineListModel*>(sourceModel())->update();
invalidate();
@ -57,6 +55,8 @@ TimelineProxyModel::TimelineProxyModel (QObject *parent) : QSortFilterProxyModel
invalidate();// Invalidate and reload GUI if the model has been reset
//updateCurrentSelection();
});
setSourceModel(model);
sort(0);
}

View file

@ -61,10 +61,10 @@ Rectangle {
//username: UtilsCpp.getDisplayName(entry.sipAddress || entry.peerAddress )
username : entry != undefined ?(entry.contactModel != undefined ? entry.contactModel.vcard.username
:entry.username != undefined ?entry.username:
LinphoneUtils.getContactUsername(entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || '')
):''
:entry.username != undefined ?entry.username:
LinphoneUtils.getContactUsername(entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || '')
):''
visible:!groupChat.visible
Icon{
anchors.right: parent.right
@ -83,7 +83,7 @@ Rectangle {
icon:'chat_room'
iconSize: ContactStyle.contentHeight
visible: entry!=undefined && !entry.isOneToOne && entry.participants.count > 2
visible: entry!=undefined && entry.isOneToOne!=undefined && !entry.isOneToOne && entry.participants.count > 2
Icon{
anchors.right: parent.right
@ -103,9 +103,9 @@ Rectangle {
Layout.leftMargin: ContactStyle.spacing
sipAddress: (entry && item.showContactAddress
&& entry.isOneToOne && (entry.haveEncryption == undefined || !entry.haveEncryption)
? entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || ''
: '')
&& (entry.isOneToOne == undefined || entry.isOneToOne) && (entry.haveEncryption == undefined || !entry.haveEncryption)
? entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || ''
: '')
participants: entry && item.showContactAddress && sipAddress == '' && entry.isOneToOne ? entry.participants.addressesToString : ''
username: avatar.username
}

View file

@ -102,8 +102,9 @@ ScrollableListView {
entry: ({
sipAddress: sipAddressesView.interpretableSipAddress,
groupEnabled:false,
haveEncryption:false
isOneToOne:true,
haveEncryption:false,
securityLevel:1
})
}
@ -229,8 +230,8 @@ ScrollableListView {
Layout.fillHeight: true
Layout.fillWidth: true
showContactAddress: sipAddressesView.showContactAddress
//: '(Admin)' : One word for Admin(istrator)
//~ Context Little Header in one word for a column in participant
//: '(Admin)' : One word for Admin(istrator)
//~ Context Little Header in one word for a column in participant
statusText : showAdminStatus && modelData.adminStatus ? qsTr('participantsAdminHeader') : ''
entry: modelData
@ -261,7 +262,7 @@ ScrollableListView {
Switch{
anchors.verticalCenter: parent.verticalCenter
width:50
//Layout.preferredWidth: 50
//Layout.preferredWidth: 50
indicatorStyle: SwitchStyle.aux
visible: sipAddressesView.showSwitch
@ -270,7 +271,7 @@ ScrollableListView {
checked: modelData.adminStatus
onClicked: {
modelData.adminStatus = !checked
}
}
}
Repeater {
@ -282,7 +283,7 @@ ScrollableListView {
visible: {
var visible = sipAddressesView.actions[index].visible
return visible === undefined || visible
}
}
onClicked: {
sipAddressesView.actions[index].handler(contactView.entry)

View file

@ -13,17 +13,17 @@ import Common.Styles 1.0
ScrollableListView {
id: sipAddressesView
// ---------------------------------------------------------------------------
// Contains a list of: {
// icon: 'string',
// handler: function () { ... }
// }
property var actions: []
property string genSipAddress
// Optional parameters.
property string headerButtonDescription
property string headerButtonIcon
@ -33,23 +33,23 @@ ScrollableListView {
property bool showSwitch : false
property bool showSeparator : true
property bool isSelectable : true
property var switchHandler : function(checked, index){
}
readonly property string interpretableSipAddress: SipAddressesModel.interpretSipAddress(
genSipAddress, false
)
// ---------------------------------------------------------------------------
signal entryClicked (var entry, var index)
// ---------------------------------------------------------------------------
// Header.
// ---------------------------------------------------------------------------
header: MouseArea {
height: {
var height = headerButton.visible ? SipAddressesViewStyle.header.button.height : 0
@ -59,68 +59,69 @@ ScrollableListView {
return height
}
width: parent.width
// Workaround to handle mouse.
// Without it, the mouse can be given to items list when mouse is hover header.
hoverEnabled: true
cursorShape: Qt.ArrowCursor
Column {
anchors.fill: parent
spacing: 0
// -----------------------------------------------------------------------
// Default contact.
// -----------------------------------------------------------------------
Loader {
id: defaultContact
height: SipAddressesViewStyle.entry.height
width: parent.width
visible: sipAddressesView.interpretableSipAddress.length > 0
sourceComponent: Rectangle {
anchors.fill: parent
color: SipAddressesViewStyle.entry.color.normal
RowLayout {
anchors {
fill: parent
rightMargin: SipAddressesViewStyle.entry.rightMargin
}
spacing: 0
Contact {
id: contact
Layout.fillHeight: true
Layout.fillWidth: true
entry: ({
sipAddress: sipAddressesView.interpretableSipAddress,
groupEnabled:false,
haveEncryption:false
isOneToOne:true,
haveEncryption:false,
securityLevel:1
})
}
ActionBar {
id: defaultContactActionBar
iconSize: SipAddressesViewStyle.entry.iconSize
Repeater {
model: sipAddressesView.actions
ActionButton {
icon: modelData.icon
visible: {
var visible = sipAddressesView.actions[index].visible
return (visible === undefined || visible) && (modelData.secure==0 || UtilsCpp.hasCapability(sipAddressesView.interpretableSipAddress, LinphoneEnums.FriendCapabilityLimeX3Dh))
}
onClicked: sipAddressesView.actions[index].handler({
sipAddress: sipAddressesView.interpretableSipAddress
})
@ -138,140 +139,140 @@ ScrollableListView {
}
}
}
// -----------------------------------------------------------------------
// Header button.
// -----------------------------------------------------------------------
MouseArea {
id: headerButton
height: SipAddressesViewStyle.header.button.height
width: parent.width
visible: sipAddressesView.showHeader && !!sipAddressesView.headerButtonAction
onClicked: sipAddressesView.headerButtonAction(sipAddressesView.interpretableSipAddress)
Rectangle {
anchors.fill: parent
color: parent.pressed
? SipAddressesViewStyle.header.color.pressed
: SipAddressesViewStyle.header.color.normal
Text {
anchors {
left: parent.left
leftMargin: SipAddressesViewStyle.header.leftMargin
verticalCenter: parent.verticalCenter
}
font {
bold: true
pointSize: SipAddressesViewStyle.header.text.pointSize
}
color: headerButton.pressed
? SipAddressesViewStyle.header.text.color.pressed
: SipAddressesViewStyle.header.text.color.normal
text: sipAddressesView.headerButtonDescription
}
Icon {
anchors {
right: parent.right
rightMargin: SipAddressesViewStyle.header.rightMargin
verticalCenter: parent.verticalCenter
}
icon: sipAddressesView.headerButtonIcon
iconSize: SipAddressesViewStyle.header.iconSize
visible: icon.length > 0
}
}
}
}
}
// ---------------------------------------------------------------------------
// Entries.
// ---------------------------------------------------------------------------
delegate: Rectangle {
id: sipAddressEntry
color: SipAddressesViewStyle.entry.color.normal
height: SipAddressesViewStyle.entry.height
width: parent ? parent.width : 0
Rectangle {
id: indicator
anchors.left: parent.left
color: 'transparent'
height: parent.height
width: SipAddressesViewStyle.entry.indicator.width
}
MouseArea {
id: mouseArea
anchors.fill: parent
cursorShape: Qt.ArrowCursor
RowLayout {
anchors {
fill: parent
rightMargin: SipAddressesViewStyle.entry.rightMargin
}
spacing: 0
// ---------------------------------------------------------------------
// Contact or address info.
// ---------------------------------------------------------------------
Contact {
Layout.fillHeight: true
Layout.fillWidth: true
showContactAddress: sipAddressesView.showContactAddress
entry: $sipAddress
MouseArea {
anchors.fill: parent
onClicked: sipAddressesView.entryClicked($sipAddress.sipAddress, index)
}
}
// ---------------------------------------------------------------------
// Actions
// ---------------------------------------------------------------------
ActionBar {
iconSize: SipAddressesViewStyle.entry.iconSize
Switch{
anchors.verticalCenter: parent.verticalCenter
width:50
//Layout.preferredWidth: 50
//Layout.preferredWidth: 50
indicatorStyle: SwitchStyle.aux
visible: sipAddressesView.showSwitch
enabled:true
checked: false
onClicked: {
//checked = !checked
switchHandler(!checked, index)
}
}
Repeater {
model: sipAddressesView.actions
ActionButton {
icon: modelData.icon
tooltipText:modelData.tooltipText?modelData.tooltipText:''
@ -279,12 +280,12 @@ ScrollableListView {
var visible = sipAddressesView.actions[index].visible
return (visible === undefined || visible) && (modelData.secure==0 || !$sipAddress.contactModel || $sipAddress.contactModel.hasCapability(LinphoneEnums.FriendCapabilityLimeX3Dh))
}
onClicked: {
sipAddressesView.actions[index].handler($sipAddress)
}
Icon{
visible: modelData.secure>0
visible: modelData.secure>0
icon:modelData.secure === 2?'secure_level_2':'secure_level_1'
iconSize:15
anchors.right:parent.right
@ -296,7 +297,7 @@ ScrollableListView {
}
}
}
// Separator.
Rectangle {
color: SipAddressesViewStyle.entry.separator.color
@ -304,17 +305,17 @@ ScrollableListView {
width: parent.width
visible: sipAddressesView.showSeparator
}
// -------------------------------------------------------------------------
states: State {
when: mouseArea.containsMouse && sipAddressesView.isSelectable
PropertyChanges {
color: SipAddressesViewStyle.entry.color.hovered
target: sipAddressEntry
}
PropertyChanges {
color: SipAddressesViewStyle.entry.indicator.color
target: indicator