blob: be76d4fa0857ec437c1da69b9dc671d25a9c155d [file] [log] [blame]
Edric Milaret627500d2015-03-27 16:41:40 -04001/***************************************************************************
Nicolas Jager45bf7c02016-01-20 09:53:02 -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"
Edric Milaret00a32252016-01-19 10:37:13 -050039#include "media/recordingmodel.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 Jagerca850292016-01-17 14:11:10 -050065 welcomePageAnim_ = new QPropertyAnimation(ui->welcomePage, "pos", this);
66 messagingPageAnim_ = new QPropertyAnimation(ui->messagingPage, "pos", this);
67
Edric Milaret6456baa2015-05-21 12:18:07 -040068 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -040069 videoRenderer_ = nullptr;
70
Edric Milaret3aca8e32015-06-12 10:01:40 -040071 connect(ui->videoWidget, SIGNAL(setChatVisibility(bool)),
72 ui->instantMessagingWidget, SLOT(setVisible(bool)));
73
Edric Milareted0b2802015-10-01 15:10:02 -040074 QPixmap logo(":/images/logo-ring-standard-coul.png");
75 ui->ringLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation));
76 ui->ringLogo->setAlignment(Qt::AlignHCenter);
77
Edric Milareta0ebd062016-01-13 12:18:23 -050078 GlobalInstances::setPixmapManipulator(std::unique_ptr<Interfaces::PixbufManipulator>(new Interfaces::PixbufManipulator()));
79
Edric Milaret627500d2015-03-27 16:41:40 -040080 try {
Edric Milareta3e47282015-10-23 15:20:30 -040081 callModel_ = &CallModel::instance();
Edric Milaret627500d2015-03-27 16:41:40 -040082
83 connect(callModel_, SIGNAL(incomingCall(Call*)),
84 this, SLOT(callIncoming(Call*)));
85 connect(callModel_, SIGNAL(callAdded(Call*,Call*)),
86 this, SLOT(addedCall(Call*, Call*)));
87 connect(callModel_, SIGNAL(callStateChanged(Call*, Call::State)),
88 this, SLOT(callStateChanged(Call*, Call::State)));
89
Edric Milareta3e47282015-10-23 15:20:30 -040090 connect(&AccountModel::instance()
Edric Milaret67007d12015-05-07 09:40:09 -040091 , SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))
92 , this
93 , SLOT(findRingAccount(QModelIndex, QModelIndex, QVector<int>)));
94
Edric Milaretfa05d972016-01-13 16:22:04 -050095 RecentModel::instance().peopleProxy()->setFilterRole(static_cast<int>(Ring::Role::Name));
96 RecentModel::instance().peopleProxy()->setFilterCaseSensitivity(Qt::CaseInsensitive);
Edric Milareta3e47282015-10-23 15:20:30 -040097 ui->smartList->setModel(RecentModel::instance().peopleProxy());
Edric Milaret6816fd72016-01-29 16:36:24 -050098 connect(ui->smartList->selectionModel(),
99 SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
100 this,
101 SLOT(smartListSelectionChanged(QItemSelection,QItemSelection)));
102
103 connect(ui->smartList, &QTreeView::entered, this, &CallWidget::on_entered);
104
105 smartListDelegate_ = new SmartListDelegate();
106 ui->smartList->setSmartListItemDelegate(smartListDelegate_);
Edric Milaret627500d2015-03-27 16:41:40 -0400107
Edric Milareta3e47282015-10-23 15:20:30 -0400108 PersonModel::instance().
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400109 addCollection<WindowsContactBackend>(LoadOptions::FORCE_ENABLED);
110
Edric Milareta3e47282015-10-23 15:20:30 -0400111 CategorizedContactModel::instance().setSortAlphabetical(false);
112 CategorizedContactModel::instance().setUnreachableHidden(true);
113 ui->contactView->setModel(&CategorizedContactModel::instance());
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400114 contactDelegate_ = new ContactDelegate();
115 ui->contactView->setItemDelegate(contactDelegate_);
116
Edric Milareta3e47282015-10-23 15:20:30 -0400117 CategorizedHistoryModel::instance().
Edric Milaret6a642e22015-05-27 15:06:30 -0400118 addCollection<LocalHistoryCollection>(LoadOptions::FORCE_ENABLED);
Edric Milaret627500d2015-03-27 16:41:40 -0400119
Edric Milareta3e47282015-10-23 15:20:30 -0400120 ui->historyList->setModel(CategorizedHistoryModel::SortedProxy::instance().model());
121 CategorizedHistoryModel::SortedProxy::instance().model()->sort(0, Qt::DescendingOrder);
Edric Milaret53f57b62015-05-11 11:02:17 -0400122 ui->historyList->setHeaderHidden(true);
Edric Milaret01f23842015-06-22 14:46:01 -0400123 historyDelegate_ = new HistoryDelegate();
124 ui->historyList->setItemDelegate(historyDelegate_);
Edric Milaret77dd6982015-07-07 16:45:41 -0400125
Edric Milareta3e47282015-10-23 15:20:30 -0400126 connect(CategorizedHistoryModel::SortedProxy::instance().model(), &QSortFilterProxyModel::layoutChanged, [=]() {
127 auto idx = CategorizedHistoryModel::SortedProxy::instance().model()->index(0,0);
Edric Milaret77dd6982015-07-07 16:45:41 -0400128 if (idx.isValid())
129 ui->historyList->setExpanded(idx, true);
130 });
131
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400132 ui->historyList->setContextMenuPolicy(Qt::CustomContextMenu);
133 connect(ui->historyList, &QListView::customContextMenuRequested, [=](const QPoint& pos){
134 if (ui->historyList->currentIndex().parent().isValid()) {
135 QPoint globalPos = ui->historyList->mapToGlobal(pos);
136 QMenu menu;
137
138 ContactMethod* contactMethod = ui->historyList->currentIndex()
139 .data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>();
140
Edric Milaret53ac6e52015-09-14 13:37:06 -0400141 auto copyAction = new QAction(tr("Copy number"), this);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400142 menu.addAction(copyAction);
143 connect(copyAction, &QAction::triggered, [=]() {
144 QApplication::clipboard()->setText(contactMethod->uri());
145 });
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400146 if (not contactMethod->contact() || contactMethod->contact()->isPlaceHolder()) {
Edric Milaret53ac6e52015-09-14 13:37:06 -0400147 auto addExisting = new QAction(tr("Add to contact"), this);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400148 menu.addAction(addExisting);
149 connect(addExisting, &QAction::triggered, [=]() {
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400150 ContactPicker contactPicker(contactMethod);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400151 contactPicker.move(globalPos.x(), globalPos.y() - (contactPicker.height()/2));
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400152 contactPicker.exec();
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400153 });
154 }
155 menu.exec(globalPos);
156 }
157 });
Edric Milaret53f57b62015-05-11 11:02:17 -0400158
Edric Milaret627500d2015-03-27 16:41:40 -0400159 findRingAccount();
Edric Milareta0ebd062016-01-13 12:18:23 -0500160 setupOutOfCallIM();
161 setupSmartListMenu();
Edric Milaret627500d2015-03-27 16:41:40 -0400162
Edric Milaret80e0b212015-10-16 10:07:43 -0400163 } catch (const std::exception& e) {
164 qDebug() << "INIT ERROR" << e.what();
Edric Milaret627500d2015-03-27 16:41:40 -0400165 }
166}
167
168CallWidget::~CallWidget()
169{
170 delete ui;
Edric Milaretc7ab5502015-06-15 11:18:02 -0400171 delete menu_;
Edric Milaret01f23842015-06-22 14:46:01 -0400172 delete contactDelegate_;
Edric Milaretab12d022015-12-04 16:09:44 -0500173 delete imDelegate_;
Nicolas Jagerca850292016-01-17 14:11:10 -0500174 delete welcomePageAnim_;
175 delete messagingPageAnim_;
Edric Milaret627500d2015-03-27 16:41:40 -0400176}
177
178void
Edric Milareta0ebd062016-01-13 12:18:23 -0500179CallWidget::setupOutOfCallIM()
180{
181 ui->listMessageView->setItemDelegate(imDelegate_);
182 ui->listMessageView->setContextMenuPolicy(Qt::ActionsContextMenu);
183
184 auto copyAction = new QAction(tr("Copy"), this);
185 ui->listMessageView->addAction(copyAction);
186 connect(copyAction, &QAction::triggered, [=]() {
187 auto idx = ui->listMessageView->currentIndex();
188 if (idx.isValid()) {
189 auto text = ui->listMessageView->model()->data(idx);
190 QApplication::clipboard()->setText(text.value<QString>());
191 }
192 });
193 auto displayDate = new QAction(tr("Display date"), this);
194 displayDate->setCheckable(true);
195 ui->listMessageView->addAction(displayDate);
196 auto displayAuthor = new QAction(tr("Display author"), this);
197 displayAuthor->setCheckable(true);
198 ui->listMessageView->addAction(displayAuthor);
199 auto lamdba = [=](){
200 int opts = 0;
201 displayAuthor->isChecked() ? opts |= ImDelegate::DisplayOptions::AUTHOR : opts;
202 displayDate->isChecked() ? opts |= ImDelegate::DisplayOptions::DATE : opts;
203 imDelegate_->setDisplayOptions(static_cast<ImDelegate::DisplayOptions>(opts));
204 };
205 connect(displayAuthor, &QAction::triggered, lamdba);
206 connect(displayDate, &QAction::triggered, lamdba);
Edric Milaret00a32252016-01-19 10:37:13 -0500207
208 connect(&::Media::RecordingModel::instance(),
209 SIGNAL(newTextMessage(::Media::TextRecording*, ContactMethod*)),
210 this,
211 SLOT(onIncomingMessage(::Media::TextRecording*, ContactMethod*)));
212}
213
214void
215CallWidget::onIncomingMessage(::Media::TextRecording* t, ContactMethod* cm) {
216 Q_UNUSED(cm)
217
218 if (!QApplication::focusWidget()) {
219 auto idx = t->instantTextMessagingModel()->
220 index(t->instantTextMessagingModel()->rowCount()-1, 0);
221 GlobalSystemTray::instance()
222 .showMessage("Ring",
223 QString(tr("Message incoming from %1")).arg(
224 idx.data((int)Media::TextRecording::Role::AuthorDisplayname).toString()));
225 QApplication::alert(this, 5000);
226 }
Edric Milareta0ebd062016-01-13 12:18:23 -0500227}
228
229void
230CallWidget::setupSmartListMenu() {
231 ui->smartList->setContextMenuPolicy(Qt::CustomContextMenu);
232 connect(ui->smartList, &QListView::customContextMenuRequested, [=](const QPoint& pos){
233 auto idx = ui->smartList->currentIndex();
234 if (not idx.isValid())
235 return;
236 QPoint globalPos = ui->smartList->mapToGlobal(pos);
237 QMenu menu;
238
Edric Milaret9949b342016-02-02 12:25:08 -0500239 QVector<ContactMethod*> contactMethods = RecentModel::instance()
240 .getContactMethods(RecentModel::instance().peopleProxy()->mapToSource(idx));
241 if (contactMethods.isEmpty())
Edric Milareta0ebd062016-01-13 12:18:23 -0500242 return;
Edric Milaret9949b342016-02-02 12:25:08 -0500243
244 if (contactMethods.size() == 1) {
245 auto contactMethod = contactMethods.at(0);
246 auto copyAction = new QAction(tr("Copy number"), this);
247 menu.addAction(copyAction);
248 connect(copyAction, &QAction::triggered, [contactMethod]() {
249 QApplication::clipboard()->setText(contactMethod->uri());
Edric Milareta0ebd062016-01-13 12:18:23 -0500250 });
Edric Milaret9949b342016-02-02 12:25:08 -0500251 if (not contactMethod->contact() || contactMethod->contact()->isPlaceHolder()) {
252 auto addExisting = new QAction(tr("Add to contact"), this);
253 menu.addAction(addExisting);
254 connect(addExisting, &QAction::triggered, [globalPos, contactMethod]() {
255 ContactPicker contactPicker(contactMethod);
256 contactPicker.move(globalPos.x(), globalPos.y() - (contactPicker.height()/2));
257 contactPicker.exec();
258 });
259 }
260 }
261 else {
262 auto callMenu = menu.addMenu(tr("Call Number"));
263 auto copyMenu = menu.addMenu(tr("Copy Number"));
264 for (auto cM : contactMethods) {
265 auto uri = cM->uri();
266 auto copyAction = new QAction(tr("Copy %1").arg(uri), this);
267 copyMenu->addAction(copyAction);
268 connect(copyAction, &QAction::triggered, [uri]() {
269 QApplication::clipboard()->setText(uri);
270 });
271 auto callAction = new QAction(tr("Call %1").arg(uri), this);
272 callMenu->addAction(callAction);
273 connect(callAction, &QAction::triggered, [cM]() {
274 Call* c = CallModel::instance().dialingCall(cM);
275 c->performAction(Call::Action::ACCEPT);
276 });
277 }
Edric Milareta0ebd062016-01-13 12:18:23 -0500278 }
279 menu.exec(globalPos);
280 });
281}
282
283void
Edric Milaret67007d12015-05-07 09:40:09 -0400284CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector<int> vec)
285{
286 Q_UNUSED(idx1)
287 Q_UNUSED(idx2)
288 Q_UNUSED(vec)
289
Edric Milareta3e47282015-10-23 15:20:30 -0400290 auto a_count = AccountModel::instance().rowCount();
Edric Milaret67007d12015-05-07 09:40:09 -0400291 auto found = false;
292 for (int i = 0; i < a_count; ++i) {
Edric Milareta3e47282015-10-23 15:20:30 -0400293 auto idx = AccountModel::instance().index(i, 0);
Edric Milaret67007d12015-05-07 09:40:09 -0400294 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
295 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
296 auto username = idx.data(static_cast<int>(Account::Role::Username));
Edric Milareted0b2802015-10-01 15:10:02 -0400297 ui->ringIdLabel->setText(username.toString());
Edric Milaret67007d12015-05-07 09:40:09 -0400298 found = true;
299 return;
300 }
301 }
Nicolas Jager97a21b42015-12-03 16:55:45 -0500302 if (not found) {
Edric Milaret53ac6e52015-09-14 13:37:06 -0400303 ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
Edric Milaret67007d12015-05-07 09:40:09 -0400304 }
305}
306
307void
308CallWidget::findRingAccount()
309{
Edric Milaret559bda52015-04-29 17:02:31 -0400310
Edric Milareta3e47282015-10-23 15:20:30 -0400311 auto a_count = AccountModel::instance().rowCount();
Edric Milaret627500d2015-03-27 16:41:40 -0400312 auto found = false;
313 for (int i = 0; i < a_count; ++i) {
Edric Milareta3e47282015-10-23 15:20:30 -0400314 auto idx = AccountModel::instance().index(i, 0);
Edric Milaret627500d2015-03-27 16:41:40 -0400315 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
316 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
Edric Milareta3e47282015-10-23 15:20:30 -0400317 auto account = AccountModel::instance().getAccountByModelIndex(idx);
Edric Milaret68779c42015-07-09 16:53:03 -0400318 if (account->displayName().isEmpty())
319 account->displayName() = account->alias();
320 auto username = account->username();
Edric Milareted0b2802015-10-01 15:10:02 -0400321 ui->ringIdLabel->setText(username);
Edric Milaret627500d2015-03-27 16:41:40 -0400322 found = true;
323 return;
324 }
325 }
326 if (!found) {
Edric Milareted0b2802015-10-01 15:10:02 -0400327 ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
Edric Milaret559bda52015-04-29 17:02:31 -0400328 WizardDialog *wizardDialog = new WizardDialog();
329 wizardDialog->exec();
330 delete wizardDialog;
Edric Milaret627500d2015-03-27 16:41:40 -0400331 }
332}
333
334void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500335CallWidget::callIncoming(Call* call)
Edric Milaret627500d2015-03-27 16:41:40 -0400336{
Edric Milaret00a32252016-01-19 10:37:13 -0500337 if (!QApplication::focusWidget()) {
338 GlobalSystemTray::instance()
339 .showMessage("Ring",
340 QString(tr("Call incoming from %1")).arg(call->formattedName()));
Edric Milaret2cf34292015-06-22 16:27:03 -0400341 QApplication::alert(this, 5000);
342 }
343
Edric Milaret435cdfc2015-06-01 16:15:50 -0400344 if (!call->account()->isAutoAnswer()) {
Nicolas Jager97a21b42015-12-03 16:55:45 -0500345 ui->callerIdLabel->setText(QString(tr("%1", "%1 is the name of the caller"))
Edric Milareta0ebd062016-01-13 12:18:23 -0500346 .arg(call->formattedName()));
Edric Milareta20501f2016-01-27 11:38:05 -0500347 ui->callerPhoto->setPixmap(
348 QPixmap::fromImage(
349 GlobalInstances::pixmapManipulator()
350 .callPhoto(call, QSize(130,130)).value<QImage>()));
Edric Milareted0b2802015-10-01 15:10:02 -0400351 ui->stackedWidget->setCurrentWidget(ui->callInvitePage);
Edric Milaret435cdfc2015-06-01 16:15:50 -0400352 }
Edric Milaret6456baa2015-05-21 12:18:07 -0400353 setActualCall(call);
Edric Milaret627500d2015-03-27 16:41:40 -0400354}
355
356void
357CallWidget::on_acceptButton_clicked()
358{
359 if (actualCall_ != nullptr)
Edric Milaret53f57b62015-05-11 11:02:17 -0400360 actualCall_->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400361 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milaret627500d2015-03-27 16:41:40 -0400362}
363
364void
365CallWidget::on_refuseButton_clicked()
366{
367 if (actualCall_ == nullptr)
368 return;
369 actualCall_->performAction(Call::Action::REFUSE);
Edric Milaret6456baa2015-05-21 12:18:07 -0400370 setActualCall(nullptr);
Edric Milareted0b2802015-10-01 15:10:02 -0400371 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Edric Milaret627500d2015-03-27 16:41:40 -0400372}
373
374void
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400375CallWidget::addedCall(Call* call, Call* parent)
376{
Edric Milaret627500d2015-03-27 16:41:40 -0400377 Q_UNUSED(parent);
378 if (call->direction() == Call::Direction::OUTGOING) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400379 setActualCall(call);
Nicolas Jager45bf7c02016-01-20 09:53:02 -0500380 ui->stackedWidget->setCurrentWidget(ui->outboundCallPage);
Edric Milaret627500d2015-03-27 16:41:40 -0400381 }
382}
383
384void
Edric Milaret67007d12015-05-07 09:40:09 -0400385CallWidget::callStateChanged(Call* call, Call::State previousState)
386{
Edric Milaret627500d2015-03-27 16:41:40 -0400387 Q_UNUSED(previousState)
Edric Milaret4b1be4a2016-01-15 16:49:20 -0500388 if (call == nullptr
389 || call != actualCall_)
Edric Milaretb5b49072015-05-08 11:56:07 -0400390 return;
Edric Milareted0b2802015-10-01 15:10:02 -0400391
Edric Milaret4b1be4a2016-01-15 16:49:20 -0500392 if (call->state() == Call::State::OVER) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400393 setActualCall(nullptr);
Edric Milaretc54e2272015-10-01 10:14:00 -0400394 ui->instantMessagingWidget->setMediaText(nullptr);
Edric Milareted0b2802015-10-01 15:10:02 -0400395 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Edric Milaret6816fd72016-01-29 16:36:24 -0500396 //TODO : Link this so that recentModel get selected correctly
397 // auto onHoldCall = callModel_->getActiveCalls().first();
398 // if (onHoldCall != nullptr && onHoldCall->state() == Call::State::HOLD) {
399 // setActualCall(onHoldCall);
400 // onHoldCall->performAction(Call::Action::HOLD);
401 // }
Edric Milaret53f57b62015-05-11 11:02:17 -0400402 } else if (call->state() == Call::State::CURRENT) {
Edric Milaretc54e2272015-10-01 10:14:00 -0400403 ui->instantMessagingWidget->setMediaText(actualCall_);
Edric Milareted0b2802015-10-01 15:10:02 -0400404 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milaret627500d2015-03-27 16:41:40 -0400405 }
Edric Milaret627500d2015-03-27 16:41:40 -0400406}
407
408void
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400409CallWidget::atExit()
410{
Edric Milaret627500d2015-03-27 16:41:40 -0400411}
Edric Milaret67007d12015-05-07 09:40:09 -0400412
413void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500414CallWidget::on_contactView_doubleClicked(const QModelIndex& index)
Edric Milaret67007d12015-05-07 09:40:09 -0400415{
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400416 if (not index.isValid())
417 return;
418
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400419 ContactMethod* uri = nullptr;
Edric Milaret67007d12015-05-07 09:40:09 -0400420
Edric Milaret7d40a4a2015-05-13 13:01:15 -0400421 auto var = index.child(0,0).data(
422 static_cast<int>(Person::Role::Object));
423 if (var.isValid()) {
424 Person* person = var.value<Person*>();
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400425 if (person->phoneNumbers().size() == 1) {
426 uri = person->phoneNumbers().at(0);
427 } else if (person->phoneNumbers().size() > 1) {
428 ContactMethodPicker dlg(person->phoneNumbers());
429 auto pos = QCursor::pos();
430 dlg.move(pos.x(), pos.y());
431 if (dlg.exec())
432 uri = dlg.getSelected();
433 }
434 if (uri) {
Edric Milareta3e47282015-10-23 15:20:30 -0400435 auto outCall = CallModel::instance().dialingCall(uri);
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400436 outCall->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400437 ui->mainTabMenu->setCurrentIndex(0);
438 ui->smartList->setFocus();
Edric Milaret67007d12015-05-07 09:40:09 -0400439 }
440 }
Edric Milaret67007d12015-05-07 09:40:09 -0400441}
Edric Milaret53f57b62015-05-11 11:02:17 -0400442
Edric Milaret6456baa2015-05-21 12:18:07 -0400443void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500444CallWidget::on_historyList_doubleClicked(const QModelIndex& index)
Edric Milaret53f57b62015-05-11 11:02:17 -0400445{
Edric Milaret12353822015-05-14 14:41:09 -0400446 if (not index.isValid())
447 return;
448
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400449 auto number = index.data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>();
450 if (number) {
Edric Milareta3e47282015-10-23 15:20:30 -0400451 auto outCall = CallModel::instance().dialingCall(number);
Edric Milaret53f57b62015-05-11 11:02:17 -0400452 outCall->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400453 ui->mainTabMenu->setCurrentIndex(0);
454 ui->smartList->setFocus();
Edric Milaret53f57b62015-05-11 11:02:17 -0400455 }
456}
Edric Milaret6456baa2015-05-21 12:18:07 -0400457
458void
459CallWidget::setActualCall(Call* value)
460{
461 actualCall_ = value;
Edric Milaret80e0b212015-10-16 10:07:43 -0400462 CallModel::instance().selectCall(value);
463 ui->videoWidget->pushRenderer(value);
Edric Milaret6456baa2015-05-21 12:18:07 -0400464}
Edric Milaretc7ab5502015-06-15 11:18:02 -0400465
466void
Edric Milareted0b2802015-10-01 15:10:02 -0400467CallWidget::on_cancelButton_clicked()
Edric Milaretd8528fa2015-07-07 14:13:51 -0400468{
469 if (actualCall_)
470 actualCall_->performAction(Call::Action::REFUSE);
471}
Edric Milareted0b2802015-10-01 15:10:02 -0400472
473void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500474CallWidget::on_smartList_doubleClicked(const QModelIndex& index)
Edric Milareted0b2802015-10-01 15:10:02 -0400475{
Edric Milareta3e47282015-10-23 15:20:30 -0400476 auto realIndex = RecentModel::instance().peopleProxy()->mapToSource(index);
477 if (RecentModel::instance().hasActiveCall(realIndex))
Edric Milareted0b2802015-10-01 15:10:02 -0400478 return;
479
480 ContactMethod* m = nullptr;
481 if (auto cm = realIndex.data((int)Call::Role::ContactMethod).value<ContactMethod*>()) {
482 m = cm;
483 } else {
484 if (auto person = realIndex.data((int)Person::Role::Object).value<Person*>()) {
485 m = person->phoneNumbers().first();
486 }
487 }
Edric Milareta3e47282015-10-23 15:20:30 -0400488 if (m && !RecentModel::instance().index(0, 0, realIndex).isValid()) {
489 Call* c = CallModel::instance().dialingCall(m);
Edric Milareted0b2802015-10-01 15:10:02 -0400490 c->performAction(Call::Action::ACCEPT);
491 }
492}
493
494void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500495CallWidget::smartListSelectionChanged(const QItemSelection& newSel, const QItemSelection& oldSel) {
Edric Milareted0b2802015-10-01 15:10:02 -0400496
497 Q_UNUSED(oldSel)
498
Edric Milaretab12d022015-12-04 16:09:44 -0500499 if (newSel.indexes().empty())
500 {
501 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
502 return;
503 }
Edric Milareted0b2802015-10-01 15:10:02 -0400504 auto newIdx = newSel.indexes().first();
Edric Milaret80e0b212015-10-16 10:07:43 -0400505 if (not newIdx.isValid())
Edric Milareted0b2802015-10-01 15:10:02 -0400506 return;
507
Edric Milaret6816fd72016-01-29 16:36:24 -0500508 auto nodeIdx = RecentModel::instance().peopleProxy()->mapToSource(newIdx);
509 auto newIdxCall = RecentModel::instance().getActiveCall(nodeIdx);
510
Edric Milareta0ebd062016-01-13 12:18:23 -0500511 if (newIdxCall && newIdxCall != actualCall_) {
Edric Milareted0b2802015-10-01 15:10:02 -0400512 setActualCall(newIdxCall);
Edric Milaret6816fd72016-01-29 16:36:24 -0500513 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milareta0ebd062016-01-13 12:18:23 -0500514 } else if (newIdxCall == nullptr){
515 setActualCall(nullptr);
Edric Milaretf6f608d2016-02-02 15:06:33 -0500516 ui->instantMessagingWidget->hide();
Edric Milaret6816fd72016-01-29 16:36:24 -0500517 showIMOutOfCall();
Edric Milareted0b2802015-10-01 15:10:02 -0400518 } else {
519 setActualCall(nullptr);
Edric Milaretf6f608d2016-02-02 15:06:33 -0500520 ui->instantMessagingWidget->hide();
Edric Milaret7ef617b2016-02-01 15:40:57 -0500521 if (imConnection_)
522 disconnect(imConnection_);
Edric Milareted0b2802015-10-01 15:10:02 -0400523 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
524 }
525}
526
527void
528CallWidget::placeCall()
529{
Nicolas Jager97a21b42015-12-03 16:55:45 -0500530 if (ui->ringContactLineEdit->text().isEmpty())
Edric Milareted0b2802015-10-01 15:10:02 -0400531 return;
Nicolas Jager97a21b42015-12-03 16:55:45 -0500532 Call* c = CallModel::instance().dialingCall(PhoneDirectoryModel::instance().getNumber(ui->ringContactLineEdit->text()));
Edric Milareted0b2802015-10-01 15:10:02 -0400533 c->performAction(Call::Action::ACCEPT);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500534 ui->ringContactLineEdit->clear();
Edric Milareted0b2802015-10-01 15:10:02 -0400535}
536
537void
Edric Milaret33cb4832016-01-08 10:14:14 -0500538CallWidget::settingsButton_clicked()
Edric Milareted0b2802015-10-01 15:10:02 -0400539{
540 emit NavigationRequested(ScreenEnum::ConfScreen);
541}
542
543void
Edric Milaret33cb4832016-01-08 10:14:14 -0500544CallWidget::contactButton_clicked(bool checked)
Edric Milareted0b2802015-10-01 15:10:02 -0400545{
Edric Milareted0b2802015-10-01 15:10:02 -0400546 ui->mainTabMenu->setCurrentIndex(checked ? 1 : 0);
547}
548
549void
Edric Milaret33cb4832016-01-08 10:14:14 -0500550CallWidget::historicButton_clicked(bool checked)
Edric Milareted0b2802015-10-01 15:10:02 -0400551{
Edric Milareted0b2802015-10-01 15:10:02 -0400552 ui->mainTabMenu->setCurrentIndex(checked ? 2 : 0);
553}
Nicolas Jager97a21b42015-12-03 16:55:45 -0500554
555void
556CallWidget::on_ringContactLineEdit_returnPressed()
557{
Edric Milaret00593d12016-01-19 11:57:46 -0500558 auto cm = PhoneDirectoryModel::instance().getNumber(ui->ringContactLineEdit->text());
559 time_t currentTime;
560 ::time(&currentTime);
561 cm->setLastUsed(currentTime);
Edric Milaret8001f6f2016-01-27 09:55:12 -0500562 ui->ringContactLineEdit->clear();
Nicolas Jager97a21b42015-12-03 16:55:45 -0500563}
564
565void
566CallWidget::on_btnCall_clicked()
567{
568 placeCall();
569}
570
571void
572CallWidget::on_btnvideo_clicked()
573{
574 if (not highLightedIndex_.isValid())
575 return;
576
577 on_smartList_doubleClicked(highLightedIndex_);
578}
Edric Milaretab12d022015-12-04 16:09:44 -0500579
580void
Edric Milaret6816fd72016-01-29 16:36:24 -0500581CallWidget::showIMOutOfCall()
Edric Milaretab12d022015-12-04 16:09:44 -0500582{
Edric Milaret6816fd72016-01-29 16:36:24 -0500583 if (not highLightedIndex_.isValid())
584 return;
585
586 ui->smartList->selectionModel()->select(highLightedIndex_, QItemSelectionModel::ClearAndSelect);
587
Edric Milaretab12d022015-12-04 16:09:44 -0500588 ui->contactMethodComboBox->clear();
589
Edric Milaret6816fd72016-01-29 16:36:24 -0500590 auto nodeIdx = RecentModel::instance().peopleProxy()->mapToSource(highLightedIndex_);
Edric Milareta0ebd062016-01-13 12:18:23 -0500591 ui->imNameLabel->setText(QString(tr("Conversation with %1", "%1 is the contact name"))
592 .arg(nodeIdx.data(static_cast<int>(Ring::Role::Name)).toString()));
Edric Milaretab12d022015-12-04 16:09:44 -0500593 auto cmVector = RecentModel::instance().getContactMethods(nodeIdx);
Edric Milareta0ebd062016-01-13 12:18:23 -0500594 ui->contactMethodComboBox->setEnabled(cmVector.size() > 1);
Edric Milaretab12d022015-12-04 16:09:44 -0500595 foreach (const ContactMethod* cm, cmVector) {
Edric Milareta0ebd062016-01-13 12:18:23 -0500596 ui->contactMethodComboBox->addItem(cm->uri());
Edric Milaretab12d022015-12-04 16:09:44 -0500597 }
Nicolas Jagerca850292016-01-17 14:11:10 -0500598 slideToRight(messagingPageAnim_, ui->messagingPage);
Edric Milaretab12d022015-12-04 16:09:44 -0500599}
600
601void
602CallWidget::on_sendButton_clicked()
603{
Edric Milareta0ebd062016-01-13 12:18:23 -0500604 if (ui->messageEdit->text().trimmed().isEmpty())
Edric Milaretab12d022015-12-04 16:09:44 -0500605 return;
606 auto number = ui->contactMethodComboBox->currentText();
607 if (auto cm = PhoneDirectoryModel::instance().getNumber(number)) {
608 QMap<QString, QString> msg;
609 msg["text/plain"] = ui->messageEdit->text();
610 cm->sendOfflineTextMessage(msg);
611 ui->messageEdit->clear();
612 } else {
613 qWarning() << "Contact Method not found for " << number;
614 }
615}
616
617void
618CallWidget::on_messageEdit_returnPressed()
619{
620 on_sendButton_clicked();
621}
622
623void
624CallWidget::on_contactMethodComboBox_currentIndexChanged(const QString& number)
625{
626 auto cm = PhoneDirectoryModel::instance().getNumber(number);
627 if (auto txtRecording = cm->textRecording()) {
628 ui->listMessageView->setModel(txtRecording->instantMessagingModel());
Edric Milaret7ef617b2016-02-01 15:40:57 -0500629 if (imConnection_)
630 disconnect(imConnection_);
Edric Milaretab12d022015-12-04 16:09:44 -0500631 imConnection_ = connect(txtRecording,
Edric Milareta0ebd062016-01-13 12:18:23 -0500632 SIGNAL(messageInserted(QMap<QString,QString>,ContactMethod*,Media::Media::Direction)),
633 this,
634 SLOT(slotAccountMessageReceived(QMap<QString,QString>,ContactMethod*,Media::Media::Direction)));
Edric Milaret4be72022016-01-19 10:24:13 -0500635 auto messagesPresent = txtRecording->instantMessagingModel()->rowCount() > 0;
636 if (messagesPresent) {
637 ui->listMessageView->scrollToBottom();
638 txtRecording->setAllRead();
639 }
640 ui->listMessageView->setVisible(messagesPresent);
641 ui->noMessagesLabel->setVisible(!messagesPresent);
642 if (not messagesPresent) {
Edric Milaret49130472016-01-22 10:39:37 -0500643 imVisibleConnection_ = connect(txtRecording->instantMessagingModel(),
644 &QAbstractItemModel::rowsInserted,
645 [this, txtRecording]() {
646 if (imVisibleConnection_)
647 disconnect(imVisibleConnection_);
648 auto messagesPresent = txtRecording->instantMessagingModel()->rowCount() > 0;
Edric Milaret4be72022016-01-19 10:24:13 -0500649 ui->listMessageView->setVisible(messagesPresent);
650 ui->noMessagesLabel->setVisible(!messagesPresent);
Edric Milaret4be72022016-01-19 10:24:13 -0500651 });
652 }
Edric Milaretab12d022015-12-04 16:09:44 -0500653 }
654}
655
656void
657CallWidget::slotAccountMessageReceived(const QMap<QString,QString> message,
658 ContactMethod* cm,
659 Media::Media::Direction dir)
660{
661 Q_UNUSED(message)
Edric Milaretab12d022015-12-04 16:09:44 -0500662 Q_UNUSED(dir)
663
664 ui->listMessageView->scrollToBottom();
Edric Milaret23fd3fa2016-01-15 15:37:35 -0500665 cm->textRecording()->setAllRead();
Edric Milaretab12d022015-12-04 16:09:44 -0500666}
Edric Milaretfa05d972016-01-13 16:22:04 -0500667
668void
Edric Milaret8001f6f2016-01-27 09:55:12 -0500669CallWidget::on_ringContactLineEdit_textChanged(const QString& text)
Edric Milaretfa05d972016-01-13 16:22:04 -0500670{
671 RecentModel::instance().peopleProxy()->setFilterWildcard(text);
672}
Edric Milareta0ebd062016-01-13 12:18:23 -0500673
Nicolas Jagerca850292016-01-17 14:11:10 -0500674void
675CallWidget::on_imBackButton_clicked()
Edric Milareta0ebd062016-01-13 12:18:23 -0500676{
Nicolas Jagerca850292016-01-17 14:11:10 -0500677 slideToLeft(welcomePageAnim_, ui->welcomePage);
678}
679
680void
681CallWidget::slideToLeft(QPropertyAnimation* anim, QWidget* widget)
682{
683 ui->stackedWidget->setCurrentWidget(widget);
684 anim->setDuration(animDuration_);
685 anim->setStartValue(QPoint(widget->width(), widget->y()));
686 anim->setEndValue(QPoint(widget->x(), widget->y()));
687 anim->setEasingCurve(QEasingCurve::OutQuad);
688 anim->start();
689}
690
691void
692CallWidget::slideToRight(QPropertyAnimation* anim, QWidget* widget)
693{
694 ui->stackedWidget->setCurrentWidget(widget);
695 anim->setDuration(animDuration_);
696 anim->setStartValue(QPoint(-widget->width(), widget->y()));
697 anim->setEndValue(QPoint(widget->x(), widget->y()));
698 anim->setEasingCurve(QEasingCurve::OutQuad);
699 anim->start();
Edric Milareta0ebd062016-01-13 12:18:23 -0500700}
Edric Milaret7cf39e22016-02-02 12:44:03 -0500701
702void
703CallWidget::on_copyCMButton_clicked()
704{
705 auto text = ui->contactMethodComboBox->currentText();
706 QApplication::clipboard()->setText(text);
707}