blob: 49ed4e31ab057d7a1db1487f146f4e06bb5c31a8 [file] [log] [blame]
Edric Milaret627500d2015-03-27 16:41:40 -04001/***************************************************************************
Edric Milaretbab169d2016-01-07 15:13:33 -05002 * Copyright (C) 2015-2016 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 Milaret43f3c1e2015-07-16 17:52:47 -040022#include <QClipboard>
23
Edric Milaret53f57b62015-05-11 11:02:17 -040024#include <memory>
Edric Milaret627500d2015-03-27 16:41:40 -040025
Edric Milaret43f3c1e2015-07-16 17:52:47 -040026//ERROR is defined in windows.h
27#include "utils.h"
28#undef ERROR
Edric Milareta0ebd062016-01-13 12:18:23 -050029#undef interface
Edric Milaret43f3c1e2015-07-16 17:52:47 -040030
Edric Milaret627500d2015-03-27 16:41:40 -040031#include "audio/settings.h"
32#include "personmodel.h"
Edric Milaret43f3c1e2015-07-16 17:52:47 -040033#include "person.h"
Edric Milaret627500d2015-03-27 16:41:40 -040034#include "fallbackpersoncollection.h"
Edric Milaret67007d12015-05-07 09:40:09 -040035#include "categorizedcontactmodel.h"
Edric Milaret6a642e22015-05-27 15:06:30 -040036#include "localhistorycollection.h"
Edric Milaret1b197eb2015-06-01 15:09:56 -040037#include "media/text.h"
38#include "media/recording.h"
39#include "media/textrecording.h"
Edric Milareted0b2802015-10-01 15:10:02 -040040#include "recentmodel.h"
Edric Milaretab12d022015-12-04 16:09:44 -050041#include "contactmethod.h"
Edric Milareta0ebd062016-01-13 12:18:23 -050042#include "globalinstances.h"
Edric Milareted0b2802015-10-01 15:10:02 -040043
Edric Milaret559bda52015-04-29 17:02:31 -040044#include "wizarddialog.h"
Edric Milaret83b248c2015-06-02 11:42:23 -040045#include "windowscontactbackend.h"
Edric Milaret43f3c1e2015-07-16 17:52:47 -040046#include "contactpicker.h"
Edric Milaret2afd2bf2015-07-21 17:12:25 -040047#include "contactmethodpicker.h"
Edric Milaret2cf34292015-06-22 16:27:03 -040048#include "globalsystemtray.h"
Edric Milareted0b2802015-10-01 15:10:02 -040049#include "historydelegate.h"
50#include "contactdelegate.h"
51#include "smartlistdelegate.h"
Edric Milaretab12d022015-12-04 16:09:44 -050052#include "imdelegate.h"
Edric Milareta0ebd062016-01-13 12:18:23 -050053#include "pixbufmanipulator.h"
Edric Milaret627500d2015-03-27 16:41:40 -040054
Nicolas Jager97a21b42015-12-03 16:55:45 -050055CallWidget::CallWidget(QWidget* parent) :
Edric Milareted0b2802015-10-01 15:10:02 -040056 NavWidget(END ,parent),
Edric Milaret7d40a4a2015-05-13 13:01:15 -040057 ui(new Ui::CallWidget),
Edric Milaretab12d022015-12-04 16:09:44 -050058 menu_(new QMenu()),
59 imDelegate_(new ImDelegate())
Edric Milaret627500d2015-03-27 16:41:40 -040060{
Nicolas Jager97a21b42015-12-03 16:55:45 -050061 setMouseTracking(true);
62
Edric Milaret627500d2015-03-27 16:41:40 -040063 ui->setupUi(this);
64
Nicolas Jager97a21b42015-12-03 16:55:45 -050065 // TODO : add this in style sheet forms
66 QPalette palette;
67 palette.setColor(QPalette::WindowText, QColor(255,255,255));
68 ui->callerIdLabel->setPalette(palette);
69
70 QPalette palette2;
71 palette2.setColor(QPalette::WindowText, QColor(141,141,141));
72
73 ui->wantToTalkLabel->setPalette(palette2);
74 ui->outboundCallLabel->setPalette(palette2);
75 ui->cancelCallLabel->setPalette(palette2);
76 ui->acceptLabel->setPalette(palette2);
77 ui->refuseLabel->setPalette(palette2);
78
79 QFont font = ui->callerIdLabel->font();
80 font.setPointSize(20);
81
82 ui->callerIdLabel->setFont(font);
83 // end of TODO : add this in style sheet forms
84
Edric Milaret627500d2015-03-27 16:41:40 -040085 ui->callInvite->setVisible(false);
86
Edric Milaret6456baa2015-05-21 12:18:07 -040087 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -040088 videoRenderer_ = nullptr;
89
Edric Milaret3aca8e32015-06-12 10:01:40 -040090 connect(ui->videoWidget, SIGNAL(setChatVisibility(bool)),
91 ui->instantMessagingWidget, SLOT(setVisible(bool)));
92
Edric Milareted0b2802015-10-01 15:10:02 -040093 QPixmap logo(":/images/logo-ring-standard-coul.png");
94 ui->ringLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation));
95 ui->ringLogo->setAlignment(Qt::AlignHCenter);
96
Edric Milareta0ebd062016-01-13 12:18:23 -050097 GlobalInstances::setPixmapManipulator(std::unique_ptr<Interfaces::PixbufManipulator>(new Interfaces::PixbufManipulator()));
98
Edric Milaret627500d2015-03-27 16:41:40 -040099 try {
Edric Milareta3e47282015-10-23 15:20:30 -0400100 callModel_ = &CallModel::instance();
Edric Milaret627500d2015-03-27 16:41:40 -0400101
102 connect(callModel_, SIGNAL(incomingCall(Call*)),
103 this, SLOT(callIncoming(Call*)));
104 connect(callModel_, SIGNAL(callAdded(Call*,Call*)),
105 this, SLOT(addedCall(Call*, Call*)));
106 connect(callModel_, SIGNAL(callStateChanged(Call*, Call::State)),
107 this, SLOT(callStateChanged(Call*, Call::State)));
108
Edric Milareta3e47282015-10-23 15:20:30 -0400109 connect(&AccountModel::instance()
Edric Milaret67007d12015-05-07 09:40:09 -0400110 , SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))
111 , this
112 , SLOT(findRingAccount(QModelIndex, QModelIndex, QVector<int>)));
113
Edric Milaretfa05d972016-01-13 16:22:04 -0500114 RecentModel::instance().peopleProxy()->setFilterRole(static_cast<int>(Ring::Role::Name));
115 RecentModel::instance().peopleProxy()->setFilterCaseSensitivity(Qt::CaseInsensitive);
Edric Milareta3e47282015-10-23 15:20:30 -0400116 ui->smartList->setModel(RecentModel::instance().peopleProxy());
Edric Milareted0b2802015-10-01 15:10:02 -0400117 connect(ui->smartList->selectionModel(),
118 SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
119 this,
120 SLOT(smartListSelectionChanged(QItemSelection,QItemSelection)));
Nicolas Jager97a21b42015-12-03 16:55:45 -0500121
122 connect(ui->smartList, &QTreeView::entered, this, &CallWidget::on_entered);
123
Edric Milareted0b2802015-10-01 15:10:02 -0400124 smartListDelegate_ = new SmartListDelegate();
Nicolas Jager97a21b42015-12-03 16:55:45 -0500125 ui->smartList->setSmartListItemDelegate(smartListDelegate_);
Edric Milaret627500d2015-03-27 16:41:40 -0400126
Edric Milareta3e47282015-10-23 15:20:30 -0400127 PersonModel::instance().
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400128 addCollection<WindowsContactBackend>(LoadOptions::FORCE_ENABLED);
129
Edric Milareta3e47282015-10-23 15:20:30 -0400130 CategorizedContactModel::instance().setSortAlphabetical(false);
131 CategorizedContactModel::instance().setUnreachableHidden(true);
132 ui->contactView->setModel(&CategorizedContactModel::instance());
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400133 contactDelegate_ = new ContactDelegate();
134 ui->contactView->setItemDelegate(contactDelegate_);
135
Edric Milareta3e47282015-10-23 15:20:30 -0400136 CategorizedHistoryModel::instance().
Edric Milaret6a642e22015-05-27 15:06:30 -0400137 addCollection<LocalHistoryCollection>(LoadOptions::FORCE_ENABLED);
Edric Milaret627500d2015-03-27 16:41:40 -0400138
Edric Milareta3e47282015-10-23 15:20:30 -0400139 ui->historyList->setModel(CategorizedHistoryModel::SortedProxy::instance().model());
140 CategorizedHistoryModel::SortedProxy::instance().model()->sort(0, Qt::DescendingOrder);
Edric Milaret53f57b62015-05-11 11:02:17 -0400141 ui->historyList->setHeaderHidden(true);
Edric Milaret01f23842015-06-22 14:46:01 -0400142 historyDelegate_ = new HistoryDelegate();
143 ui->historyList->setItemDelegate(historyDelegate_);
Edric Milaret77dd6982015-07-07 16:45:41 -0400144
Edric Milareta3e47282015-10-23 15:20:30 -0400145 connect(CategorizedHistoryModel::SortedProxy::instance().model(), &QSortFilterProxyModel::layoutChanged, [=]() {
146 auto idx = CategorizedHistoryModel::SortedProxy::instance().model()->index(0,0);
Edric Milaret77dd6982015-07-07 16:45:41 -0400147 if (idx.isValid())
148 ui->historyList->setExpanded(idx, true);
149 });
150
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400151 ui->historyList->setContextMenuPolicy(Qt::CustomContextMenu);
152 connect(ui->historyList, &QListView::customContextMenuRequested, [=](const QPoint& pos){
153 if (ui->historyList->currentIndex().parent().isValid()) {
154 QPoint globalPos = ui->historyList->mapToGlobal(pos);
155 QMenu menu;
156
157 ContactMethod* contactMethod = ui->historyList->currentIndex()
158 .data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>();
159
Edric Milaret53ac6e52015-09-14 13:37:06 -0400160 auto copyAction = new QAction(tr("Copy number"), this);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400161 menu.addAction(copyAction);
162 connect(copyAction, &QAction::triggered, [=]() {
163 QApplication::clipboard()->setText(contactMethod->uri());
164 });
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400165 if (not contactMethod->contact() || contactMethod->contact()->isPlaceHolder()) {
Edric Milaret53ac6e52015-09-14 13:37:06 -0400166 auto addExisting = new QAction(tr("Add to contact"), this);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400167 menu.addAction(addExisting);
168 connect(addExisting, &QAction::triggered, [=]() {
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400169 ContactPicker contactPicker(contactMethod);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400170 contactPicker.move(globalPos.x(), globalPos.y() - (contactPicker.height()/2));
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400171 contactPicker.exec();
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400172 });
173 }
174 menu.exec(globalPos);
175 }
176 });
Edric Milaret53f57b62015-05-11 11:02:17 -0400177
Edric Milaret627500d2015-03-27 16:41:40 -0400178 findRingAccount();
Edric Milareta0ebd062016-01-13 12:18:23 -0500179 setupOutOfCallIM();
180 setupSmartListMenu();
Edric Milaret627500d2015-03-27 16:41:40 -0400181
Edric Milaret80e0b212015-10-16 10:07:43 -0400182 } catch (const std::exception& e) {
183 qDebug() << "INIT ERROR" << e.what();
Edric Milaret627500d2015-03-27 16:41:40 -0400184 }
185}
186
187CallWidget::~CallWidget()
188{
189 delete ui;
Edric Milaretc7ab5502015-06-15 11:18:02 -0400190 delete menu_;
Edric Milaret01f23842015-06-22 14:46:01 -0400191 delete contactDelegate_;
Edric Milaretab12d022015-12-04 16:09:44 -0500192 delete imDelegate_;
Edric Milaret627500d2015-03-27 16:41:40 -0400193}
194
195void
Edric Milareta0ebd062016-01-13 12:18:23 -0500196CallWidget::setupOutOfCallIM()
197{
198 ui->listMessageView->setItemDelegate(imDelegate_);
199 ui->listMessageView->setContextMenuPolicy(Qt::ActionsContextMenu);
200
201 auto copyAction = new QAction(tr("Copy"), this);
202 ui->listMessageView->addAction(copyAction);
203 connect(copyAction, &QAction::triggered, [=]() {
204 auto idx = ui->listMessageView->currentIndex();
205 if (idx.isValid()) {
206 auto text = ui->listMessageView->model()->data(idx);
207 QApplication::clipboard()->setText(text.value<QString>());
208 }
209 });
210 auto displayDate = new QAction(tr("Display date"), this);
211 displayDate->setCheckable(true);
212 ui->listMessageView->addAction(displayDate);
213 auto displayAuthor = new QAction(tr("Display author"), this);
214 displayAuthor->setCheckable(true);
215 ui->listMessageView->addAction(displayAuthor);
216 auto lamdba = [=](){
217 int opts = 0;
218 displayAuthor->isChecked() ? opts |= ImDelegate::DisplayOptions::AUTHOR : opts;
219 displayDate->isChecked() ? opts |= ImDelegate::DisplayOptions::DATE : opts;
220 imDelegate_->setDisplayOptions(static_cast<ImDelegate::DisplayOptions>(opts));
221 };
222 connect(displayAuthor, &QAction::triggered, lamdba);
223 connect(displayDate, &QAction::triggered, lamdba);
224}
225
226void
227CallWidget::setupSmartListMenu() {
228 ui->smartList->setContextMenuPolicy(Qt::CustomContextMenu);
229 connect(ui->smartList, &QListView::customContextMenuRequested, [=](const QPoint& pos){
230 auto idx = ui->smartList->currentIndex();
231 if (not idx.isValid())
232 return;
233 QPoint globalPos = ui->smartList->mapToGlobal(pos);
234 QMenu menu;
235
236 ContactMethod* contactMethod = RecentModel::instance()
237 .getContactMethods(RecentModel::instance().peopleProxy()->mapToSource(idx)).at(0);
238 if (not contactMethod)
239 return;
240 auto copyAction = new QAction(tr("Copy number"), this);
241 menu.addAction(copyAction);
242 connect(copyAction, &QAction::triggered, [=]() {
243 QApplication::clipboard()->setText(contactMethod->uri());
244 });
245 if (not contactMethod->contact() || contactMethod->contact()->isPlaceHolder()) {
246 auto addExisting = new QAction(tr("Add to contact"), this);
247 menu.addAction(addExisting);
248 connect(addExisting, &QAction::triggered, [=]() {
249 ContactPicker contactPicker(contactMethod);
250 contactPicker.move(globalPos.x(), globalPos.y() - (contactPicker.height()/2));
251 contactPicker.exec();
252 });
253 }
254 menu.exec(globalPos);
255 });
256}
257
258void
Edric Milaret67007d12015-05-07 09:40:09 -0400259CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector<int> vec)
260{
261 Q_UNUSED(idx1)
262 Q_UNUSED(idx2)
263 Q_UNUSED(vec)
264
Edric Milareta3e47282015-10-23 15:20:30 -0400265 auto a_count = AccountModel::instance().rowCount();
Edric Milaret67007d12015-05-07 09:40:09 -0400266 auto found = false;
267 for (int i = 0; i < a_count; ++i) {
Edric Milareta3e47282015-10-23 15:20:30 -0400268 auto idx = AccountModel::instance().index(i, 0);
Edric Milaret67007d12015-05-07 09:40:09 -0400269 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
270 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
271 auto username = idx.data(static_cast<int>(Account::Role::Username));
Edric Milareted0b2802015-10-01 15:10:02 -0400272 ui->ringIdLabel->setText(username.toString());
Edric Milaret67007d12015-05-07 09:40:09 -0400273 found = true;
274 return;
275 }
276 }
Nicolas Jager97a21b42015-12-03 16:55:45 -0500277 if (not found) {
Edric Milaret53ac6e52015-09-14 13:37:06 -0400278 ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
Edric Milaret67007d12015-05-07 09:40:09 -0400279 }
280}
281
282void
283CallWidget::findRingAccount()
284{
Edric Milaret559bda52015-04-29 17:02:31 -0400285
Edric Milareta3e47282015-10-23 15:20:30 -0400286 auto a_count = AccountModel::instance().rowCount();
Edric Milaret627500d2015-03-27 16:41:40 -0400287 auto found = false;
288 for (int i = 0; i < a_count; ++i) {
Edric Milareta3e47282015-10-23 15:20:30 -0400289 auto idx = AccountModel::instance().index(i, 0);
Edric Milaret627500d2015-03-27 16:41:40 -0400290 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
291 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
Edric Milareta3e47282015-10-23 15:20:30 -0400292 auto account = AccountModel::instance().getAccountByModelIndex(idx);
Edric Milaret68779c42015-07-09 16:53:03 -0400293 if (account->displayName().isEmpty())
294 account->displayName() = account->alias();
295 auto username = account->username();
Edric Milareted0b2802015-10-01 15:10:02 -0400296 ui->ringIdLabel->setText(username);
Edric Milaret627500d2015-03-27 16:41:40 -0400297 found = true;
298 return;
299 }
300 }
301 if (!found) {
Edric Milareted0b2802015-10-01 15:10:02 -0400302 ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
Edric Milaret559bda52015-04-29 17:02:31 -0400303 WizardDialog *wizardDialog = new WizardDialog();
304 wizardDialog->exec();
305 delete wizardDialog;
Edric Milaret627500d2015-03-27 16:41:40 -0400306 }
307}
308
309void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500310CallWidget::callIncoming(Call* call)
Edric Milaret627500d2015-03-27 16:41:40 -0400311{
Nicolas Jager97a21b42015-12-03 16:55:45 -0500312 ui->outboundCall->hide();
313
Edric Milaret2cf34292015-06-22 16:27:03 -0400314 if (!QApplication::activeWindow()) {
315 GlobalSystemTray::instance().showMessage("Ring", "Call incoming from " + call->formattedName());
316 QApplication::alert(this, 5000);
317 }
318
Edric Milaret435cdfc2015-06-01 16:15:50 -0400319 if (!call->account()->isAutoAnswer()) {
Nicolas Jager97a21b42015-12-03 16:55:45 -0500320 ui->callerIdLabel->setText(QString(tr("%1", "%1 is the name of the caller"))
Edric Milareta0ebd062016-01-13 12:18:23 -0500321 .arg(call->formattedName()));
Edric Milareted0b2802015-10-01 15:10:02 -0400322 ui->stackedWidget->setCurrentWidget(ui->callInvitePage);
Edric Milaret627500d2015-03-27 16:41:40 -0400323 ui->callInvite->setVisible(true);
Edric Milaret435cdfc2015-06-01 16:15:50 -0400324 ui->callInvite->raise();
325 }
Edric Milaret6456baa2015-05-21 12:18:07 -0400326 setActualCall(call);
Edric Milaret627500d2015-03-27 16:41:40 -0400327}
328
329void
330CallWidget::on_acceptButton_clicked()
331{
332 if (actualCall_ != nullptr)
Edric Milaret53f57b62015-05-11 11:02:17 -0400333 actualCall_->performAction(Call::Action::ACCEPT);
Edric Milaret627500d2015-03-27 16:41:40 -0400334 ui->callInvite->setVisible(false);
Edric Milareted0b2802015-10-01 15:10:02 -0400335 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milaret627500d2015-03-27 16:41:40 -0400336}
337
338void
339CallWidget::on_refuseButton_clicked()
340{
341 if (actualCall_ == nullptr)
342 return;
343 actualCall_->performAction(Call::Action::REFUSE);
Edric Milaret6456baa2015-05-21 12:18:07 -0400344 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -0400345 ui->callInvite->setVisible(false);
Edric Milareted0b2802015-10-01 15:10:02 -0400346 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Edric Milaret627500d2015-03-27 16:41:40 -0400347}
348
349void
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400350CallWidget::addedCall(Call* call, Call* parent)
351{
Edric Milaret627500d2015-03-27 16:41:40 -0400352 Q_UNUSED(parent);
353 if (call->direction() == Call::Direction::OUTGOING) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400354 setActualCall(call);
Edric Milareted0b2802015-10-01 15:10:02 -0400355 ui->stackedWidget->setCurrentWidget(ui->callInvitePage);
Edric Milaret627500d2015-03-27 16:41:40 -0400356 }
357}
358
359void
Edric Milaret67007d12015-05-07 09:40:09 -0400360CallWidget::callStateChanged(Call* call, Call::State previousState)
361{
Edric Milaret627500d2015-03-27 16:41:40 -0400362 Q_UNUSED(previousState)
Edric Milaret4b1be4a2016-01-15 16:49:20 -0500363 if (call == nullptr
364 || call != actualCall_)
Edric Milaretb5b49072015-05-08 11:56:07 -0400365 return;
Edric Milareted0b2802015-10-01 15:10:02 -0400366
Edric Milaret4b1be4a2016-01-15 16:49:20 -0500367 if (call->state() == Call::State::OVER) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400368 setActualCall(nullptr);
Edric Milaretc54e2272015-10-01 10:14:00 -0400369 ui->instantMessagingWidget->setMediaText(nullptr);
Edric Milareted0b2802015-10-01 15:10:02 -0400370 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Edric Milareta0ebd062016-01-13 12:18:23 -0500371 //TODO : Link this so that recentModel get selected correctly
372 // auto onHoldCall = callModel_->getActiveCalls().first();
373 // if (onHoldCall != nullptr && onHoldCall->state() == Call::State::HOLD) {
374 // setActualCall(onHoldCall);
375 // onHoldCall->performAction(Call::Action::HOLD);
376 // }
Edric Milaret53f57b62015-05-11 11:02:17 -0400377 } else if (call->state() == Call::State::CURRENT) {
Edric Milaretc54e2272015-10-01 10:14:00 -0400378 ui->instantMessagingWidget->setMediaText(actualCall_);
Edric Milareted0b2802015-10-01 15:10:02 -0400379 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milaret627500d2015-03-27 16:41:40 -0400380 }
Edric Milaret627500d2015-03-27 16:41:40 -0400381}
382
383void
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400384CallWidget::atExit()
385{
Edric Milaret627500d2015-03-27 16:41:40 -0400386}
Edric Milaret67007d12015-05-07 09:40:09 -0400387
388void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500389CallWidget::on_contactView_doubleClicked(const QModelIndex& index)
Edric Milaret67007d12015-05-07 09:40:09 -0400390{
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400391 if (not index.isValid())
392 return;
393
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400394 ContactMethod* uri = nullptr;
Edric Milaret67007d12015-05-07 09:40:09 -0400395
Edric Milaret7d40a4a2015-05-13 13:01:15 -0400396 auto var = index.child(0,0).data(
397 static_cast<int>(Person::Role::Object));
398 if (var.isValid()) {
399 Person* person = var.value<Person*>();
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400400 if (person->phoneNumbers().size() == 1) {
401 uri = person->phoneNumbers().at(0);
402 } else if (person->phoneNumbers().size() > 1) {
403 ContactMethodPicker dlg(person->phoneNumbers());
404 auto pos = QCursor::pos();
405 dlg.move(pos.x(), pos.y());
406 if (dlg.exec())
407 uri = dlg.getSelected();
408 }
409 if (uri) {
Edric Milareta3e47282015-10-23 15:20:30 -0400410 auto outCall = CallModel::instance().dialingCall(uri);
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400411 outCall->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400412 ui->mainTabMenu->setCurrentIndex(0);
413 ui->smartList->setFocus();
Edric Milaret67007d12015-05-07 09:40:09 -0400414 }
415 }
Edric Milaret67007d12015-05-07 09:40:09 -0400416}
Edric Milaret53f57b62015-05-11 11:02:17 -0400417
Edric Milaret6456baa2015-05-21 12:18:07 -0400418void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500419CallWidget::on_historyList_doubleClicked(const QModelIndex& index)
Edric Milaret53f57b62015-05-11 11:02:17 -0400420{
Edric Milaret12353822015-05-14 14:41:09 -0400421 if (not index.isValid())
422 return;
423
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400424 auto number = index.data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>();
425 if (number) {
Edric Milareta3e47282015-10-23 15:20:30 -0400426 auto outCall = CallModel::instance().dialingCall(number);
Edric Milaret53f57b62015-05-11 11:02:17 -0400427 outCall->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400428 ui->mainTabMenu->setCurrentIndex(0);
429 ui->smartList->setFocus();
Edric Milaret53f57b62015-05-11 11:02:17 -0400430 }
431}
Edric Milaret6456baa2015-05-21 12:18:07 -0400432
433void
434CallWidget::setActualCall(Call* value)
435{
436 actualCall_ = value;
Edric Milaret80e0b212015-10-16 10:07:43 -0400437 CallModel::instance().selectCall(value);
438 ui->videoWidget->pushRenderer(value);
Edric Milaret6456baa2015-05-21 12:18:07 -0400439}
Edric Milaretc7ab5502015-06-15 11:18:02 -0400440
441void
Edric Milareted0b2802015-10-01 15:10:02 -0400442CallWidget::on_cancelButton_clicked()
Edric Milaretd8528fa2015-07-07 14:13:51 -0400443{
444 if (actualCall_)
445 actualCall_->performAction(Call::Action::REFUSE);
446}
Edric Milareted0b2802015-10-01 15:10:02 -0400447
448void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500449CallWidget::on_smartList_doubleClicked(const QModelIndex& index)
Edric Milareted0b2802015-10-01 15:10:02 -0400450{
Edric Milareta3e47282015-10-23 15:20:30 -0400451 auto realIndex = RecentModel::instance().peopleProxy()->mapToSource(index);
452 if (RecentModel::instance().hasActiveCall(realIndex))
Edric Milareted0b2802015-10-01 15:10:02 -0400453 return;
454
455 ContactMethod* m = nullptr;
456 if (auto cm = realIndex.data((int)Call::Role::ContactMethod).value<ContactMethod*>()) {
457 m = cm;
458 } else {
459 if (auto person = realIndex.data((int)Person::Role::Object).value<Person*>()) {
460 m = person->phoneNumbers().first();
461 }
462 }
Edric Milareta3e47282015-10-23 15:20:30 -0400463 if (m && !RecentModel::instance().index(0, 0, realIndex).isValid()) {
464 Call* c = CallModel::instance().dialingCall(m);
Edric Milareted0b2802015-10-01 15:10:02 -0400465 c->performAction(Call::Action::ACCEPT);
466 }
467}
468
469void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500470CallWidget::smartListSelectionChanged(const QItemSelection& newSel, const QItemSelection& oldSel) {
Edric Milareted0b2802015-10-01 15:10:02 -0400471
472 Q_UNUSED(oldSel)
473
Edric Milaretab12d022015-12-04 16:09:44 -0500474 if (newSel.indexes().empty())
475 {
476 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
477 return;
478 }
Edric Milareted0b2802015-10-01 15:10:02 -0400479 auto newIdx = newSel.indexes().first();
Edric Milaret80e0b212015-10-16 10:07:43 -0400480 if (not newIdx.isValid())
Edric Milareted0b2802015-10-01 15:10:02 -0400481 return;
482
Edric Milaretab12d022015-12-04 16:09:44 -0500483 auto nodeIdx = RecentModel::instance().peopleProxy()->mapToSource(newIdx);
484 auto newIdxCall = RecentModel::instance().getActiveCall(nodeIdx);
Edric Milareted0b2802015-10-01 15:10:02 -0400485
Edric Milareta0ebd062016-01-13 12:18:23 -0500486 if (newIdxCall && newIdxCall != actualCall_) {
Edric Milareted0b2802015-10-01 15:10:02 -0400487 setActualCall(newIdxCall);
488 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milareta0ebd062016-01-13 12:18:23 -0500489 } else if (newIdxCall == nullptr){
490 setActualCall(nullptr);
491 showIMOutOfCall();
Edric Milareted0b2802015-10-01 15:10:02 -0400492 } else {
493 setActualCall(nullptr);
494 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
495 }
496}
497
498void
499CallWidget::placeCall()
500{
Nicolas Jager97a21b42015-12-03 16:55:45 -0500501 if (ui->ringContactLineEdit->text().isEmpty())
Edric Milareted0b2802015-10-01 15:10:02 -0400502 return;
Nicolas Jager97a21b42015-12-03 16:55:45 -0500503 Call* c = CallModel::instance().dialingCall(PhoneDirectoryModel::instance().getNumber(ui->ringContactLineEdit->text()));
Edric Milareted0b2802015-10-01 15:10:02 -0400504 c->performAction(Call::Action::ACCEPT);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500505 ui->ringContactLineEdit->clear();
Edric Milareted0b2802015-10-01 15:10:02 -0400506}
507
508void
Edric Milaret33cb4832016-01-08 10:14:14 -0500509CallWidget::settingsButton_clicked()
Edric Milareted0b2802015-10-01 15:10:02 -0400510{
511 emit NavigationRequested(ScreenEnum::ConfScreen);
512}
513
514void
Edric Milaret33cb4832016-01-08 10:14:14 -0500515CallWidget::contactButton_clicked(bool checked)
Edric Milareted0b2802015-10-01 15:10:02 -0400516{
Edric Milareted0b2802015-10-01 15:10:02 -0400517 ui->mainTabMenu->setCurrentIndex(checked ? 1 : 0);
518}
519
520void
Edric Milaret33cb4832016-01-08 10:14:14 -0500521CallWidget::historicButton_clicked(bool checked)
Edric Milareted0b2802015-10-01 15:10:02 -0400522{
Edric Milareted0b2802015-10-01 15:10:02 -0400523 ui->mainTabMenu->setCurrentIndex(checked ? 2 : 0);
524}
Nicolas Jager97a21b42015-12-03 16:55:45 -0500525
526void
527CallWidget::on_ringContactLineEdit_returnPressed()
528{
529 placeCall();
530}
531
532void
533CallWidget::on_btnCall_clicked()
534{
535 placeCall();
536}
537
538void
539CallWidget::on_btnvideo_clicked()
540{
541 if (not highLightedIndex_.isValid())
542 return;
543
544 on_smartList_doubleClicked(highLightedIndex_);
545}
Edric Milaretab12d022015-12-04 16:09:44 -0500546
547void
Edric Milareta0ebd062016-01-13 12:18:23 -0500548CallWidget::showIMOutOfCall()
Edric Milaretab12d022015-12-04 16:09:44 -0500549{
550 if (not highLightedIndex_.isValid())
551 return;
552
553 ui->smartList->selectionModel()->select(highLightedIndex_, QItemSelectionModel::ClearAndSelect);
554
555 ui->contactMethodComboBox->clear();
556
557 auto nodeIdx = RecentModel::instance().peopleProxy()->mapToSource(highLightedIndex_);
Edric Milareta0ebd062016-01-13 12:18:23 -0500558 ui->imNameLabel->setText(QString(tr("Conversation with %1", "%1 is the contact name"))
559 .arg(nodeIdx.data(static_cast<int>(Ring::Role::Name)).toString()));
Edric Milaretab12d022015-12-04 16:09:44 -0500560 auto cmVector = RecentModel::instance().getContactMethods(nodeIdx);
Edric Milareta0ebd062016-01-13 12:18:23 -0500561 ui->contactMethodComboBox->setEnabled(cmVector.size() > 1);
Edric Milaretab12d022015-12-04 16:09:44 -0500562 foreach (const ContactMethod* cm, cmVector) {
Edric Milareta0ebd062016-01-13 12:18:23 -0500563 ui->contactMethodComboBox->addItem(cm->uri());
Edric Milaretab12d022015-12-04 16:09:44 -0500564 }
565
Edric Milareta0ebd062016-01-13 12:18:23 -0500566 ui->stackedWidget->setCurrentWidget(ui->messagingPage);
Edric Milaretab12d022015-12-04 16:09:44 -0500567}
568
569void
570CallWidget::on_sendButton_clicked()
571{
Edric Milareta0ebd062016-01-13 12:18:23 -0500572 if (ui->messageEdit->text().trimmed().isEmpty())
Edric Milaretab12d022015-12-04 16:09:44 -0500573 return;
574 auto number = ui->contactMethodComboBox->currentText();
575 if (auto cm = PhoneDirectoryModel::instance().getNumber(number)) {
576 QMap<QString, QString> msg;
577 msg["text/plain"] = ui->messageEdit->text();
578 cm->sendOfflineTextMessage(msg);
579 ui->messageEdit->clear();
580 } else {
581 qWarning() << "Contact Method not found for " << number;
582 }
583}
584
585void
586CallWidget::on_messageEdit_returnPressed()
587{
588 on_sendButton_clicked();
589}
590
591void
592CallWidget::on_contactMethodComboBox_currentIndexChanged(const QString& number)
593{
594 auto cm = PhoneDirectoryModel::instance().getNumber(number);
595 if (auto txtRecording = cm->textRecording()) {
596 ui->listMessageView->setModel(txtRecording->instantMessagingModel());
597 disconnect(imConnection_);
598 imConnection_ = connect(txtRecording,
Edric Milareta0ebd062016-01-13 12:18:23 -0500599 SIGNAL(messageInserted(QMap<QString,QString>,ContactMethod*,Media::Media::Direction)),
600 this,
601 SLOT(slotAccountMessageReceived(QMap<QString,QString>,ContactMethod*,Media::Media::Direction)));
Edric Milaretab12d022015-12-04 16:09:44 -0500602 ui->listMessageView->scrollToBottom();
603 }
604}
605
606void
607CallWidget::slotAccountMessageReceived(const QMap<QString,QString> message,
608 ContactMethod* cm,
609 Media::Media::Direction dir)
610{
611 Q_UNUSED(message)
612 Q_UNUSED(cm)
613 Q_UNUSED(dir)
614
615 ui->listMessageView->scrollToBottom();
616}
Edric Milaretfa05d972016-01-13 16:22:04 -0500617
618void
619CallWidget::on_ringContactLineEdit_textEdited(const QString& text)
620{
621 RecentModel::instance().peopleProxy()->setFilterWildcard(text);
622}
Edric Milareta0ebd062016-01-13 12:18:23 -0500623
624void CallWidget::on_imBackButton_clicked()
625{
626 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
627}