blob: fb837aa4b6afddae493c8e2ffca5702eb87287cc [file] [log] [blame]
Sébastien Blin1f915762020-08-03 13:27:42 -04001/*
2 * Copyright (C) 2020 by Savoir-faire Linux
3 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
4 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
5 * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "contactadapter.h"
22
23#include "lrcinstance.h"
24
25ContactAdapter::ContactAdapter(QObject *parent)
26 : QmlAdapterBase(parent)
27{
28 selectableProxyModel_.reset(new SelectableProxyModel(smartListModel_.get()));
29}
30
31ContactAdapter::~ContactAdapter() {}
32
33QVariant
34ContactAdapter::getContactSelectableModel(int type)
35{
36 /*
37 * Called from qml every time contact picker refreshes.
38 */
39 listModeltype_ = Utils::toEnum<SmartListModel::Type>(type);
40 smartListModel_.reset(new SmartListModel(LRCInstance::getCurrAccId(),
41 this,
42 listModeltype_,
43 LRCInstance::getCurrentConvUid()));
44 selectableProxyModel_->setSourceModel(smartListModel_.get());
45
46 /*
47 * Adjust filter.
48 */
49 switch (listModeltype_) {
50 case SmartListModel::Type::CONFERENCE:
51 selectableProxyModel_->setPredicate([this](const QModelIndex &index, const QRegExp &) {
52 return index.data(SmartListModel::Presence).toBool();
53 });
54 break;
55 case SmartListModel::Type::TRANSFER:
56 selectableProxyModel_->setPredicate([this](const QModelIndex &index, const QRegExp &regexp) {
57 /*
58 * Regex to remove current callee.
59 */
60 QRegExp matchExcept = QRegExp(QString("\\b(?!" + calleeDisplayName_ + "\\b)\\w+"));
61 bool match = false;
62 bool match_non_self = matchExcept.indexIn(
63 index.data(SmartListModel::Role::DisplayName).toString())
64 != -1;
65 if (match_non_self) {
66 match = regexp.indexIn(index.data(SmartListModel::Role::DisplayName).toString())
67 != -1;
68 }
69 return match && !index.parent().isValid();
70 });
71 break;
72 default:
73 break;
74 }
75 selectableProxyModel_->invalidate();
76
77 return QVariant::fromValue(selectableProxyModel_.get());
78}
79
80void
81ContactAdapter::setSearchFilter(const QString &filter)
82{
83 if (listModeltype_ == SmartListModel::Type::CONFERENCE) {
84 smartListModel_->setConferenceableFilter(filter);
85 }
86 selectableProxyModel_->setFilterRegExp(
87 QRegExp(filter, Qt::CaseInsensitive, QRegExp::FixedString));
88}
89
90void
91ContactAdapter::contactSelected(int index)
92{
93 auto contactIndex = selectableProxyModel_->index(index, 0);
94 auto callModel = LRCInstance::getCurrentCallModel();
95 auto conversation = LRCInstance::getCurrentConversation();
96
97 if (contactIndex.isValid()) {
98 switch (listModeltype_) {
99 case SmartListModel::Type::CONFERENCE: {
100 /*
101 * Conference.
102 */
103 auto sectionName = contactIndex.data(SmartListModel::Role::SectionName).value<QString>();
104 if (!sectionName.isEmpty()) {
105 smartListModel_->toggleSection(sectionName);
106 return;
107 }
108
109 auto convUid = contactIndex.data(SmartListModel::Role::UID).value<QString>();
110 auto accId = contactIndex.data(SmartListModel::Role::AccountId).value<QString>();
111 auto callId = LRCInstance::getCallIdForConversationUid(convUid, accId);
112
113 if (!callId.isEmpty()) {
114 if (conversation.uid.isEmpty()) {
115 return;
116 }
117 auto thisCallId = conversation.confId.isEmpty() ? conversation.callId
118 : conversation.confId;
119
120 callModel->joinCalls(thisCallId, callId);
121 } else {
122 auto contactUri = contactIndex.data(SmartListModel::Role::URI).value<QString>();
123 auto call = LRCInstance::getCallInfoForConversation(conversation);
124 if (!call) {
125 return;
126 }
127 callModel->callAndAddParticipant(contactUri, call->id, call->isAudioOnly);
128 }
129 } break;
130 case SmartListModel::Type::TRANSFER: {
131 /*
132 * SIP Transfer.
133 */
134 auto contactUri = contactIndex.data(SmartListModel::Role::URI).value<QString>();
135
136 if (conversation.uid.isEmpty()) {
137 return;
138 }
139 auto callId = conversation.confId.isEmpty() ? conversation.callId : conversation.confId;
140
141 QString destCallId;
142
143 try {
144 /*
145 * Check if the call exist - (check non-finished calls).
146 */
147 auto callInfo = callModel->getCallFromURI(contactUri, true);
148 destCallId = callInfo.id;
149 } catch (std::exception &e) {
150 qDebug().noquote() << e.what();
151 destCallId = "";
152 }
153 /*
154 * If no second call -> blind transfer.
155 * If there is a second call -> attended transfer.
156 */
157 if (destCallId.size() == 0) {
158 callModel->transfer(callId, "sip:" + contactUri);
159 callModel->hangUp(callId);
160 } else {
161 callModel->transferToCall(callId, destCallId);
162 callModel->hangUp(callId);
163 callModel->hangUp(destCallId);
164 }
165 } break;
166 default:
167 break;
168 }
169 }
170}
171
172void
173ContactAdapter::setCalleeDisplayName(const QString &name)
174{
175 calleeDisplayName_ = name;
176}
177
178void
179ContactAdapter::initQmlObject()
180{}