blob: 6c4625ddfa98cebd5c04d3e6c7a38dee651f300d [file] [log] [blame]
Edric Milaret627500d2015-03-27 16:41:40 -04001/***************************************************************************
Edric Milaret4bba46d2015-04-29 16:33:38 -04002 * Copyright (C) 2015 by Savoir-Faire Linux *
Edric Milaret627500d2015-03-27 16:41:40 -04003 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
19#include "callwidget.h"
20#include "ui_callwidget.h"
21
Edric Milaret53f57b62015-05-11 11:02:17 -040022#include <memory>
Edric Milaret627500d2015-03-27 16:41:40 -040023
Edric Milaret627500d2015-03-27 16:41:40 -040024#include "audio/settings.h"
25#include "personmodel.h"
26#include "fallbackpersoncollection.h"
Edric Milaret67007d12015-05-07 09:40:09 -040027#include "categorizedcontactmodel.h"
Edric Milaret6a642e22015-05-27 15:06:30 -040028#include "localhistorycollection.h"
Edric Milaret1b197eb2015-06-01 15:09:56 -040029#include "media/text.h"
30#include "media/recording.h"
31#include "media/textrecording.h"
Edric Milaret627500d2015-03-27 16:41:40 -040032
Edric Milaret559bda52015-04-29 17:02:31 -040033#include "wizarddialog.h"
Edric Milaret83b248c2015-06-02 11:42:23 -040034#include "windowscontactbackend.h"
Edric Milaret627500d2015-03-27 16:41:40 -040035
36CallWidget::CallWidget(QWidget *parent) :
37 NavWidget(Main ,parent),
Edric Milaret7d40a4a2015-05-13 13:01:15 -040038 ui(new Ui::CallWidget),
39 menu_(new QMenu())
Edric Milaret627500d2015-03-27 16:41:40 -040040{
41 ui->setupUi(this);
42
Edric Milaret627500d2015-03-27 16:41:40 -040043 ui->callInvite->setVisible(false);
Edric Milareta9f937f2015-06-01 17:10:34 -040044 ui->videoWidget->setVisible(false);
Edric Milaret627500d2015-03-27 16:41:40 -040045
Edric Milaret6456baa2015-05-21 12:18:07 -040046 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -040047 videoRenderer_ = nullptr;
48
Edric Milaret3aca8e32015-06-12 10:01:40 -040049 connect(ui->videoWidget, SIGNAL(setChatVisibility(bool)),
50 ui->instantMessagingWidget, SLOT(setVisible(bool)));
51
Edric Milaretc7ab5502015-06-15 11:18:02 -040052 ui->spinnerLabel->hide();
53 spinner_ = new QMovie(":/images/spinner.gif");
54 if (spinner_->isValid()) {
55 ui->spinnerLabel->setMovie(spinner_);
56 }
57
Edric Milaret627500d2015-03-27 16:41:40 -040058 try {
59 callModel_ = CallModel::instance();
60
61 connect(callModel_, SIGNAL(incomingCall(Call*)),
62 this, SLOT(callIncoming(Call*)));
63 connect(callModel_, SIGNAL(callAdded(Call*,Call*)),
64 this, SLOT(addedCall(Call*, Call*)));
65 connect(callModel_, SIGNAL(callStateChanged(Call*, Call::State)),
66 this, SLOT(callStateChanged(Call*, Call::State)));
67
Edric Milarete5afb072015-06-02 16:45:44 -040068 connect(AccountModel::instance(),
69 SIGNAL(accountStateChanged(Account*,Account::RegistrationState)),
70 this,
71 SLOT(checkRegistrationState(Account*,Account::RegistrationState)));
72
Edric Milaret67007d12015-05-07 09:40:09 -040073 connect(AccountModel::instance()
74 , SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))
75 , this
76 , SLOT(findRingAccount(QModelIndex, QModelIndex, QVector<int>)));
77
Edric Milaret627500d2015-03-27 16:41:40 -040078 ui->callList->setModel(callModel_);
Edric Milaret029b95a2015-06-09 09:51:44 -040079 ui->callList->setSelectionModel(callModel_->selectionModel());
Edric Milaret627500d2015-03-27 16:41:40 -040080
81 CategorizedHistoryModel::instance()->
Edric Milaret6a642e22015-05-27 15:06:30 -040082 addCollection<LocalHistoryCollection>(LoadOptions::FORCE_ENABLED);
Edric Milaret627500d2015-03-27 16:41:40 -040083
Edric Milaret67007d12015-05-07 09:40:09 -040084 PersonModel::instance()->
85 addCollection<FallbackPersonCollection>(LoadOptions::FORCE_ENABLED);
86
87 PersonModel::instance()->
88 addCollection<WindowsContactBackend>(LoadOptions::FORCE_ENABLED);
89
Edric Milaret12353822015-05-14 14:41:09 -040090 ui->historyList->setModel(CategorizedHistoryModel::SortedProxy::instance()->model());
91 CategorizedHistoryModel::SortedProxy::instance()->model()->sort(0, Qt::DescendingOrder);
Edric Milaret53f57b62015-05-11 11:02:17 -040092 ui->historyList->setHeaderHidden(true);
Edric Milaret01f23842015-06-22 14:46:01 -040093 historyDelegate_ = new HistoryDelegate();
94 ui->historyList->setItemDelegate(historyDelegate_);
Edric Milaret12353822015-05-14 14:41:09 -040095 auto idx = CategorizedHistoryModel::SortedProxy::instance()->model()->index(0,0);
96 if (idx.isValid())
97 ui->historyList->setExpanded(idx, true);
Edric Milaret53f57b62015-05-11 11:02:17 -040098
Edric Milaret12353822015-05-14 14:41:09 -040099 ui->sortComboBox->setModel(CategorizedHistoryModel::SortedProxy::instance()->categoryModel());
Edric Milaret7d40a4a2015-05-13 13:01:15 -0400100
Edric Milaret67007d12015-05-07 09:40:09 -0400101 CategorizedContactModel::instance()->setSortAlphabetical(false);
102 ui->contactView->setModel(CategorizedContactModel::instance());
Edric Milaret01f23842015-06-22 14:46:01 -0400103 contactDelegate_ = new ContactDelegate();
104 ui->contactView->setItemDelegate(contactDelegate_);
Edric Milaret53f57b62015-05-11 11:02:17 -0400105
Edric Milaret627500d2015-03-27 16:41:40 -0400106 findRingAccount();
107
108 } catch (...) {
109 qDebug() << "INIT ERROR";
110 }
111}
112
113CallWidget::~CallWidget()
114{
115 delete ui;
Edric Milaretc7ab5502015-06-15 11:18:02 -0400116 delete spinner_;
117 delete menu_;
Edric Milaret01f23842015-06-22 14:46:01 -0400118 delete historyDelegate_;
119 delete contactDelegate_;
Edric Milaret627500d2015-03-27 16:41:40 -0400120}
121
122void
Edric Milaret67007d12015-05-07 09:40:09 -0400123CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector<int> vec)
124{
125 Q_UNUSED(idx1)
126 Q_UNUSED(idx2)
127 Q_UNUSED(vec)
128
129 auto a_count = AccountModel::instance()->rowCount();
130 auto found = false;
131 for (int i = 0; i < a_count; ++i) {
132 auto idx = AccountModel::instance()->index(i, 0);
133 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
134 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
135 auto username = idx.data(static_cast<int>(Account::Role::Username));
136 ui->ringIdLabel->setText(
137 "Your Ring ID: " + username.toString());
138 found = true;
139 return;
140 }
141 }
142 if (not found){
143 ui->ringIdLabel->setText("NO RING ACCOUNT FOUND");
144 }
145}
146
147void
Edric Milarete5afb072015-06-02 16:45:44 -0400148CallWidget::checkRegistrationState(Account *account,
149 Account::RegistrationState state)
150{
151 Q_UNUSED(account);
152
153 QPixmap pm(20,20);
154 pm.fill();
155 QPainter p(&pm);
156 QPen pen(Qt::black, 2);
157 p.setPen(pen);
158 p.setRenderHint(QPainter::Antialiasing, true);
159
160 switch(state) {
161 case Account::RegistrationState::ERROR:
162 p.setBrush(Qt::red);
163 break;
164 case Account::RegistrationState::TRYING:
165 p.setBrush(Qt::yellow);
166 break;
167 case Account::RegistrationState::READY:
168 p.setBrush(Qt::green);
169 auto a_count = AccountModel::instance()->rowCount();
170 for (int i = 0; i < a_count; ++i) {
171 auto idx = AccountModel::instance()->index(i, 0);
172 auto stateAcc = idx.data(
173 static_cast<int>(Account::Role::RegistrationState));
174 if (stateAcc.value<Account::RegistrationState>()
175 != Account::RegistrationState::READY) {
176 checkRegistrationState(nullptr,
177 stateAcc.value<Account::RegistrationState>());
178 return;
179 }
180 }
181 break;
182 }
183 p.drawEllipse(3, 3, 16, 16);
184 ui->accountStateHintLabel->setPixmap(pm);
185 ui->accountStateHintLabel->show();
186}
187
188void
Edric Milaret67007d12015-05-07 09:40:09 -0400189CallWidget::findRingAccount()
190{
Edric Milaret559bda52015-04-29 17:02:31 -0400191
Edric Milaret627500d2015-03-27 16:41:40 -0400192 auto a_count = AccountModel::instance()->rowCount();
193 auto found = false;
194 for (int i = 0; i < a_count; ++i) {
195 auto idx = AccountModel::instance()->index(i, 0);
196 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
197 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
198 auto username = idx.data(static_cast<int>(Account::Role::Username));
199 ui->ringIdLabel->setText(
200 ui->ringIdLabel->text() + " " + username.toString());
201 found = true;
202 return;
203 }
204 }
205 if (!found) {
Edric Milaret559bda52015-04-29 17:02:31 -0400206 WizardDialog *wizardDialog = new WizardDialog();
207 wizardDialog->exec();
208 delete wizardDialog;
Edric Milaret627500d2015-03-27 16:41:40 -0400209 }
210}
211
212void
213CallWidget::callIncoming(Call *call)
214{
Edric Milaret435cdfc2015-06-01 16:15:50 -0400215 if (!call->account()->isAutoAnswer()) {
Edric Milaretd9ebe232015-06-15 10:44:49 -0400216 ui->callLabel->setText("Call from " + call->formattedName());
Edric Milaret627500d2015-03-27 16:41:40 -0400217 ui->callInvite->setVisible(true);
Edric Milaret435cdfc2015-06-01 16:15:50 -0400218 ui->callInvite->raise();
219 }
Edric Milaret6456baa2015-05-21 12:18:07 -0400220 setActualCall(call);
Edric Milaret627500d2015-03-27 16:41:40 -0400221}
222
223void
224CallWidget::on_acceptButton_clicked()
225{
226 if (actualCall_ != nullptr)
Edric Milaret53f57b62015-05-11 11:02:17 -0400227 actualCall_->performAction(Call::Action::ACCEPT);
Edric Milaret627500d2015-03-27 16:41:40 -0400228 ui->callInvite->setVisible(false);
229}
230
231void
232CallWidget::on_refuseButton_clicked()
233{
234 if (actualCall_ == nullptr)
235 return;
236 actualCall_->performAction(Call::Action::REFUSE);
Edric Milaret6456baa2015-05-21 12:18:07 -0400237 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -0400238 ui->callInvite->setVisible(false);
239}
240
241void
Edric Milaret627500d2015-03-27 16:41:40 -0400242CallWidget::addedCall(Call* call, Call* parent) {
243 Q_UNUSED(parent);
244 if (call->direction() == Call::Direction::OUTGOING) {
Edric Milaretc7ab5502015-06-15 11:18:02 -0400245 displaySpinner(true);
Edric Milaret6456baa2015-05-21 12:18:07 -0400246 setActualCall(call);
Edric Milaret627500d2015-03-27 16:41:40 -0400247 }
248}
249
250void
Edric Milaret67007d12015-05-07 09:40:09 -0400251CallWidget::callStateChanged(Call* call, Call::State previousState)
252{
Edric Milaret627500d2015-03-27 16:41:40 -0400253 Q_UNUSED(previousState)
Edric Milaretb5b49072015-05-08 11:56:07 -0400254 if (call == nullptr)
255 return;
Edric Milaret627500d2015-03-27 16:41:40 -0400256 ui->callList->setCurrentIndex(callModel_->getIndex(actualCall_));
Edric Milaretc7ab5502015-06-15 11:18:02 -0400257 if (call->state() == Call::State::OVER
258 || call->state() == Call::State::ERROR
259 || call->state() == Call::State::FAILURE
260 || call->state() == Call::State::ABORTED) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400261 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -0400262 ui->videoWidget->hide();
Edric Milaretc7ab5502015-06-15 11:18:02 -0400263 displaySpinner(false);
Edric Milaret53f57b62015-05-11 11:02:17 -0400264 } else if (call->state() == Call::State::CURRENT) {
Edric Milaretc7ab5502015-06-15 11:18:02 -0400265 displaySpinner(false);
Edric Milaret627500d2015-03-27 16:41:40 -0400266 ui->videoWidget->show();
Edric Milaret627500d2015-03-27 16:41:40 -0400267 }
Edric Milaretf25d3bd2015-06-04 10:23:24 -0400268 ui->callStateLabel->setText("Call State : " + call->toHumanStateName());
Edric Milaret627500d2015-03-27 16:41:40 -0400269}
270
271void
272CallWidget::on_callList_activated(const QModelIndex &index)
273{
274 Call *callSelected = callModel_->getCall(index);
275 if (actualCall_ != nullptr) {
276 if (callSelected == actualCall_)
277 return;
Edric Milaret72c406d2015-04-28 13:23:54 -0400278 ui->videoWidget->hide();
Edric Milaret627500d2015-03-27 16:41:40 -0400279 actualCall_->performAction(Call::Action::HOLD);
280 }
Edric Milaret6456baa2015-05-21 12:18:07 -0400281 setActualCall(callSelected);
Edric Milaret627500d2015-03-27 16:41:40 -0400282 actualCall_->performAction(Call::Action::HOLD);
Edric Milaret72c406d2015-04-28 13:23:54 -0400283 ui->videoWidget->show();
Edric Milaret627500d2015-03-27 16:41:40 -0400284}
285
286void
Edric Milaret627500d2015-03-27 16:41:40 -0400287CallWidget::atExit() {
288
289}
Edric Milaret67007d12015-05-07 09:40:09 -0400290
291void
292CallWidget::on_contactView_doubleClicked(const QModelIndex &index)
293{
Edric Milaret67007d12015-05-07 09:40:09 -0400294 QString uri;
295
Edric Milaret7d40a4a2015-05-13 13:01:15 -0400296 auto var = index.child(0,0).data(
297 static_cast<int>(Person::Role::Object));
298 if (var.isValid()) {
299 Person* person = var.value<Person*>();
300 if (person->phoneNumbers().size() > 0) {
301 uri = person->phoneNumbers().at(0)->uri();
Edric Milaret67007d12015-05-07 09:40:09 -0400302 }
303 }
304 if (not uri.isEmpty()) {
305 auto outCall = CallModel::instance()->dialingCall(uri);
306 outCall->setDialNumber(uri);
307 outCall->performAction(Call::Action::ACCEPT);
308 }
309}
Edric Milaret53f57b62015-05-11 11:02:17 -0400310
Edric Milaret6456baa2015-05-21 12:18:07 -0400311void
312CallWidget::on_historyList_doubleClicked(const QModelIndex &index)
Edric Milaret53f57b62015-05-11 11:02:17 -0400313{
Edric Milaret12353822015-05-14 14:41:09 -0400314 if (not index.isValid())
315 return;
316
Edric Milaret53f57b62015-05-11 11:02:17 -0400317 QString number = index.model()->data(index, static_cast<int>(Call::Role::Number)).toString();
318 if (not number.isEmpty()) {
319 auto outCall = CallModel::instance()->dialingCall(number);
320 outCall->setDialNumber(number);
321 outCall->performAction(Call::Action::ACCEPT);
322 }
323}
Edric Milaret6456baa2015-05-21 12:18:07 -0400324
325void
326CallWidget::setActualCall(Call* value)
327{
328 actualCall_ = value;
Edric Milaretcdc978b2015-06-04 11:25:12 -0400329 ui->instantMessagingWidget->setMediaText(actualCall_);
Edric Milaret12353822015-05-14 14:41:09 -0400330}
Edric Milaretcdc978b2015-06-04 11:25:12 -0400331
Edric Milaret12353822015-05-14 14:41:09 -0400332void
333CallWidget::on_sortComboBox_currentIndexChanged(int index)
334{
335 auto idx = CategorizedHistoryModel::SortedProxy::instance()->
336 categoryModel()->index(index, 0);
337 CategorizedHistoryModel::SortedProxy::instance()->categorySelectionModel()->
338 setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
339 ui->historyList->setModel(CategorizedHistoryModel::SortedProxy::instance()->model());
Edric Milaret6456baa2015-05-21 12:18:07 -0400340}
Edric Milaretc7ab5502015-06-15 11:18:02 -0400341
342void
343CallWidget::displaySpinner(bool display)
344{
345 display ? ui->spinnerLabel->show() : ui->spinnerLabel->hide();
346 if (ui->spinnerLabel->movie())
347 display ? ui->spinnerLabel->movie()->start() : ui->spinnerLabel->movie()->stop();
348}