blob: 168aea1f49851c163bc346464e2079d33a1b109f [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"
27#include "accountmodel.h"
Edric Milaret67007d12015-05-07 09:40:09 -040028#include "categorizedcontactmodel.h"
29#include "windowscontactbackend.h"
Edric Milaret53f57b62015-05-11 11:02:17 -040030#include "historydelegate.h"
Edric Milaretdb76aa82015-05-11 16:01:00 -040031#include "contactdelegate.h"
Edric Milaret6a642e22015-05-27 15:06:30 -040032#include "localhistorycollection.h"
Edric Milaret1b197eb2015-06-01 15:09:56 -040033#include "media/text.h"
34#include "media/recording.h"
35#include "media/textrecording.h"
Edric Milaret627500d2015-03-27 16:41:40 -040036
Edric Milaret559bda52015-04-29 17:02:31 -040037#include "wizarddialog.h"
Edric Milaret627500d2015-03-27 16:41:40 -040038
39CallWidget::CallWidget(QWidget *parent) :
40 NavWidget(Main ,parent),
Edric Milaret7d40a4a2015-05-13 13:01:15 -040041 ui(new Ui::CallWidget),
42 menu_(new QMenu())
Edric Milaret627500d2015-03-27 16:41:40 -040043{
44 ui->setupUi(this);
45
46 ui->holdButton->setCheckable(true);
47 ui->muteMicButton->setCheckable(true);
48 ui->muteSpeakerButton->setCheckable(true);
49 ui->callInvite->setVisible(false);
50
Edric Milaret6456baa2015-05-21 12:18:07 -040051 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -040052 videoRenderer_ = nullptr;
53
54 try {
55 callModel_ = CallModel::instance();
56
57 connect(callModel_, SIGNAL(incomingCall(Call*)),
58 this, SLOT(callIncoming(Call*)));
59 connect(callModel_, SIGNAL(callAdded(Call*,Call*)),
60 this, SLOT(addedCall(Call*, Call*)));
61 connect(callModel_, SIGNAL(callStateChanged(Call*, Call::State)),
62 this, SLOT(callStateChanged(Call*, Call::State)));
63
Edric Milaret67007d12015-05-07 09:40:09 -040064 connect(AccountModel::instance()
65 , SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))
66 , this
67 , SLOT(findRingAccount(QModelIndex, QModelIndex, QVector<int>)));
68
Edric Milaret627500d2015-03-27 16:41:40 -040069 ui->callList->setModel(callModel_);
70
71 CategorizedHistoryModel::instance()->
Edric Milaret6a642e22015-05-27 15:06:30 -040072 addCollection<LocalHistoryCollection>(LoadOptions::FORCE_ENABLED);
Edric Milaret627500d2015-03-27 16:41:40 -040073
Edric Milaret67007d12015-05-07 09:40:09 -040074 PersonModel::instance()->
75 addCollection<FallbackPersonCollection>(LoadOptions::FORCE_ENABLED);
76
77 PersonModel::instance()->
78 addCollection<WindowsContactBackend>(LoadOptions::FORCE_ENABLED);
79
Edric Milaret12353822015-05-14 14:41:09 -040080 ui->historyList->setModel(CategorizedHistoryModel::SortedProxy::instance()->model());
81 CategorizedHistoryModel::SortedProxy::instance()->model()->sort(0, Qt::DescendingOrder);
Edric Milaret53f57b62015-05-11 11:02:17 -040082 ui->historyList->setHeaderHidden(true);
83 ui->historyList->setItemDelegate(new HistoryDelegate());
Edric Milaret12353822015-05-14 14:41:09 -040084 auto idx = CategorizedHistoryModel::SortedProxy::instance()->model()->index(0,0);
85 if (idx.isValid())
86 ui->historyList->setExpanded(idx, true);
Edric Milaret53f57b62015-05-11 11:02:17 -040087
Edric Milaret12353822015-05-14 14:41:09 -040088 ui->sortComboBox->setModel(CategorizedHistoryModel::SortedProxy::instance()->categoryModel());
Edric Milaret7d40a4a2015-05-13 13:01:15 -040089
Edric Milaret67007d12015-05-07 09:40:09 -040090 CategorizedContactModel::instance()->setSortAlphabetical(false);
91 ui->contactView->setModel(CategorizedContactModel::instance());
Edric Milaretdb76aa82015-05-11 16:01:00 -040092 ui->contactView->setItemDelegate(new ContactDelegate());
Edric Milaret53f57b62015-05-11 11:02:17 -040093
Edric Milaret627500d2015-03-27 16:41:40 -040094 ui->speakerSlider->setValue(Audio::Settings::instance()->playbackVolume());
95 ui->micSlider->setValue(Audio::Settings::instance()->captureVolume());
96
97 findRingAccount();
98
99 } catch (...) {
100 qDebug() << "INIT ERROR";
101 }
102}
103
104CallWidget::~CallWidget()
105{
106 delete ui;
107}
108
109void
Edric Milaret67007d12015-05-07 09:40:09 -0400110CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector<int> vec)
111{
112 Q_UNUSED(idx1)
113 Q_UNUSED(idx2)
114 Q_UNUSED(vec)
115
116 auto a_count = AccountModel::instance()->rowCount();
117 auto found = false;
118 for (int i = 0; i < a_count; ++i) {
119 auto idx = AccountModel::instance()->index(i, 0);
120 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
121 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
122 auto username = idx.data(static_cast<int>(Account::Role::Username));
123 ui->ringIdLabel->setText(
124 "Your Ring ID: " + username.toString());
125 found = true;
126 return;
127 }
128 }
129 if (not found){
130 ui->ringIdLabel->setText("NO RING ACCOUNT FOUND");
131 }
132}
133
134void
135CallWidget::findRingAccount()
136{
Edric Milaret559bda52015-04-29 17:02:31 -0400137
Edric Milaret627500d2015-03-27 16:41:40 -0400138 auto a_count = AccountModel::instance()->rowCount();
139 auto found = false;
140 for (int i = 0; i < a_count; ++i) {
141 auto idx = AccountModel::instance()->index(i, 0);
142 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
143 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
144 auto username = idx.data(static_cast<int>(Account::Role::Username));
145 ui->ringIdLabel->setText(
146 ui->ringIdLabel->text() + " " + username.toString());
147 found = true;
148 return;
149 }
150 }
151 if (!found) {
Edric Milaret559bda52015-04-29 17:02:31 -0400152 WizardDialog *wizardDialog = new WizardDialog();
153 wizardDialog->exec();
154 delete wizardDialog;
Edric Milaret627500d2015-03-27 16:41:40 -0400155 }
156}
157
158void
159CallWidget::callIncoming(Call *call)
160{
Edric Milaret435cdfc2015-06-01 16:15:50 -0400161 if (!call->account()->isAutoAnswer()) {
Edric Milaret627500d2015-03-27 16:41:40 -0400162 ui->callInvite->setVisible(true);
Edric Milaret435cdfc2015-06-01 16:15:50 -0400163 ui->callInvite->raise();
164 }
Edric Milaret6456baa2015-05-21 12:18:07 -0400165 setActualCall(call);
Edric Milaret627500d2015-03-27 16:41:40 -0400166}
167
168void
169CallWidget::on_acceptButton_clicked()
170{
171 if (actualCall_ != nullptr)
Edric Milaret53f57b62015-05-11 11:02:17 -0400172 actualCall_->performAction(Call::Action::ACCEPT);
Edric Milaret627500d2015-03-27 16:41:40 -0400173 ui->callInvite->setVisible(false);
174}
175
176void
177CallWidget::on_refuseButton_clicked()
178{
179 if (actualCall_ == nullptr)
180 return;
181 actualCall_->performAction(Call::Action::REFUSE);
Edric Milaret6456baa2015-05-21 12:18:07 -0400182 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -0400183 ui->callInvite->setVisible(false);
184}
185
186void
187CallWidget::on_holdButton_toggled(bool checked)
188{
189 Q_UNUSED(checked)
190 if (actualCall_ == nullptr)
191 return;
192 actualCall_->performAction(Call::Action::HOLD);
193}
194
195void
196CallWidget::on_hangupButton_clicked()
197{
198 if (actualCall_ == nullptr)
199 return;
200 actualCall_->performAction(Call::Action::REFUSE);
201}
202
203void
204CallWidget::addedCall(Call* call, Call* parent) {
205 Q_UNUSED(parent);
206 if (call->direction() == Call::Direction::OUTGOING) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400207 setActualCall(call);
Edric Milaret627500d2015-03-27 16:41:40 -0400208 }
209}
210
211void
Edric Milaret67007d12015-05-07 09:40:09 -0400212CallWidget::callStateChanged(Call* call, Call::State previousState)
213{
Edric Milaret627500d2015-03-27 16:41:40 -0400214 Q_UNUSED(previousState)
Edric Milaretb5b49072015-05-08 11:56:07 -0400215 if (call == nullptr)
216 return;
Edric Milaret627500d2015-03-27 16:41:40 -0400217 ui->callList->setCurrentIndex(callModel_->getIndex(actualCall_));
Edric Milaret6456baa2015-05-21 12:18:07 -0400218 if (call->state() == Call::State::OVER || call->state() == Call::State::ERROR) {
219 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -0400220 ui->videoWidget->hide();
Edric Milaret67007d12015-05-07 09:40:09 -0400221 } else if (call->state() == Call::State::HOLD) {
222 ui->videoWidget->hide();
Edric Milaret53f57b62015-05-11 11:02:17 -0400223 } else if (call->state() == Call::State::CURRENT) {
Edric Milaret627500d2015-03-27 16:41:40 -0400224 ui->videoWidget->show();
Edric Milaret627500d2015-03-27 16:41:40 -0400225 }
Edric Milaret67007d12015-05-07 09:40:09 -0400226 ui->callStateLabel->setText("Call State : " + state.at((int)call->state()));
Edric Milaret627500d2015-03-27 16:41:40 -0400227}
228
229void
Edric Milaret1b197eb2015-06-01 15:09:56 -0400230CallWidget::setMediaText(Call *call)
231{
232 if (call != nullptr) {
233 connect(call, SIGNAL(mediaAdded(Media::Media*)),
234 this, SLOT(mediaAdd(Media::Media*)));
235 Media::Text *textMedia = call->addOutgoingMedia<Media::Text>();
236 connect(ui->messageInput, &QLineEdit::returnPressed, [=]()
237 {
238 textMedia->send(ui->messageInput->text());
239 ui->messageInput->clear();
240 });
241 ui->messageInput->show();
242 } else {
243 ui->messageOutput->disconnect();
244 ui->messageInput->disconnect();
245 ui->messageOutput->hide();
246 ui->messageInput->hide();
247 }
248}
249
250void
251CallWidget::mediaAdd(Media::Media *media)
252{
253 switch(static_cast<int>(media->type())) {
254 case 0: /*AUDIO*/
255 break;
256 case 1: /*VIDEO*/
257 break;
258 case 2: /*TEXT*/
259 if (media->direction() == Media::Text::Direction::IN) {
260 ui->messageOutput->setModel(
261 static_cast<Media::Text*>(media)->recording()->
262 instantMessagingModel());
263 connect(ui->messageOutput->model(),
264 SIGNAL(rowsInserted(const QModelIndex&, int, int)),
265 ui->messageOutput, SLOT(scrollToBottom()));
266 ui->messageOutput->show();
267 }
268 break;
269 case 3: /*FILE*/
270 break;
271 }
272}
273
274void
Edric Milaret627500d2015-03-27 16:41:40 -0400275CallWidget::on_callList_activated(const QModelIndex &index)
276{
277 Call *callSelected = callModel_->getCall(index);
278 if (actualCall_ != nullptr) {
279 if (callSelected == actualCall_)
280 return;
Edric Milaret72c406d2015-04-28 13:23:54 -0400281 ui->videoWidget->hide();
Edric Milaret627500d2015-03-27 16:41:40 -0400282 actualCall_->performAction(Call::Action::HOLD);
283 }
Edric Milaret6456baa2015-05-21 12:18:07 -0400284 setActualCall(callSelected);
Edric Milaret627500d2015-03-27 16:41:40 -0400285 actualCall_->performAction(Call::Action::HOLD);
Edric Milaret72c406d2015-04-28 13:23:54 -0400286 ui->videoWidget->show();
Edric Milaret627500d2015-03-27 16:41:40 -0400287}
288
289void
290CallWidget::on_muteSpeakerButton_toggled(bool checked)
291{
292 Audio::Settings::instance()->mutePlayback(checked);
293}
294
295void
296CallWidget::on_muteMicButton_toggled(bool checked)
297{
298 Audio::Settings::instance()->muteCapture(checked);
299}
300
301void
302CallWidget::on_speakerSlider_sliderMoved(int position)
303{
304 outputVolume_ = position;
305}
306
307void
308CallWidget::on_speakerSlider_sliderReleased()
309{
310 emit Audio::Settings::instance()->setPlaybackVolume(outputVolume_);
311}
312
313void
314CallWidget::on_micSlider_sliderMoved(int position)
315{
316 inputVolume_ = position;
317}
318
319void
320CallWidget::on_micSlider_sliderReleased()
321{
322 emit Audio::Settings::instance()->setCaptureVolume(inputVolume_);
323}
324
325void
326CallWidget::atExit() {
327
328}
Edric Milaret67007d12015-05-07 09:40:09 -0400329
330void
331CallWidget::on_contactView_doubleClicked(const QModelIndex &index)
332{
Edric Milaret67007d12015-05-07 09:40:09 -0400333 QString uri;
334
Edric Milaret7d40a4a2015-05-13 13:01:15 -0400335 auto var = index.child(0,0).data(
336 static_cast<int>(Person::Role::Object));
337 if (var.isValid()) {
338 Person* person = var.value<Person*>();
339 if (person->phoneNumbers().size() > 0) {
340 uri = person->phoneNumbers().at(0)->uri();
Edric Milaret67007d12015-05-07 09:40:09 -0400341 }
342 }
343 if (not uri.isEmpty()) {
344 auto outCall = CallModel::instance()->dialingCall(uri);
345 outCall->setDialNumber(uri);
346 outCall->performAction(Call::Action::ACCEPT);
347 }
348}
Edric Milaret53f57b62015-05-11 11:02:17 -0400349
Edric Milaret6456baa2015-05-21 12:18:07 -0400350void
351CallWidget::on_historyList_doubleClicked(const QModelIndex &index)
Edric Milaret53f57b62015-05-11 11:02:17 -0400352{
Edric Milaret12353822015-05-14 14:41:09 -0400353 if (not index.isValid())
354 return;
355
Edric Milaret53f57b62015-05-11 11:02:17 -0400356 QString number = index.model()->data(index, static_cast<int>(Call::Role::Number)).toString();
357 if (not number.isEmpty()) {
358 auto outCall = CallModel::instance()->dialingCall(number);
359 outCall->setDialNumber(number);
360 outCall->performAction(Call::Action::ACCEPT);
361 }
362}
Edric Milaret6456baa2015-05-21 12:18:07 -0400363
364void
365CallWidget::setActualCall(Call* value)
366{
367 actualCall_ = value;
368 ui->holdButton->setEnabled(actualCall_ != nullptr);
369 ui->hangupButton->setEnabled(actualCall_ != nullptr);
Edric Milaret1b197eb2015-06-01 15:09:56 -0400370 ui->messageInput->setEnabled(actualCall_ != nullptr);
371 ui->messageOutput->setEnabled(actualCall_ != nullptr);
372 setMediaText(actualCall_);
Edric Milaret12353822015-05-14 14:41:09 -0400373}
374void
375CallWidget::on_sortComboBox_currentIndexChanged(int index)
376{
377 auto idx = CategorizedHistoryModel::SortedProxy::instance()->
378 categoryModel()->index(index, 0);
379 CategorizedHistoryModel::SortedProxy::instance()->categorySelectionModel()->
380 setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
381 ui->historyList->setModel(CategorizedHistoryModel::SortedProxy::instance()->model());
Edric Milaret6456baa2015-05-21 12:18:07 -0400382}