blob: 7bc345c7e173de0f153bdf44aca308c8d21fd7d0 [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 Jagerca850292016-01-17 14:11:10 -050065 welcomePageAnim_ = new QPropertyAnimation(ui->welcomePage, "pos", this);
66 messagingPageAnim_ = new QPropertyAnimation(ui->messagingPage, "pos", this);
67
Nicolas Jager97a21b42015-12-03 16:55:45 -050068 // TODO : add this in style sheet forms
69 QPalette palette;
70 palette.setColor(QPalette::WindowText, QColor(255,255,255));
71 ui->callerIdLabel->setPalette(palette);
72
73 QPalette palette2;
74 palette2.setColor(QPalette::WindowText, QColor(141,141,141));
75
76 ui->wantToTalkLabel->setPalette(palette2);
77 ui->outboundCallLabel->setPalette(palette2);
78 ui->cancelCallLabel->setPalette(palette2);
79 ui->acceptLabel->setPalette(palette2);
80 ui->refuseLabel->setPalette(palette2);
81
82 QFont font = ui->callerIdLabel->font();
83 font.setPointSize(20);
84
85 ui->callerIdLabel->setFont(font);
86 // end of TODO : add this in style sheet forms
87
Edric Milaret627500d2015-03-27 16:41:40 -040088 ui->callInvite->setVisible(false);
89
Edric Milaret6456baa2015-05-21 12:18:07 -040090 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -040091 videoRenderer_ = nullptr;
92
Edric Milaret3aca8e32015-06-12 10:01:40 -040093 connect(ui->videoWidget, SIGNAL(setChatVisibility(bool)),
94 ui->instantMessagingWidget, SLOT(setVisible(bool)));
95
Edric Milareted0b2802015-10-01 15:10:02 -040096 QPixmap logo(":/images/logo-ring-standard-coul.png");
97 ui->ringLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation));
98 ui->ringLogo->setAlignment(Qt::AlignHCenter);
99
Nicolas Jagerd0b33752016-01-17 00:00:40 -0500100 QPixmap sendPixmap(":/images/ic_send_white.svg");
101 QIcon sendIcon(sendPixmap);
102 ui->sendButton->setIcon(sendIcon);
103 ui->sendButton->setIconSize(sendPixmap.rect().size());
104
Edric Milareta0ebd062016-01-13 12:18:23 -0500105 GlobalInstances::setPixmapManipulator(std::unique_ptr<Interfaces::PixbufManipulator>(new Interfaces::PixbufManipulator()));
106
Edric Milaret627500d2015-03-27 16:41:40 -0400107 try {
Edric Milareta3e47282015-10-23 15:20:30 -0400108 callModel_ = &CallModel::instance();
Edric Milaret627500d2015-03-27 16:41:40 -0400109
110 connect(callModel_, SIGNAL(incomingCall(Call*)),
111 this, SLOT(callIncoming(Call*)));
112 connect(callModel_, SIGNAL(callAdded(Call*,Call*)),
113 this, SLOT(addedCall(Call*, Call*)));
114 connect(callModel_, SIGNAL(callStateChanged(Call*, Call::State)),
115 this, SLOT(callStateChanged(Call*, Call::State)));
116
Edric Milareta3e47282015-10-23 15:20:30 -0400117 connect(&AccountModel::instance()
Edric Milaret67007d12015-05-07 09:40:09 -0400118 , SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))
119 , this
120 , SLOT(findRingAccount(QModelIndex, QModelIndex, QVector<int>)));
121
Edric Milaretfa05d972016-01-13 16:22:04 -0500122 RecentModel::instance().peopleProxy()->setFilterRole(static_cast<int>(Ring::Role::Name));
123 RecentModel::instance().peopleProxy()->setFilterCaseSensitivity(Qt::CaseInsensitive);
Edric Milareta3e47282015-10-23 15:20:30 -0400124 ui->smartList->setModel(RecentModel::instance().peopleProxy());
Edric Milareted0b2802015-10-01 15:10:02 -0400125 connect(ui->smartList->selectionModel(),
126 SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
127 this,
128 SLOT(smartListSelectionChanged(QItemSelection,QItemSelection)));
Nicolas Jager97a21b42015-12-03 16:55:45 -0500129
130 connect(ui->smartList, &QTreeView::entered, this, &CallWidget::on_entered);
131
Edric Milareted0b2802015-10-01 15:10:02 -0400132 smartListDelegate_ = new SmartListDelegate();
Nicolas Jager97a21b42015-12-03 16:55:45 -0500133 ui->smartList->setSmartListItemDelegate(smartListDelegate_);
Edric Milaret627500d2015-03-27 16:41:40 -0400134
Edric Milareta3e47282015-10-23 15:20:30 -0400135 PersonModel::instance().
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400136 addCollection<WindowsContactBackend>(LoadOptions::FORCE_ENABLED);
137
Edric Milareta3e47282015-10-23 15:20:30 -0400138 CategorizedContactModel::instance().setSortAlphabetical(false);
139 CategorizedContactModel::instance().setUnreachableHidden(true);
140 ui->contactView->setModel(&CategorizedContactModel::instance());
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400141 contactDelegate_ = new ContactDelegate();
142 ui->contactView->setItemDelegate(contactDelegate_);
143
Edric Milareta3e47282015-10-23 15:20:30 -0400144 CategorizedHistoryModel::instance().
Edric Milaret6a642e22015-05-27 15:06:30 -0400145 addCollection<LocalHistoryCollection>(LoadOptions::FORCE_ENABLED);
Edric Milaret627500d2015-03-27 16:41:40 -0400146
Edric Milareta3e47282015-10-23 15:20:30 -0400147 ui->historyList->setModel(CategorizedHistoryModel::SortedProxy::instance().model());
148 CategorizedHistoryModel::SortedProxy::instance().model()->sort(0, Qt::DescendingOrder);
Edric Milaret53f57b62015-05-11 11:02:17 -0400149 ui->historyList->setHeaderHidden(true);
Edric Milaret01f23842015-06-22 14:46:01 -0400150 historyDelegate_ = new HistoryDelegate();
151 ui->historyList->setItemDelegate(historyDelegate_);
Edric Milaret77dd6982015-07-07 16:45:41 -0400152
Edric Milareta3e47282015-10-23 15:20:30 -0400153 connect(CategorizedHistoryModel::SortedProxy::instance().model(), &QSortFilterProxyModel::layoutChanged, [=]() {
154 auto idx = CategorizedHistoryModel::SortedProxy::instance().model()->index(0,0);
Edric Milaret77dd6982015-07-07 16:45:41 -0400155 if (idx.isValid())
156 ui->historyList->setExpanded(idx, true);
157 });
158
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400159 ui->historyList->setContextMenuPolicy(Qt::CustomContextMenu);
160 connect(ui->historyList, &QListView::customContextMenuRequested, [=](const QPoint& pos){
161 if (ui->historyList->currentIndex().parent().isValid()) {
162 QPoint globalPos = ui->historyList->mapToGlobal(pos);
163 QMenu menu;
164
165 ContactMethod* contactMethod = ui->historyList->currentIndex()
166 .data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>();
167
Edric Milaret53ac6e52015-09-14 13:37:06 -0400168 auto copyAction = new QAction(tr("Copy number"), this);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400169 menu.addAction(copyAction);
170 connect(copyAction, &QAction::triggered, [=]() {
171 QApplication::clipboard()->setText(contactMethod->uri());
172 });
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400173 if (not contactMethod->contact() || contactMethod->contact()->isPlaceHolder()) {
Edric Milaret53ac6e52015-09-14 13:37:06 -0400174 auto addExisting = new QAction(tr("Add to contact"), this);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400175 menu.addAction(addExisting);
176 connect(addExisting, &QAction::triggered, [=]() {
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400177 ContactPicker contactPicker(contactMethod);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400178 contactPicker.move(globalPos.x(), globalPos.y() - (contactPicker.height()/2));
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400179 contactPicker.exec();
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400180 });
181 }
182 menu.exec(globalPos);
183 }
184 });
Edric Milaret53f57b62015-05-11 11:02:17 -0400185
Edric Milaret627500d2015-03-27 16:41:40 -0400186 findRingAccount();
Edric Milareta0ebd062016-01-13 12:18:23 -0500187 setupOutOfCallIM();
188 setupSmartListMenu();
Edric Milaret627500d2015-03-27 16:41:40 -0400189
Edric Milaret80e0b212015-10-16 10:07:43 -0400190 } catch (const std::exception& e) {
191 qDebug() << "INIT ERROR" << e.what();
Edric Milaret627500d2015-03-27 16:41:40 -0400192 }
193}
194
195CallWidget::~CallWidget()
196{
197 delete ui;
Edric Milaretc7ab5502015-06-15 11:18:02 -0400198 delete menu_;
Edric Milaret01f23842015-06-22 14:46:01 -0400199 delete contactDelegate_;
Edric Milaretab12d022015-12-04 16:09:44 -0500200 delete imDelegate_;
Nicolas Jagerca850292016-01-17 14:11:10 -0500201 delete welcomePageAnim_;
202 delete messagingPageAnim_;
Edric Milaret627500d2015-03-27 16:41:40 -0400203}
204
205void
Edric Milareta0ebd062016-01-13 12:18:23 -0500206CallWidget::setupOutOfCallIM()
207{
208 ui->listMessageView->setItemDelegate(imDelegate_);
209 ui->listMessageView->setContextMenuPolicy(Qt::ActionsContextMenu);
210
211 auto copyAction = new QAction(tr("Copy"), this);
212 ui->listMessageView->addAction(copyAction);
213 connect(copyAction, &QAction::triggered, [=]() {
214 auto idx = ui->listMessageView->currentIndex();
215 if (idx.isValid()) {
216 auto text = ui->listMessageView->model()->data(idx);
217 QApplication::clipboard()->setText(text.value<QString>());
218 }
219 });
220 auto displayDate = new QAction(tr("Display date"), this);
221 displayDate->setCheckable(true);
222 ui->listMessageView->addAction(displayDate);
223 auto displayAuthor = new QAction(tr("Display author"), this);
224 displayAuthor->setCheckable(true);
225 ui->listMessageView->addAction(displayAuthor);
226 auto lamdba = [=](){
227 int opts = 0;
228 displayAuthor->isChecked() ? opts |= ImDelegate::DisplayOptions::AUTHOR : opts;
229 displayDate->isChecked() ? opts |= ImDelegate::DisplayOptions::DATE : opts;
230 imDelegate_->setDisplayOptions(static_cast<ImDelegate::DisplayOptions>(opts));
231 };
232 connect(displayAuthor, &QAction::triggered, lamdba);
233 connect(displayDate, &QAction::triggered, lamdba);
234}
235
236void
237CallWidget::setupSmartListMenu() {
238 ui->smartList->setContextMenuPolicy(Qt::CustomContextMenu);
239 connect(ui->smartList, &QListView::customContextMenuRequested, [=](const QPoint& pos){
240 auto idx = ui->smartList->currentIndex();
241 if (not idx.isValid())
242 return;
243 QPoint globalPos = ui->smartList->mapToGlobal(pos);
244 QMenu menu;
245
246 ContactMethod* contactMethod = RecentModel::instance()
247 .getContactMethods(RecentModel::instance().peopleProxy()->mapToSource(idx)).at(0);
248 if (not contactMethod)
249 return;
250 auto copyAction = new QAction(tr("Copy number"), this);
251 menu.addAction(copyAction);
252 connect(copyAction, &QAction::triggered, [=]() {
253 QApplication::clipboard()->setText(contactMethod->uri());
254 });
255 if (not contactMethod->contact() || contactMethod->contact()->isPlaceHolder()) {
256 auto addExisting = new QAction(tr("Add to contact"), this);
257 menu.addAction(addExisting);
258 connect(addExisting, &QAction::triggered, [=]() {
259 ContactPicker contactPicker(contactMethod);
260 contactPicker.move(globalPos.x(), globalPos.y() - (contactPicker.height()/2));
261 contactPicker.exec();
262 });
263 }
264 menu.exec(globalPos);
265 });
266}
267
268void
Edric Milaret67007d12015-05-07 09:40:09 -0400269CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector<int> vec)
270{
271 Q_UNUSED(idx1)
272 Q_UNUSED(idx2)
273 Q_UNUSED(vec)
274
Edric Milareta3e47282015-10-23 15:20:30 -0400275 auto a_count = AccountModel::instance().rowCount();
Edric Milaret67007d12015-05-07 09:40:09 -0400276 auto found = false;
277 for (int i = 0; i < a_count; ++i) {
Edric Milareta3e47282015-10-23 15:20:30 -0400278 auto idx = AccountModel::instance().index(i, 0);
Edric Milaret67007d12015-05-07 09:40:09 -0400279 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
280 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
281 auto username = idx.data(static_cast<int>(Account::Role::Username));
Edric Milareted0b2802015-10-01 15:10:02 -0400282 ui->ringIdLabel->setText(username.toString());
Edric Milaret67007d12015-05-07 09:40:09 -0400283 found = true;
284 return;
285 }
286 }
Nicolas Jager97a21b42015-12-03 16:55:45 -0500287 if (not found) {
Edric Milaret53ac6e52015-09-14 13:37:06 -0400288 ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
Edric Milaret67007d12015-05-07 09:40:09 -0400289 }
290}
291
292void
293CallWidget::findRingAccount()
294{
Edric Milaret559bda52015-04-29 17:02:31 -0400295
Edric Milareta3e47282015-10-23 15:20:30 -0400296 auto a_count = AccountModel::instance().rowCount();
Edric Milaret627500d2015-03-27 16:41:40 -0400297 auto found = false;
298 for (int i = 0; i < a_count; ++i) {
Edric Milareta3e47282015-10-23 15:20:30 -0400299 auto idx = AccountModel::instance().index(i, 0);
Edric Milaret627500d2015-03-27 16:41:40 -0400300 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
301 if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) {
Edric Milareta3e47282015-10-23 15:20:30 -0400302 auto account = AccountModel::instance().getAccountByModelIndex(idx);
Edric Milaret68779c42015-07-09 16:53:03 -0400303 if (account->displayName().isEmpty())
304 account->displayName() = account->alias();
305 auto username = account->username();
Edric Milareted0b2802015-10-01 15:10:02 -0400306 ui->ringIdLabel->setText(username);
Edric Milaret627500d2015-03-27 16:41:40 -0400307 found = true;
308 return;
309 }
310 }
311 if (!found) {
Edric Milareted0b2802015-10-01 15:10:02 -0400312 ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
Edric Milaret559bda52015-04-29 17:02:31 -0400313 WizardDialog *wizardDialog = new WizardDialog();
314 wizardDialog->exec();
315 delete wizardDialog;
Edric Milaret627500d2015-03-27 16:41:40 -0400316 }
317}
318
319void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500320CallWidget::callIncoming(Call* call)
Edric Milaret627500d2015-03-27 16:41:40 -0400321{
Nicolas Jager97a21b42015-12-03 16:55:45 -0500322 ui->outboundCall->hide();
323
Edric Milaret2cf34292015-06-22 16:27:03 -0400324 if (!QApplication::activeWindow()) {
325 GlobalSystemTray::instance().showMessage("Ring", "Call incoming from " + call->formattedName());
326 QApplication::alert(this, 5000);
327 }
328
Edric Milaret435cdfc2015-06-01 16:15:50 -0400329 if (!call->account()->isAutoAnswer()) {
Nicolas Jager97a21b42015-12-03 16:55:45 -0500330 ui->callerIdLabel->setText(QString(tr("%1", "%1 is the name of the caller"))
Edric Milareta0ebd062016-01-13 12:18:23 -0500331 .arg(call->formattedName()));
Edric Milareted0b2802015-10-01 15:10:02 -0400332 ui->stackedWidget->setCurrentWidget(ui->callInvitePage);
Edric Milaret627500d2015-03-27 16:41:40 -0400333 ui->callInvite->setVisible(true);
Edric Milaret435cdfc2015-06-01 16:15:50 -0400334 ui->callInvite->raise();
335 }
Edric Milaret6456baa2015-05-21 12:18:07 -0400336 setActualCall(call);
Edric Milaret627500d2015-03-27 16:41:40 -0400337}
338
339void
340CallWidget::on_acceptButton_clicked()
341{
342 if (actualCall_ != nullptr)
Edric Milaret53f57b62015-05-11 11:02:17 -0400343 actualCall_->performAction(Call::Action::ACCEPT);
Edric Milaret627500d2015-03-27 16:41:40 -0400344 ui->callInvite->setVisible(false);
Edric Milareted0b2802015-10-01 15:10:02 -0400345 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milaret627500d2015-03-27 16:41:40 -0400346}
347
348void
349CallWidget::on_refuseButton_clicked()
350{
351 if (actualCall_ == nullptr)
352 return;
353 actualCall_->performAction(Call::Action::REFUSE);
Edric Milaret6456baa2015-05-21 12:18:07 -0400354 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -0400355 ui->callInvite->setVisible(false);
Edric Milareted0b2802015-10-01 15:10:02 -0400356 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Edric Milaret627500d2015-03-27 16:41:40 -0400357}
358
359void
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400360CallWidget::addedCall(Call* call, Call* parent)
361{
Edric Milaret627500d2015-03-27 16:41:40 -0400362 Q_UNUSED(parent);
363 if (call->direction() == Call::Direction::OUTGOING) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400364 setActualCall(call);
Edric Milareted0b2802015-10-01 15:10:02 -0400365 ui->stackedWidget->setCurrentWidget(ui->callInvitePage);
Edric Milaret627500d2015-03-27 16:41:40 -0400366 }
367}
368
369void
Edric Milaret67007d12015-05-07 09:40:09 -0400370CallWidget::callStateChanged(Call* call, Call::State previousState)
371{
Edric Milaret627500d2015-03-27 16:41:40 -0400372 Q_UNUSED(previousState)
Edric Milaret4b1be4a2016-01-15 16:49:20 -0500373 if (call == nullptr
374 || call != actualCall_)
Edric Milaretb5b49072015-05-08 11:56:07 -0400375 return;
Edric Milareted0b2802015-10-01 15:10:02 -0400376
Edric Milaret4b1be4a2016-01-15 16:49:20 -0500377 if (call->state() == Call::State::OVER) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400378 setActualCall(nullptr);
Edric Milaretc54e2272015-10-01 10:14:00 -0400379 ui->instantMessagingWidget->setMediaText(nullptr);
Edric Milareted0b2802015-10-01 15:10:02 -0400380 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Edric Milareta0ebd062016-01-13 12:18:23 -0500381 //TODO : Link this so that recentModel get selected correctly
382 // auto onHoldCall = callModel_->getActiveCalls().first();
383 // if (onHoldCall != nullptr && onHoldCall->state() == Call::State::HOLD) {
384 // setActualCall(onHoldCall);
385 // onHoldCall->performAction(Call::Action::HOLD);
386 // }
Edric Milaret53f57b62015-05-11 11:02:17 -0400387 } else if (call->state() == Call::State::CURRENT) {
Edric Milaretc54e2272015-10-01 10:14:00 -0400388 ui->instantMessagingWidget->setMediaText(actualCall_);
Edric Milareted0b2802015-10-01 15:10:02 -0400389 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milaret627500d2015-03-27 16:41:40 -0400390 }
Edric Milaret627500d2015-03-27 16:41:40 -0400391}
392
393void
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400394CallWidget::atExit()
395{
Edric Milaret627500d2015-03-27 16:41:40 -0400396}
Edric Milaret67007d12015-05-07 09:40:09 -0400397
398void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500399CallWidget::on_contactView_doubleClicked(const QModelIndex& index)
Edric Milaret67007d12015-05-07 09:40:09 -0400400{
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400401 if (not index.isValid())
402 return;
403
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400404 ContactMethod* uri = nullptr;
Edric Milaret67007d12015-05-07 09:40:09 -0400405
Edric Milaret7d40a4a2015-05-13 13:01:15 -0400406 auto var = index.child(0,0).data(
407 static_cast<int>(Person::Role::Object));
408 if (var.isValid()) {
409 Person* person = var.value<Person*>();
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400410 if (person->phoneNumbers().size() == 1) {
411 uri = person->phoneNumbers().at(0);
412 } else if (person->phoneNumbers().size() > 1) {
413 ContactMethodPicker dlg(person->phoneNumbers());
414 auto pos = QCursor::pos();
415 dlg.move(pos.x(), pos.y());
416 if (dlg.exec())
417 uri = dlg.getSelected();
418 }
419 if (uri) {
Edric Milareta3e47282015-10-23 15:20:30 -0400420 auto outCall = CallModel::instance().dialingCall(uri);
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400421 outCall->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400422 ui->mainTabMenu->setCurrentIndex(0);
423 ui->smartList->setFocus();
Edric Milaret67007d12015-05-07 09:40:09 -0400424 }
425 }
Edric Milaret67007d12015-05-07 09:40:09 -0400426}
Edric Milaret53f57b62015-05-11 11:02:17 -0400427
Edric Milaret6456baa2015-05-21 12:18:07 -0400428void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500429CallWidget::on_historyList_doubleClicked(const QModelIndex& index)
Edric Milaret53f57b62015-05-11 11:02:17 -0400430{
Edric Milaret12353822015-05-14 14:41:09 -0400431 if (not index.isValid())
432 return;
433
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400434 auto number = index.data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>();
435 if (number) {
Edric Milareta3e47282015-10-23 15:20:30 -0400436 auto outCall = CallModel::instance().dialingCall(number);
Edric Milaret53f57b62015-05-11 11:02:17 -0400437 outCall->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400438 ui->mainTabMenu->setCurrentIndex(0);
439 ui->smartList->setFocus();
Edric Milaret53f57b62015-05-11 11:02:17 -0400440 }
441}
Edric Milaret6456baa2015-05-21 12:18:07 -0400442
443void
444CallWidget::setActualCall(Call* value)
445{
446 actualCall_ = value;
Edric Milaret80e0b212015-10-16 10:07:43 -0400447 CallModel::instance().selectCall(value);
448 ui->videoWidget->pushRenderer(value);
Edric Milaret6456baa2015-05-21 12:18:07 -0400449}
Edric Milaretc7ab5502015-06-15 11:18:02 -0400450
451void
Edric Milareted0b2802015-10-01 15:10:02 -0400452CallWidget::on_cancelButton_clicked()
Edric Milaretd8528fa2015-07-07 14:13:51 -0400453{
454 if (actualCall_)
455 actualCall_->performAction(Call::Action::REFUSE);
456}
Edric Milareted0b2802015-10-01 15:10:02 -0400457
458void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500459CallWidget::on_smartList_doubleClicked(const QModelIndex& index)
Edric Milareted0b2802015-10-01 15:10:02 -0400460{
Edric Milareta3e47282015-10-23 15:20:30 -0400461 auto realIndex = RecentModel::instance().peopleProxy()->mapToSource(index);
462 if (RecentModel::instance().hasActiveCall(realIndex))
Edric Milareted0b2802015-10-01 15:10:02 -0400463 return;
464
465 ContactMethod* m = nullptr;
466 if (auto cm = realIndex.data((int)Call::Role::ContactMethod).value<ContactMethod*>()) {
467 m = cm;
468 } else {
469 if (auto person = realIndex.data((int)Person::Role::Object).value<Person*>()) {
470 m = person->phoneNumbers().first();
471 }
472 }
Edric Milareta3e47282015-10-23 15:20:30 -0400473 if (m && !RecentModel::instance().index(0, 0, realIndex).isValid()) {
474 Call* c = CallModel::instance().dialingCall(m);
Edric Milareted0b2802015-10-01 15:10:02 -0400475 c->performAction(Call::Action::ACCEPT);
476 }
477}
478
479void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500480CallWidget::smartListSelectionChanged(const QItemSelection& newSel, const QItemSelection& oldSel) {
Edric Milareted0b2802015-10-01 15:10:02 -0400481
482 Q_UNUSED(oldSel)
483
Edric Milaretab12d022015-12-04 16:09:44 -0500484 if (newSel.indexes().empty())
485 {
486 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
487 return;
488 }
Edric Milareted0b2802015-10-01 15:10:02 -0400489 auto newIdx = newSel.indexes().first();
Edric Milaret80e0b212015-10-16 10:07:43 -0400490 if (not newIdx.isValid())
Edric Milareted0b2802015-10-01 15:10:02 -0400491 return;
492
Edric Milaretab12d022015-12-04 16:09:44 -0500493 auto nodeIdx = RecentModel::instance().peopleProxy()->mapToSource(newIdx);
494 auto newIdxCall = RecentModel::instance().getActiveCall(nodeIdx);
Edric Milareted0b2802015-10-01 15:10:02 -0400495
Edric Milareta0ebd062016-01-13 12:18:23 -0500496 if (newIdxCall && newIdxCall != actualCall_) {
Edric Milareted0b2802015-10-01 15:10:02 -0400497 setActualCall(newIdxCall);
498 ui->stackedWidget->setCurrentWidget(ui->videoPage);
Edric Milareta0ebd062016-01-13 12:18:23 -0500499 } else if (newIdxCall == nullptr){
500 setActualCall(nullptr);
501 showIMOutOfCall();
Edric Milareted0b2802015-10-01 15:10:02 -0400502 } else {
503 setActualCall(nullptr);
504 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
505 }
506}
507
508void
509CallWidget::placeCall()
510{
Nicolas Jager97a21b42015-12-03 16:55:45 -0500511 if (ui->ringContactLineEdit->text().isEmpty())
Edric Milareted0b2802015-10-01 15:10:02 -0400512 return;
Nicolas Jager97a21b42015-12-03 16:55:45 -0500513 Call* c = CallModel::instance().dialingCall(PhoneDirectoryModel::instance().getNumber(ui->ringContactLineEdit->text()));
Edric Milareted0b2802015-10-01 15:10:02 -0400514 c->performAction(Call::Action::ACCEPT);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500515 ui->ringContactLineEdit->clear();
Edric Milareted0b2802015-10-01 15:10:02 -0400516}
517
518void
Edric Milaret33cb4832016-01-08 10:14:14 -0500519CallWidget::settingsButton_clicked()
Edric Milareted0b2802015-10-01 15:10:02 -0400520{
521 emit NavigationRequested(ScreenEnum::ConfScreen);
522}
523
524void
Edric Milaret33cb4832016-01-08 10:14:14 -0500525CallWidget::contactButton_clicked(bool checked)
Edric Milareted0b2802015-10-01 15:10:02 -0400526{
Edric Milareted0b2802015-10-01 15:10:02 -0400527 ui->mainTabMenu->setCurrentIndex(checked ? 1 : 0);
528}
529
530void
Edric Milaret33cb4832016-01-08 10:14:14 -0500531CallWidget::historicButton_clicked(bool checked)
Edric Milareted0b2802015-10-01 15:10:02 -0400532{
Edric Milareted0b2802015-10-01 15:10:02 -0400533 ui->mainTabMenu->setCurrentIndex(checked ? 2 : 0);
534}
Nicolas Jager97a21b42015-12-03 16:55:45 -0500535
536void
537CallWidget::on_ringContactLineEdit_returnPressed()
538{
539 placeCall();
540}
541
542void
543CallWidget::on_btnCall_clicked()
544{
545 placeCall();
546}
547
548void
549CallWidget::on_btnvideo_clicked()
550{
551 if (not highLightedIndex_.isValid())
552 return;
553
554 on_smartList_doubleClicked(highLightedIndex_);
555}
Edric Milaretab12d022015-12-04 16:09:44 -0500556
557void
Edric Milareta0ebd062016-01-13 12:18:23 -0500558CallWidget::showIMOutOfCall()
Edric Milaretab12d022015-12-04 16:09:44 -0500559{
560 if (not highLightedIndex_.isValid())
561 return;
562
563 ui->smartList->selectionModel()->select(highLightedIndex_, QItemSelectionModel::ClearAndSelect);
564
565 ui->contactMethodComboBox->clear();
566
567 auto nodeIdx = RecentModel::instance().peopleProxy()->mapToSource(highLightedIndex_);
Edric Milareta0ebd062016-01-13 12:18:23 -0500568 ui->imNameLabel->setText(QString(tr("Conversation with %1", "%1 is the contact name"))
569 .arg(nodeIdx.data(static_cast<int>(Ring::Role::Name)).toString()));
Edric Milaretab12d022015-12-04 16:09:44 -0500570 auto cmVector = RecentModel::instance().getContactMethods(nodeIdx);
Edric Milareta0ebd062016-01-13 12:18:23 -0500571 ui->contactMethodComboBox->setEnabled(cmVector.size() > 1);
Edric Milaretab12d022015-12-04 16:09:44 -0500572 foreach (const ContactMethod* cm, cmVector) {
Edric Milareta0ebd062016-01-13 12:18:23 -0500573 ui->contactMethodComboBox->addItem(cm->uri());
Edric Milaretab12d022015-12-04 16:09:44 -0500574 }
Nicolas Jagerca850292016-01-17 14:11:10 -0500575 slideToRight(messagingPageAnim_, ui->messagingPage);
Edric Milaretab12d022015-12-04 16:09:44 -0500576}
577
578void
579CallWidget::on_sendButton_clicked()
580{
Edric Milareta0ebd062016-01-13 12:18:23 -0500581 if (ui->messageEdit->text().trimmed().isEmpty())
Edric Milaretab12d022015-12-04 16:09:44 -0500582 return;
583 auto number = ui->contactMethodComboBox->currentText();
584 if (auto cm = PhoneDirectoryModel::instance().getNumber(number)) {
585 QMap<QString, QString> msg;
586 msg["text/plain"] = ui->messageEdit->text();
587 cm->sendOfflineTextMessage(msg);
588 ui->messageEdit->clear();
589 } else {
590 qWarning() << "Contact Method not found for " << number;
591 }
592}
593
594void
595CallWidget::on_messageEdit_returnPressed()
596{
597 on_sendButton_clicked();
598}
599
600void
601CallWidget::on_contactMethodComboBox_currentIndexChanged(const QString& number)
602{
603 auto cm = PhoneDirectoryModel::instance().getNumber(number);
604 if (auto txtRecording = cm->textRecording()) {
605 ui->listMessageView->setModel(txtRecording->instantMessagingModel());
606 disconnect(imConnection_);
607 imConnection_ = connect(txtRecording,
Edric Milareta0ebd062016-01-13 12:18:23 -0500608 SIGNAL(messageInserted(QMap<QString,QString>,ContactMethod*,Media::Media::Direction)),
609 this,
610 SLOT(slotAccountMessageReceived(QMap<QString,QString>,ContactMethod*,Media::Media::Direction)));
Edric Milaretab12d022015-12-04 16:09:44 -0500611 ui->listMessageView->scrollToBottom();
612 }
613}
614
615void
616CallWidget::slotAccountMessageReceived(const QMap<QString,QString> message,
617 ContactMethod* cm,
618 Media::Media::Direction dir)
619{
620 Q_UNUSED(message)
621 Q_UNUSED(cm)
622 Q_UNUSED(dir)
623
624 ui->listMessageView->scrollToBottom();
625}
Edric Milaretfa05d972016-01-13 16:22:04 -0500626
627void
628CallWidget::on_ringContactLineEdit_textEdited(const QString& text)
629{
630 RecentModel::instance().peopleProxy()->setFilterWildcard(text);
631}
Edric Milareta0ebd062016-01-13 12:18:23 -0500632
Nicolas Jagerca850292016-01-17 14:11:10 -0500633void
634CallWidget::on_imBackButton_clicked()
Edric Milareta0ebd062016-01-13 12:18:23 -0500635{
Nicolas Jagerca850292016-01-17 14:11:10 -0500636 slideToLeft(welcomePageAnim_, ui->welcomePage);
637}
638
639void
640CallWidget::slideToLeft(QPropertyAnimation* anim, QWidget* widget)
641{
642 ui->stackedWidget->setCurrentWidget(widget);
643 anim->setDuration(animDuration_);
644 anim->setStartValue(QPoint(widget->width(), widget->y()));
645 anim->setEndValue(QPoint(widget->x(), widget->y()));
646 anim->setEasingCurve(QEasingCurve::OutQuad);
647 anim->start();
648}
649
650void
651CallWidget::slideToRight(QPropertyAnimation* anim, QWidget* widget)
652{
653 ui->stackedWidget->setCurrentWidget(widget);
654 anim->setDuration(animDuration_);
655 anim->setStartValue(QPoint(-widget->width(), widget->y()));
656 anim->setEndValue(QPoint(widget->x(), widget->y()));
657 anim->setEasingCurve(QEasingCurve::OutQuad);
658 anim->start();
Edric Milareta0ebd062016-01-13 12:18:23 -0500659}