-
Ming Rui Zhang authored
Gitlab: #492 Change-Id: I8bab7bc1cd1f5bdbf7c6c54e615a21690dad1585
Ming Rui Zhang authoredGitlab: #492 Change-Id: I8bab7bc1cd1f5bdbf7c6c54e615a21690dad1585
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
contactadapter.cpp 7.54 KiB
/*
* Copyright (C) 2020 by Savoir-faire Linux
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "contactadapter.h"
#include "lrcinstance.h"
ContactAdapter::ContactAdapter(LRCInstance* instance, QObject* parent)
: QmlAdapterBase(instance, parent)
{
selectableProxyModel_.reset(new SelectableProxyModel(this));
if (lrcInstance_) {
connectSignals();
connect(lrcInstance_, &LRCInstance::currentAccountIdChanged, [this] { connectSignals(); });
}
}
QVariant
ContactAdapter::getContactSelectableModel(int type)
{
// Called from qml every time contact picker refreshes.
listModeltype_ = static_cast<SmartListModel::Type>(type);
if (listModeltype_ == SmartListModel::Type::CONVERSATION) {
defaultModerators_ = lrcInstance_->accountModel().getDefaultModerators(
lrcInstance_->get_currentAccountId());
}
smartListModel_.reset(new SmartListModel(this, listModeltype_, lrcInstance_));
selectableProxyModel_->setSourceModel(smartListModel_.get());
// Adjust filter.
switch (listModeltype_) {
case SmartListModel::Type::CONVERSATION:
selectableProxyModel_->setPredicate([this](const QModelIndex& index, const QRegExp&) {
return !defaultModerators_.contains(index.data(Role::URI).toString());
});
break;
case SmartListModel::Type::CONFERENCE:
selectableProxyModel_->setPredicate([](const QModelIndex& index, const QRegExp&) {
return index.data(Role::Presence).toBool();
});
break;
case SmartListModel::Type::TRANSFER:
selectableProxyModel_->setPredicate([this](const QModelIndex& index, const QRegExp& regexp) {
// Exclude current sip callee and filtered contact.
bool match = true;
const auto& conv = lrcInstance_->getConversationFromConvUid(
lrcInstance_->get_selectedConvUid());
if (!conv.participants.isEmpty()) {
QString calleeDisplayId = lrcInstance_
->getAccountInfo(lrcInstance_->get_currentAccountId())
.contactModel->bestIdForContact(conv.participants[0]);
QRegExp matchExcept = QRegExp(QString("\\b(?!" + calleeDisplayId + "\\b)\\w+"));
match = matchExcept.indexIn(index.data(Role::BestId).toString()) != -1;
}
if (match) {
match = regexp.indexIn(index.data(Role::BestId).toString()) != -1;
}
return match && !index.parent().isValid();
});
break;
default:
break;
}
selectableProxyModel_->invalidate();
return QVariant::fromValue(selectableProxyModel_.get());
}
void
ContactAdapter::setSearchFilter(const QString& filter)
{
if (listModeltype_ == SmartListModel::Type::CONFERENCE) {
smartListModel_->setConferenceableFilter(filter);
} else if (listModeltype_ == SmartListModel::Type::CONVERSATION) {
selectableProxyModel_->setPredicate(
[this, filter](const QModelIndex& index, const QRegExp&) {
return (!defaultModerators_.contains(index.data(Role::URI).toString())
&& index.data(Role::Title).toString().contains(filter));
});
}
selectableProxyModel_->setFilterRegExp(
QRegExp(filter, Qt::CaseInsensitive, QRegExp::FixedString));
}
void
ContactAdapter::contactSelected(int index)
{
auto contactIndex = selectableProxyModel_->index(index, 0);
auto* callModel = lrcInstance_->getCurrentCallModel();
const auto& convInfo = lrcInstance_->getConversationFromConvUid(
lrcInstance_->get_selectedConvUid());
if (contactIndex.isValid()) {
switch (listModeltype_) {
case SmartListModel::Type::CONFERENCE: {
// Conference.
const auto sectionName = contactIndex.data(Role::SectionName).value<QString>();
if (!sectionName.isEmpty()) {
smartListModel_->toggleSection(sectionName);
return;
}
const auto convUid = contactIndex.data(Role::UID).value<QString>();
const auto accId = contactIndex.data(Role::AccountId).value<QString>();
const auto callId = lrcInstance_->getCallIdForConversationUid(convUid, accId);
if (!callId.isEmpty()) {
if (convInfo.uid.isEmpty()) {
return;
}
auto thisCallId = convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
callModel->joinCalls(thisCallId, callId);
} else {
const auto contactUri = contactIndex.data(Role::URI).value<QString>();
auto call = lrcInstance_->getCallInfoForConversation(convInfo);
if (!call) {
return;
}
callModel->callAndAddParticipant(contactUri, call->id, call->isAudioOnly);
}
} break;
case SmartListModel::Type::TRANSFER: {
// SIP Transfer.
const auto contactUri = contactIndex.data(Role::URI).value<QString>();
if (convInfo.uid.isEmpty()) {
return;
}
const auto callId = convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
QString destCallId;
try {
// Check if the call exist - (check non-finished calls).
const auto callInfo = callModel->getCallFromURI(contactUri, true);
destCallId = callInfo.id;
} catch (std::exception& e) {
qDebug().noquote() << e.what();
destCallId = "";
}
// If no second call -> blind transfer.
// If there is a second call -> attended transfer.
if (destCallId.size() == 0) {
callModel->transfer(callId, "sip:" + contactUri);
} else {
callModel->transferToCall(callId, destCallId);
}
} break;
case SmartListModel::Type::CONVERSATION: {
const auto contactUri = contactIndex.data(Role::URI).value<QString>();
if (contactUri.isEmpty()) {
return;
}
lrcInstance_->accountModel().setDefaultModerator(lrcInstance_->get_currentAccountId(),
contactUri,
true);
Q_EMIT defaultModeratorsUpdated();
} break;
default:
break;
}
}
}
void
ContactAdapter::connectSignals()
{
connect(lrcInstance_->getCurrentContactModel(),
&ContactModel::bannedStatusChanged,
this,
&ContactAdapter::bannedStatusChanged,
Qt::UniqueConnection);
}