blob: 5dfe0d841aa4c9b1d5ac07cadcc8877abd31452b [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>
Edric Milaret70ae8782016-04-18 16:10:44 -040023#include <QDesktopServices>
Edric Milaret43f3c1e2015-07-16 17:52:47 -040024
Edric Milaret53f57b62015-05-11 11:02:17 -040025#include <memory>
Edric Milaret627500d2015-03-27 16:41:40 -040026
Edric Milarete19c4cd2016-02-12 10:19:44 -050027#include "qrencode.h"
28
Edric Milaret43f3c1e2015-07-16 17:52:47 -040029//ERROR is defined in windows.h
30#include "utils.h"
31#undef ERROR
Edric Milareta0ebd062016-01-13 12:18:23 -050032#undef interface
Edric Milaret43f3c1e2015-07-16 17:52:47 -040033
Edric Milaret627500d2015-03-27 16:41:40 -040034#include "audio/settings.h"
35#include "personmodel.h"
Edric Milaret43f3c1e2015-07-16 17:52:47 -040036#include "person.h"
Edric Milaret627500d2015-03-27 16:41:40 -040037#include "fallbackpersoncollection.h"
Edric Milaret67007d12015-05-07 09:40:09 -040038#include "categorizedcontactmodel.h"
Edric Milaret6a642e22015-05-27 15:06:30 -040039#include "localhistorycollection.h"
Edric Milaret1b197eb2015-06-01 15:09:56 -040040#include "media/text.h"
41#include "media/recording.h"
Edric Milaret00a32252016-01-19 10:37:13 -050042#include "media/recordingmodel.h"
Edric Milareted0b2802015-10-01 15:10:02 -040043#include "recentmodel.h"
Edric Milaretab12d022015-12-04 16:09:44 -050044#include "contactmethod.h"
Edric Milareta0ebd062016-01-13 12:18:23 -050045#include "globalinstances.h"
Olivier SOLDANO63178ee2016-11-04 16:50:08 -040046#include <availableaccountmodel.h>
Edric Milareted0b2802015-10-01 15:10:02 -040047
Edric Milaret559bda52015-04-29 17:02:31 -040048#include "wizarddialog.h"
Edric Milaret83b248c2015-06-02 11:42:23 -040049#include "windowscontactbackend.h"
Edric Milaret43f3c1e2015-07-16 17:52:47 -040050#include "contactpicker.h"
Edric Milaret2afd2bf2015-07-21 17:12:25 -040051#include "contactmethodpicker.h"
Edric Milaret2cf34292015-06-22 16:27:03 -040052#include "globalsystemtray.h"
Edric Milareted0b2802015-10-01 15:10:02 -040053#include "historydelegate.h"
54#include "contactdelegate.h"
55#include "smartlistdelegate.h"
Edric Milaretab12d022015-12-04 16:09:44 -050056#include "imdelegate.h"
Edric Milareta0ebd062016-01-13 12:18:23 -050057#include "pixbufmanipulator.h"
Edric Milaret70ae8782016-04-18 16:10:44 -040058#include "settingskey.h"
Edric Milaret627500d2015-03-27 16:41:40 -040059
Edric Milaret25236d92016-03-28 09:40:58 -040060#include "profilemodel.h"
61#include "peerprofilecollection.h"
62#include "localprofilecollection.h"
63
Nicolas Jager97a21b42015-12-03 16:55:45 -050064CallWidget::CallWidget(QWidget* parent) :
Nicolas Jager74fe46f2016-02-29 14:55:09 -050065 NavWidget(parent),
Edric Milaret7d40a4a2015-05-13 13:01:15 -040066 ui(new Ui::CallWidget),
Edric Milaretab12d022015-12-04 16:09:44 -050067 menu_(new QMenu()),
68 imDelegate_(new ImDelegate())
Edric Milaret627500d2015-03-27 16:41:40 -040069{
70 ui->setupUi(this);
71
Edric Milaret6b68a482016-02-01 15:23:44 -050072 pageAnim_ = new QPropertyAnimation(ui->welcomePage, "pos", this);
Nicolas Jagerca850292016-01-17 14:11:10 -050073
Edric Milaret6456baa2015-05-21 12:18:07 -040074 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -040075 videoRenderer_ = nullptr;
76
Nicolas Jager74fe46f2016-02-29 14:55:09 -050077 connect(ui->settingsButton, &QPushButton::clicked, this, &CallWidget::settingsButtonClicked);
78
Edric Milaret3aca8e32015-06-12 10:01:40 -040079 connect(ui->videoWidget, SIGNAL(setChatVisibility(bool)),
80 ui->instantMessagingWidget, SLOT(setVisible(bool)));
81
Edric Milareted0b2802015-10-01 15:10:02 -040082 QPixmap logo(":/images/logo-ring-standard-coul.png");
83 ui->ringLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation));
84 ui->ringLogo->setAlignment(Qt::AlignHCenter);
85
Edric Milaret1e598592016-09-02 10:10:01 -040086 ui->qrLabel->hide();
Edric Milarete19c4cd2016-02-12 10:19:44 -050087
Edric Milareta0ebd062016-01-13 12:18:23 -050088 GlobalInstances::setPixmapManipulator(std::unique_ptr<Interfaces::PixbufManipulator>(new Interfaces::PixbufManipulator()));
89
Edric Milaret627500d2015-03-27 16:41:40 -040090 try {
Edric Milareta3e47282015-10-23 15:20:30 -040091 callModel_ = &CallModel::instance();
Edric Milaret627500d2015-03-27 16:41:40 -040092
93 connect(callModel_, SIGNAL(incomingCall(Call*)),
94 this, SLOT(callIncoming(Call*)));
Edric Milaret627500d2015-03-27 16:41:40 -040095 connect(callModel_, SIGNAL(callStateChanged(Call*, Call::State)),
96 this, SLOT(callStateChanged(Call*, Call::State)));
97
Edric Milareta3e47282015-10-23 15:20:30 -040098 connect(&AccountModel::instance()
Edric Milaret67007d12015-05-07 09:40:09 -040099 , SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))
100 , this
101 , SLOT(findRingAccount(QModelIndex, QModelIndex, QVector<int>)));
102
Edric Milaretfa05d972016-01-13 16:22:04 -0500103 RecentModel::instance().peopleProxy()->setFilterRole(static_cast<int>(Ring::Role::Name));
104 RecentModel::instance().peopleProxy()->setFilterCaseSensitivity(Qt::CaseInsensitive);
Edric Milareta3e47282015-10-23 15:20:30 -0400105 ui->smartList->setModel(RecentModel::instance().peopleProxy());
Edric Milaret6816fd72016-01-29 16:36:24 -0500106
107 smartListDelegate_ = new SmartListDelegate();
108 ui->smartList->setSmartListItemDelegate(smartListDelegate_);
Edric Milaret627500d2015-03-27 16:41:40 -0400109
Edric Milaret25236d92016-03-28 09:40:58 -0400110 PersonModel::instance().addCollection<PeerProfileCollection>(LoadOptions::FORCE_ENABLED);
111 ProfileModel::instance().addCollection<LocalProfileCollection>(LoadOptions::FORCE_ENABLED);
112
Edric Milareta3e47282015-10-23 15:20:30 -0400113 PersonModel::instance().
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400114 addCollection<WindowsContactBackend>(LoadOptions::FORCE_ENABLED);
115
Edric Milareta3e47282015-10-23 15:20:30 -0400116 CategorizedContactModel::instance().setSortAlphabetical(false);
117 CategorizedContactModel::instance().setUnreachableHidden(true);
118 ui->contactView->setModel(&CategorizedContactModel::instance());
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400119 contactDelegate_ = new ContactDelegate();
120 ui->contactView->setItemDelegate(contactDelegate_);
121
Edric Milareta3e47282015-10-23 15:20:30 -0400122 CategorizedHistoryModel::instance().
Edric Milaret6a642e22015-05-27 15:06:30 -0400123 addCollection<LocalHistoryCollection>(LoadOptions::FORCE_ENABLED);
Edric Milaret627500d2015-03-27 16:41:40 -0400124
Edric Milareta3e47282015-10-23 15:20:30 -0400125 ui->historyList->setModel(CategorizedHistoryModel::SortedProxy::instance().model());
126 CategorizedHistoryModel::SortedProxy::instance().model()->sort(0, Qt::DescendingOrder);
Edric Milaret53f57b62015-05-11 11:02:17 -0400127 ui->historyList->setHeaderHidden(true);
Edric Milaret01f23842015-06-22 14:46:01 -0400128 historyDelegate_ = new HistoryDelegate();
129 ui->historyList->setItemDelegate(historyDelegate_);
Edric Milaret77dd6982015-07-07 16:45:41 -0400130
Edric Milareta3e47282015-10-23 15:20:30 -0400131 connect(CategorizedHistoryModel::SortedProxy::instance().model(), &QSortFilterProxyModel::layoutChanged, [=]() {
132 auto idx = CategorizedHistoryModel::SortedProxy::instance().model()->index(0,0);
Edric Milaret77dd6982015-07-07 16:45:41 -0400133 if (idx.isValid())
134 ui->historyList->setExpanded(idx, true);
135 });
136
Edric Milaret6b68a482016-02-01 15:23:44 -0500137 connect(ui->smartList, &QTreeView::entered, this, &CallWidget::on_entered);
138
139 smartListDelegate_ = new SmartListDelegate();
140 ui->smartList->setSmartListItemDelegate(smartListDelegate_);
141
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400142 ui->historyList->setContextMenuPolicy(Qt::CustomContextMenu);
143 connect(ui->historyList, &QListView::customContextMenuRequested, [=](const QPoint& pos){
144 if (ui->historyList->currentIndex().parent().isValid()) {
145 QPoint globalPos = ui->historyList->mapToGlobal(pos);
146 QMenu menu;
147
148 ContactMethod* contactMethod = ui->historyList->currentIndex()
149 .data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>();
150
Edric Milaret53ac6e52015-09-14 13:37:06 -0400151 auto copyAction = new QAction(tr("Copy number"), this);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400152 menu.addAction(copyAction);
153 connect(copyAction, &QAction::triggered, [=]() {
154 QApplication::clipboard()->setText(contactMethod->uri());
155 });
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400156 if (not contactMethod->contact() || contactMethod->contact()->isPlaceHolder()) {
Edric Milaret53ac6e52015-09-14 13:37:06 -0400157 auto addExisting = new QAction(tr("Add to contact"), this);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400158 menu.addAction(addExisting);
159 connect(addExisting, &QAction::triggered, [=]() {
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400160 ContactPicker contactPicker(contactMethod);
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400161 contactPicker.move(globalPos.x(), globalPos.y() - (contactPicker.height()/2));
Edric Milaretbe0aa5a2015-07-31 15:08:39 -0400162 contactPicker.exec();
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400163 });
164 }
165 menu.exec(globalPos);
166 }
167 });
Edric Milaret53f57b62015-05-11 11:02:17 -0400168
Edric Milaret627500d2015-03-27 16:41:40 -0400169 findRingAccount();
Edric Milareta0ebd062016-01-13 12:18:23 -0500170 setupOutOfCallIM();
171 setupSmartListMenu();
Edric Milaret627500d2015-03-27 16:41:40 -0400172
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500173 connect(ui->smartList, &SmartList::btnVideoClicked, this, &CallWidget::btnComBarVideoClicked);
Nicolas Jager41e4fcf2016-01-28 11:37:03 -0500174
Edric Milaret6b68a482016-02-01 15:23:44 -0500175 connect(RecentModel::instance().selectionModel(),
Olivier SOLDANO61065ec2016-11-11 16:31:34 -0500176 SIGNAL(currentChanged(QModelIndex,QModelIndex)),
177 this,
178 SLOT(smartListCurrentChanged(QModelIndex,QModelIndex)));
179
Olivier SOLDANOea6d71b2016-11-16 15:56:59 -0500180 connect(RecentModel::instance().selectionModel(), &QItemSelectionModel::selectionChanged, [=](const QItemSelection &selected, const QItemSelection &deselected) {
181 // lambda used to focus on the correct smartList element when switching automatically between two calls
182 Q_UNUSED(deselected)
183 if (selected.size()) {
184 auto idx = selected.indexes().first();
185 auto realIdx = RecentModel::instance().peopleProxy()->mapFromSource(idx);
186 ui->smartList->selectionModel()->setCurrentIndex(realIdx, QItemSelectionModel::ClearAndSelect);
187 } else
188 ui->smartList->clearSelection();
189 });
190
Anthony LĂ©onardaa90e1a2016-10-12 11:24:17 -0400191 connect(&NameDirectory::instance(), SIGNAL(registeredNameFound(const Account*,NameDirectory::LookupStatus,const QString&,const QString&)),
192 this, SLOT(contactLineEdit_registeredNameFound(const Account*,NameDirectory::LookupStatus,const QString&,const QString&)));
193
Edric Milaret80e0b212015-10-16 10:07:43 -0400194 } catch (const std::exception& e) {
195 qDebug() << "INIT ERROR" << e.what();
Edric Milaret627500d2015-03-27 16:41:40 -0400196 }
197}
198
199CallWidget::~CallWidget()
200{
201 delete ui;
Edric Milaretc7ab5502015-06-15 11:18:02 -0400202 delete menu_;
Edric Milaret01f23842015-06-22 14:46:01 -0400203 delete contactDelegate_;
Edric Milaretab12d022015-12-04 16:09:44 -0500204 delete imDelegate_;
Edric Milaret6b68a482016-02-01 15:23:44 -0500205 delete pageAnim_;
206 delete smartListDelegate_;
Edric Milarete19c4cd2016-02-12 10:19:44 -0500207 delete shareMenu_;
208}
209
210void
Edric Milareta0ebd062016-01-13 12:18:23 -0500211CallWidget::setupOutOfCallIM()
212{
213 ui->listMessageView->setItemDelegate(imDelegate_);
214 ui->listMessageView->setContextMenuPolicy(Qt::ActionsContextMenu);
215
216 auto copyAction = new QAction(tr("Copy"), this);
217 ui->listMessageView->addAction(copyAction);
218 connect(copyAction, &QAction::triggered, [=]() {
219 auto idx = ui->listMessageView->currentIndex();
220 if (idx.isValid()) {
221 auto text = ui->listMessageView->model()->data(idx);
222 QApplication::clipboard()->setText(text.value<QString>());
223 }
224 });
Edric Milaret70ae8782016-04-18 16:10:44 -0400225 QSettings settings;
Edric Milareta0ebd062016-01-13 12:18:23 -0500226 auto displayDate = new QAction(tr("Display date"), this);
227 displayDate->setCheckable(true);
Edric Milaret70ae8782016-04-18 16:10:44 -0400228 displayDate->setChecked(settings.value(SettingsKey::imShowDate).toBool());
Edric Milareta0ebd062016-01-13 12:18:23 -0500229 ui->listMessageView->addAction(displayDate);
230 auto displayAuthor = new QAction(tr("Display author"), this);
231 displayAuthor->setCheckable(true);
Edric Milaret70ae8782016-04-18 16:10:44 -0400232 displayAuthor->setChecked(settings.value(SettingsKey::imShowAuthor).toBool());
Edric Milareta0ebd062016-01-13 12:18:23 -0500233 ui->listMessageView->addAction(displayAuthor);
234 auto lamdba = [=](){
Edric Milaret70ae8782016-04-18 16:10:44 -0400235 QSettings settings;
236 settings.setValue(SettingsKey::imShowAuthor, displayAuthor->isChecked());
237 settings.setValue(SettingsKey::imShowDate, displayDate->isChecked());
238 emit imDelegate_->sizeHintChanged(QModelIndex());
Edric Milareta0ebd062016-01-13 12:18:23 -0500239 };
240 connect(displayAuthor, &QAction::triggered, lamdba);
241 connect(displayDate, &QAction::triggered, lamdba);
Edric Milaret00a32252016-01-19 10:37:13 -0500242
243 connect(&::Media::RecordingModel::instance(),
244 SIGNAL(newTextMessage(::Media::TextRecording*, ContactMethod*)),
245 this,
246 SLOT(onIncomingMessage(::Media::TextRecording*, ContactMethod*)));
247}
248
249void
250CallWidget::onIncomingMessage(::Media::TextRecording* t, ContactMethod* cm) {
251 Q_UNUSED(cm)
252
253 if (!QApplication::focusWidget()) {
254 auto idx = t->instantTextMessagingModel()->
255 index(t->instantTextMessagingModel()->rowCount()-1, 0);
256 GlobalSystemTray::instance()
257 .showMessage("Ring",
258 QString(tr("Message incoming from %1")).arg(
259 idx.data((int)Media::TextRecording::Role::AuthorDisplayname).toString()));
260 QApplication::alert(this, 5000);
261 }
Edric Milareta0ebd062016-01-13 12:18:23 -0500262}
263
264void
265CallWidget::setupSmartListMenu() {
266 ui->smartList->setContextMenuPolicy(Qt::CustomContextMenu);
267 connect(ui->smartList, &QListView::customContextMenuRequested, [=](const QPoint& pos){
268 auto idx = ui->smartList->currentIndex();
269 if (not idx.isValid())
270 return;
271 QPoint globalPos = ui->smartList->mapToGlobal(pos);
272 QMenu menu;
273
Edric Milaret9949b342016-02-02 12:25:08 -0500274 QVector<ContactMethod*> contactMethods = RecentModel::instance()
275 .getContactMethods(RecentModel::instance().peopleProxy()->mapToSource(idx));
276 if (contactMethods.isEmpty())
Edric Milareta0ebd062016-01-13 12:18:23 -0500277 return;
Edric Milaret9949b342016-02-02 12:25:08 -0500278
279 if (contactMethods.size() == 1) {
280 auto contactMethod = contactMethods.at(0);
281 auto copyAction = new QAction(tr("Copy number"), this);
282 menu.addAction(copyAction);
283 connect(copyAction, &QAction::triggered, [contactMethod]() {
284 QApplication::clipboard()->setText(contactMethod->uri());
Edric Milareta0ebd062016-01-13 12:18:23 -0500285 });
Edric Milaretac21b3d2016-09-01 12:45:49 -0400286 auto copyNameAction = new QAction(tr("Copy name"), this);
287 menu.addAction(copyNameAction);
288 connect(copyNameAction, &QAction::triggered, [contactMethod]() {
289 QApplication::clipboard()->setText(contactMethod->primaryName());
290 });
Edric Milaret9949b342016-02-02 12:25:08 -0500291 if (not contactMethod->contact() || contactMethod->contact()->isPlaceHolder()) {
292 auto addExisting = new QAction(tr("Add to contact"), this);
293 menu.addAction(addExisting);
294 connect(addExisting, &QAction::triggered, [globalPos, contactMethod]() {
295 ContactPicker contactPicker(contactMethod);
296 contactPicker.move(globalPos.x(), globalPos.y() - (contactPicker.height()/2));
297 contactPicker.exec();
298 });
299 }
300 }
301 else {
302 auto callMenu = menu.addMenu(tr("Call Number"));
303 auto copyMenu = menu.addMenu(tr("Copy Number"));
304 for (auto cM : contactMethods) {
305 auto uri = cM->uri();
306 auto copyAction = new QAction(tr("Copy %1").arg(uri), this);
307 copyMenu->addAction(copyAction);
308 connect(copyAction, &QAction::triggered, [uri]() {
309 QApplication::clipboard()->setText(uri);
310 });
311 auto callAction = new QAction(tr("Call %1").arg(uri), this);
312 callMenu->addAction(callAction);
313 connect(callAction, &QAction::triggered, [cM]() {
314 Call* c = CallModel::instance().dialingCall(cM);
315 c->performAction(Call::Action::ACCEPT);
316 });
317 }
Edric Milareta0ebd062016-01-13 12:18:23 -0500318 }
319 menu.exec(globalPos);
320 });
321}
322
323void
Edric Milaret67007d12015-05-07 09:40:09 -0400324CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector<int> vec)
325{
326 Q_UNUSED(idx1)
327 Q_UNUSED(idx2)
328 Q_UNUSED(vec)
329
Edric Milareta3e47282015-10-23 15:20:30 -0400330 auto a_count = AccountModel::instance().rowCount();
Edric Milaret67007d12015-05-07 09:40:09 -0400331 for (int i = 0; i < a_count; ++i) {
Edric Milareta3e47282015-10-23 15:20:30 -0400332 auto idx = AccountModel::instance().index(i, 0);
Edric Milaret67007d12015-05-07 09:40:09 -0400333 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
Edric Milaret74474f52016-05-16 13:36:23 -0400334 if (static_cast<Account::Protocol>(protocol.toUInt()) == Account::Protocol::RING) {
Anthony LĂ©onarda86a8972016-12-15 10:33:47 -0500335 auto account = AccountModel::instance().getAccountByModelIndex(idx);
336 auto registeredName = account->registeredName();
Edric Milaret67007d12015-05-07 09:40:09 -0400337 auto username = idx.data(static_cast<int>(Account::Role::Username));
Anthony LĂ©onarda86a8972016-12-15 10:33:47 -0500338 if (registeredName.isEmpty()) {
339 ui->ringIdLabel->setText(username.toString());
340 } else
341 ui->ringIdLabel->setText(registeredName);
342 setupQRCode(username.toString());
Edric Milaret67007d12015-05-07 09:40:09 -0400343 return;
344 }
345 }
Edric Milaret74474f52016-05-16 13:36:23 -0400346 ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
Edric Milaret67007d12015-05-07 09:40:09 -0400347}
348
Anthony LĂ©onarda86a8972016-12-15 10:33:47 -0500349void CallWidget::setupQRCode(QString ringID)
Edric Milarete19c4cd2016-02-12 10:19:44 -0500350{
Anthony LĂ©onarda86a8972016-12-15 10:33:47 -0500351 auto rcode = QRcode_encodeString(ringID.toStdString().c_str(),
Edric Milaret6d0e5312016-04-04 16:30:22 -0400352 0, //Let the version be decided by libqrencode
353 QR_ECLEVEL_L, // Lowest level of error correction
Edric Milarete19c4cd2016-02-12 10:19:44 -0500354 QR_MODE_8, // 8-bit data mode
355 1);
356 if (not rcode) {
357 qWarning() << "Failed to generate QR code: " << strerror(errno);
358 return;
359 }
360
361 auto margin = 5;
362 int qrwidth = rcode->width + margin * 2;
363 QImage result(QSize(qrwidth, qrwidth), QImage::Format_Mono);
364 QPainter painter;
365 painter.begin(&result);
366 painter.setClipRect(QRect(0, 0, qrwidth, qrwidth));
367 painter.setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
368 painter.setBrush(Qt::black);
369 painter.fillRect(QRect(0, 0, qrwidth, qrwidth), Qt::white);
Edric Milaret74474f52016-05-16 13:36:23 -0400370 unsigned char* p;
Edric Milarete19c4cd2016-02-12 10:19:44 -0500371 p = rcode->data;
372 for(int y = 0; y < rcode->width; y++) {
Edric Milaret74474f52016-05-16 13:36:23 -0400373 unsigned char* row = (p + (y * rcode->width));
Edric Milarete19c4cd2016-02-12 10:19:44 -0500374 for(int x = 0; x < rcode->width; x++) {
375 if(*(row + x) & 0x1) {
376 painter.drawRect(margin + x, margin + y, 1, 1);
377 }
378 }
379
380 }
381 painter.end();
382 QRcode_free(rcode);
Edric Milaret6d0e5312016-04-04 16:30:22 -0400383 ui->qrLabel->setPixmap(QPixmap::fromImage(result.scaled(QSize(qrSize_, qrSize_), Qt::KeepAspectRatio)));
Edric Milarete19c4cd2016-02-12 10:19:44 -0500384}
385
Edric Milaret67007d12015-05-07 09:40:09 -0400386void
387CallWidget::findRingAccount()
388{
Anthony LĂ©onard314c2a42016-10-20 10:39:56 -0400389 ui->ringIdLabel->clear();
Edric Milaret57467842016-08-30 13:06:11 -0400390
Edric Milareta3e47282015-10-23 15:20:30 -0400391 auto a_count = AccountModel::instance().rowCount();
Edric Milaret627500d2015-03-27 16:41:40 -0400392 for (int i = 0; i < a_count; ++i) {
Edric Milareta3e47282015-10-23 15:20:30 -0400393 auto idx = AccountModel::instance().index(i, 0);
Edric Milaret627500d2015-03-27 16:41:40 -0400394 auto protocol = idx.data(static_cast<int>(Account::Role::Proto));
Edric Milaret74474f52016-05-16 13:36:23 -0400395 if (static_cast<Account::Protocol>(protocol.toUInt()) == Account::Protocol::RING) {
Edric Milareta3e47282015-10-23 15:20:30 -0400396 auto account = AccountModel::instance().getAccountByModelIndex(idx);
Edric Milaret68779c42015-07-09 16:53:03 -0400397 if (account->displayName().isEmpty())
398 account->displayName() = account->alias();
Edric Milaret57467842016-08-30 13:06:11 -0400399 if (account->needsMigration()) {
400 WizardDialog dlg(WizardDialog::MIGRATION, account);
401 dlg.exec();
402 }
403 if (ui->ringIdLabel->text().isEmpty()) {
Anthony LĂ©onarda86a8972016-12-15 10:33:47 -0500404 auto registeredName = account->registeredName();
405 ui->ringIdLabel->setText((registeredName.isEmpty())?account->username():registeredName);
406 setupQRCode(account->username());
Edric Milaret57467842016-08-30 13:06:11 -0400407 }
Edric Milaret627500d2015-03-27 16:41:40 -0400408 }
409 }
Edric Milaret57467842016-08-30 13:06:11 -0400410 if (ui->ringIdLabel->text().isEmpty()) {
411 ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
412 WizardDialog wizardDialog;
413 wizardDialog.exec();
414 }
Edric Milaret627500d2015-03-27 16:41:40 -0400415}
416
417void
Edric Milaret00d34f22016-05-09 16:30:29 -0400418CallWidget::callChangedSlot()
419{
420 if (not actualCall_)
421 return;
Edric Milaret41941582016-09-14 12:59:04 -0400422 ui->callerIdLabel->setText(QString("%1")
Edric Milaret00d34f22016-05-09 16:30:29 -0400423 .arg(actualCall_->formattedName()));
424 ui->callerPhoto->setPixmap(
425 QPixmap::fromImage(
426 GlobalInstances::pixmapManipulator()
427 .callPhoto(actualCall_, QSize(130,130)).value<QImage>()));
Olivier SOLDANO2f9e6702016-11-02 14:20:57 -0400428
Olivier SOLDANO02971ce2016-11-04 15:38:29 -0400429 if(actualCall_->state() == Call::State::OVER || actualCall_->state() == Call::State::FAILURE){
Olivier SOLDANO2f9e6702016-11-02 14:20:57 -0400430 ui->outboundCallLabel->setText(actualCall_->toHumanStateName(Call::State::INITIALIZATION));
431 } else {
432 ui->outboundCallLabel->setText(actualCall_->toHumanStateName());
433 }
Edric Milaret00d34f22016-05-09 16:30:29 -0400434}
435
436void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500437CallWidget::callIncoming(Call* call)
Edric Milaret627500d2015-03-27 16:41:40 -0400438{
Edric Milaret00a32252016-01-19 10:37:13 -0500439 if (!QApplication::focusWidget()) {
440 GlobalSystemTray::instance()
441 .showMessage("Ring",
442 QString(tr("Call incoming from %1")).arg(call->formattedName()));
Edric Milaret2cf34292015-06-22 16:27:03 -0400443 QApplication::alert(this, 5000);
444 }
445
Edric Milaret6456baa2015-05-21 12:18:07 -0400446 setActualCall(call);
Edric Milaret627500d2015-03-27 16:41:40 -0400447}
448
449void
450CallWidget::on_acceptButton_clicked()
451{
452 if (actualCall_ != nullptr)
Edric Milaret53f57b62015-05-11 11:02:17 -0400453 actualCall_->performAction(Call::Action::ACCEPT);
Edric Milaret627500d2015-03-27 16:41:40 -0400454}
455
456void
457CallWidget::on_refuseButton_clicked()
458{
459 if (actualCall_ == nullptr)
460 return;
461 actualCall_->performAction(Call::Action::REFUSE);
Nicolas Jager13745062016-02-12 18:56:40 -0500462 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Edric Milaret6456baa2015-05-21 12:18:07 -0400463 setActualCall(nullptr);
Edric Milaret627500d2015-03-27 16:41:40 -0400464}
465
466void
Edric Milaret67007d12015-05-07 09:40:09 -0400467CallWidget::callStateChanged(Call* call, Call::State previousState)
468{
Edric Milaret627500d2015-03-27 16:41:40 -0400469 Q_UNUSED(previousState)
Edric Milaret4b1be4a2016-01-15 16:49:20 -0500470 if (call == nullptr
471 || call != actualCall_)
Edric Milaretb5b49072015-05-08 11:56:07 -0400472 return;
Edric Milareted0b2802015-10-01 15:10:02 -0400473
Olivier SOLDANOea6d71b2016-11-16 15:56:59 -0500474 callStateToView(call);
475
Edric Milaret4b1be4a2016-01-15 16:49:20 -0500476 if (call->state() == Call::State::OVER) {
Edric Milaret6456baa2015-05-21 12:18:07 -0400477 setActualCall(nullptr);
Olivier SOLDANOea6d71b2016-11-16 15:56:59 -0500478 ui->smartList->clearSelection();
Edric Milaret6b68a482016-02-01 15:23:44 -0500479 RecentModel::instance().selectionModel()->clear();
Edric Milaret627500d2015-03-27 16:41:40 -0400480 }
Edric Milaret627500d2015-03-27 16:41:40 -0400481}
482
483void
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400484CallWidget::atExit()
485{
Edric Milaret627500d2015-03-27 16:41:40 -0400486}
Edric Milaret67007d12015-05-07 09:40:09 -0400487
488void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500489CallWidget::on_contactView_doubleClicked(const QModelIndex& index)
Edric Milaret67007d12015-05-07 09:40:09 -0400490{
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400491 if (not index.isValid())
492 return;
493
Edric Milaret7d40a4a2015-05-13 13:01:15 -0400494 auto var = index.child(0,0).data(
495 static_cast<int>(Person::Role::Object));
496 if (var.isValid()) {
497 Person* person = var.value<Person*>();
Edric Milaret74474f52016-05-16 13:36:23 -0400498 ContactMethod* uri = nullptr;
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400499 if (person->phoneNumbers().size() == 1) {
500 uri = person->phoneNumbers().at(0);
501 } else if (person->phoneNumbers().size() > 1) {
502 ContactMethodPicker dlg(person->phoneNumbers());
503 auto pos = QCursor::pos();
504 dlg.move(pos.x(), pos.y());
505 if (dlg.exec())
506 uri = dlg.getSelected();
507 }
508 if (uri) {
Edric Milareta3e47282015-10-23 15:20:30 -0400509 auto outCall = CallModel::instance().dialingCall(uri);
Edric Milaret2afd2bf2015-07-21 17:12:25 -0400510 outCall->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400511 ui->mainTabMenu->setCurrentIndex(0);
512 ui->smartList->setFocus();
Edric Milaret67007d12015-05-07 09:40:09 -0400513 }
514 }
Edric Milaret67007d12015-05-07 09:40:09 -0400515}
Edric Milaret53f57b62015-05-11 11:02:17 -0400516
Edric Milaret6456baa2015-05-21 12:18:07 -0400517void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500518CallWidget::on_historyList_doubleClicked(const QModelIndex& index)
Edric Milaret53f57b62015-05-11 11:02:17 -0400519{
Edric Milaret12353822015-05-14 14:41:09 -0400520 if (not index.isValid())
521 return;
522
Edric Milaret43f3c1e2015-07-16 17:52:47 -0400523 auto number = index.data(static_cast<int>(Call::Role::ContactMethod)).value<ContactMethod*>();
524 if (number) {
Edric Milareta3e47282015-10-23 15:20:30 -0400525 auto outCall = CallModel::instance().dialingCall(number);
Edric Milaret53f57b62015-05-11 11:02:17 -0400526 outCall->performAction(Call::Action::ACCEPT);
Edric Milareted0b2802015-10-01 15:10:02 -0400527 ui->mainTabMenu->setCurrentIndex(0);
528 ui->smartList->setFocus();
Edric Milaret53f57b62015-05-11 11:02:17 -0400529 }
530}
Edric Milaret6456baa2015-05-21 12:18:07 -0400531
Edric Milaret6b68a482016-02-01 15:23:44 -0500532void CallWidget::callStateToView(Call* value)
533{
534 if (value) {
535 switch (value->state()) {
536 case Call::State::INCOMING:
537 if (not value->account()->isAutoAnswer())
538 ui->stackedWidget->setCurrentWidget(ui->callInvitePage);
539 else
540 ui->stackedWidget->setCurrentWidget(ui->videoPage);
541 break;
542 case Call::State::CURRENT:
Edric Milareta86e3f52016-03-14 16:28:57 -0400543 case Call::State::CONFERENCE:
Edric Milaret854c6b44d2016-03-08 11:00:48 -0500544 case Call::State::HOLD:
Edric Milaret6b68a482016-02-01 15:23:44 -0500545 ui->stackedWidget->setCurrentWidget(ui->videoPage);
546 break;
Olivier SOLDANO02971ce2016-11-04 15:38:29 -0400547 case Call::State::OVER:
Olivier SOLDANOea6d71b2016-11-16 15:56:59 -0500548 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
Olivier SOLDANO02971ce2016-11-04 15:38:29 -0400549 break;
Olivier SOLDANO2f9e6702016-11-02 14:20:57 -0400550 case Call::State::FAILURE:
551 case Call::State::ERROR:
Olivier SOLDANO02971ce2016-11-04 15:38:29 -0400552 on_cancelButton_clicked();
Edric Milaret6b68a482016-02-01 15:23:44 -0500553 break;
554 case Call::State::INITIALIZATION:
555 case Call::State::CONNECTED:
556 case Call::State::RINGING:
Edric Milaret6b68a482016-02-01 15:23:44 -0500557 ui->stackedWidget->setCurrentWidget(ui->outboundCallPage);
558 break;
559 default:
Edric Milaret854c6b44d2016-03-08 11:00:48 -0500560 qWarning() << "Call state not handled doing nothing : "
561 << value->toHumanStateName();
Edric Milaret6b68a482016-02-01 15:23:44 -0500562 break;
563 }
Nicolas Jager13745062016-02-12 18:56:40 -0500564 }
Edric Milaret6b68a482016-02-01 15:23:44 -0500565}
566
Edric Milaret6456baa2015-05-21 12:18:07 -0400567void
568CallWidget::setActualCall(Call* value)
569{
570 actualCall_ = value;
Edric Milaret80e0b212015-10-16 10:07:43 -0400571 CallModel::instance().selectCall(value);
572 ui->videoWidget->pushRenderer(value);
Edric Milareta86e3f52016-03-14 16:28:57 -0400573 ui->instantMessagingWidget->setMediaText(actualCall_);
Edric Milaret6b68a482016-02-01 15:23:44 -0500574 callStateToView(value);
Edric Milaret00d34f22016-05-09 16:30:29 -0400575 if (actualCall_) {
576 callChangedConnection_ = connect(actualCall_,
577 SIGNAL(changed()),
578 this,
579 SLOT(callChangedSlot()));
580 } else
581 disconnect(callChangedConnection_);
582
Edric Milaret6456baa2015-05-21 12:18:07 -0400583}
Edric Milaretc7ab5502015-06-15 11:18:02 -0400584
585void
Edric Milareted0b2802015-10-01 15:10:02 -0400586CallWidget::on_cancelButton_clicked()
Edric Milaretd8528fa2015-07-07 14:13:51 -0400587{
Olivier SOLDANO2f9e6702016-11-02 14:20:57 -0400588 if (actualCall_){
Edric Milaretd8528fa2015-07-07 14:13:51 -0400589 actualCall_->performAction(Call::Action::REFUSE);
Olivier SOLDANO2f9e6702016-11-02 14:20:57 -0400590 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
591 }
Edric Milaretd8528fa2015-07-07 14:13:51 -0400592}
Edric Milareted0b2802015-10-01 15:10:02 -0400593
594void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500595CallWidget::on_smartList_doubleClicked(const QModelIndex& index)
Edric Milareted0b2802015-10-01 15:10:02 -0400596{
Edric Milareta3e47282015-10-23 15:20:30 -0400597 auto realIndex = RecentModel::instance().peopleProxy()->mapToSource(index);
598 if (RecentModel::instance().hasActiveCall(realIndex))
Edric Milareted0b2802015-10-01 15:10:02 -0400599 return;
600
601 ContactMethod* m = nullptr;
602 if (auto cm = realIndex.data((int)Call::Role::ContactMethod).value<ContactMethod*>()) {
603 m = cm;
604 } else {
605 if (auto person = realIndex.data((int)Person::Role::Object).value<Person*>()) {
606 m = person->phoneNumbers().first();
607 }
608 }
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500609
Edric Milareta3e47282015-10-23 15:20:30 -0400610 if (m && !RecentModel::instance().index(0, 0, realIndex).isValid()) {
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500611
612 QPixmap map = QPixmap::fromImage(
613 GlobalInstances::pixmapManipulator().callPhoto(m, QSize(130,130)).value<QImage>());
614 ui->callingPhoto->setPixmap(map);
615
Edric Milareta3e47282015-10-23 15:20:30 -0400616 Call* c = CallModel::instance().dialingCall(m);
Edric Milareted0b2802015-10-01 15:10:02 -0400617 c->performAction(Call::Action::ACCEPT);
Edric Milaret6b68a482016-02-01 15:23:44 -0500618 setActualCall(c);
Edric Milareted0b2802015-10-01 15:10:02 -0400619 }
620}
621
622void
Olivier SOLDANO61065ec2016-11-11 16:31:34 -0500623CallWidget::smartListCurrentChanged(const QModelIndex &currentIdx, const QModelIndex &previousIdx)
624{
625 Q_UNUSED(previousIdx);
626 if (not currentIdx.isValid())
Edric Milareted0b2802015-10-01 15:10:02 -0400627 return;
628
Olivier SOLDANO703caba2016-11-15 16:18:55 -0500629 //catch call of current index
Olivier SOLDANO61065ec2016-11-11 16:31:34 -0500630 auto currentIdxCall = RecentModel::instance().getActiveCall(currentIdx);
Olivier SOLDANO703caba2016-11-15 16:18:55 -0500631
632 if (currentIdxCall && currentIdxCall != actualCall_) { //if it is different from actual call, switch between the two
Olivier SOLDANO61065ec2016-11-11 16:31:34 -0500633 setActualCall(currentIdxCall);
Olivier SOLDANO703caba2016-11-15 16:18:55 -0500634 } else if (currentIdxCall == nullptr){ // if there is no call attached to this smartlist index (contact tab)
Edric Milareta0ebd062016-01-13 12:18:23 -0500635 setActualCall(nullptr);
Olivier SOLDANO703caba2016-11-15 16:18:55 -0500636 showIMOutOfCall(currentIdx); //change page to messaging page with correct behaviour
637 } else { // if non defined behaviour disconnect instant messaging and return to welcome page
Edric Milareted0b2802015-10-01 15:10:02 -0400638 setActualCall(nullptr);
Edric Milaret7ef617b2016-02-01 15:40:57 -0500639 if (imConnection_)
640 disconnect(imConnection_);
Edric Milareted0b2802015-10-01 15:10:02 -0400641 ui->stackedWidget->setCurrentWidget(ui->welcomePage);
642 }
643}
644
645void
646CallWidget::placeCall()
647{
Nicolas Jager97a21b42015-12-03 16:55:45 -0500648 if (ui->ringContactLineEdit->text().isEmpty())
Edric Milareted0b2802015-10-01 15:10:02 -0400649 return;
Nicolas Jager97a21b42015-12-03 16:55:45 -0500650 Call* c = CallModel::instance().dialingCall(PhoneDirectoryModel::instance().getNumber(ui->ringContactLineEdit->text()));
Edric Milareted0b2802015-10-01 15:10:02 -0400651 c->performAction(Call::Action::ACCEPT);
Nicolas Jager97a21b42015-12-03 16:55:45 -0500652 ui->ringContactLineEdit->clear();
Edric1bed3f92016-05-19 10:24:48 -0400653 ui->callingPhoto->setPixmap(
654 QPixmap::fromImage(
655 GlobalInstances::pixmapManipulator()
656 .callPhoto(c, QSize(130,130)).value<QImage>()));
Edric Milareted0b2802015-10-01 15:10:02 -0400657}
658
659void
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500660CallWidget::settingsButtonClicked()
Edric Milareted0b2802015-10-01 15:10:02 -0400661{
662 emit NavigationRequested(ScreenEnum::ConfScreen);
663}
664
665void
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500666CallWidget::contactButtonClicked(bool checked)
Edric Milareted0b2802015-10-01 15:10:02 -0400667{
Edric Milareted0b2802015-10-01 15:10:02 -0400668 ui->mainTabMenu->setCurrentIndex(checked ? 1 : 0);
669}
670
671void
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500672CallWidget::historicButtonClicked(bool checked)
Edric Milareted0b2802015-10-01 15:10:02 -0400673{
Edric Milareted0b2802015-10-01 15:10:02 -0400674 ui->mainTabMenu->setCurrentIndex(checked ? 2 : 0);
675}
Nicolas Jager97a21b42015-12-03 16:55:45 -0500676
677void
Anthony LĂ©onardaa90e1a2016-10-12 11:24:17 -0400678CallWidget::searchContactLineEditEntry(const URI &uri)
679{
680 auto cm = PhoneDirectoryModel::instance().getNumber(uri);
681 // if its a new CM, bring it to the top
682 if (cm->lastUsed() == 0)
683 cm->setLastUsed(QDateTime::currentDateTime().toTime_t());
684
685 // select cm
686 RecentModel::instance().selectionModel()->setCurrentIndex(RecentModel::instance().getIndex(cm),
687 QItemSelectionModel::ClearAndSelect);
688 ui->ringContactLineEdit->clear();
689}
690
691void
Nicolas Jager97a21b42015-12-03 16:55:45 -0500692CallWidget::on_ringContactLineEdit_returnPressed()
693{
Olivier SOLDANO63178ee2016-11-04 16:50:08 -0400694 bool lookup_username = false;
Anthony LĂ©onardaa90e1a2016-10-12 11:24:17 -0400695 auto contactLineText = ui->ringContactLineEdit->text();
696 URI uri_passed = URI(contactLineText);
Nicolas Jager5e845d52016-02-18 13:26:12 -0500697
Olivier SOLDANO63178ee2016-11-04 16:50:08 -0400698 if (!contactLineText.isNull() && !contactLineText.isEmpty()){
699 if (uri_passed.protocolHint() == URI::ProtocolHint::RING_USERNAME ) {
700 lookup_username = TRUE;
701 } else if (
702 uri_passed.protocolHint() != URI::ProtocolHint::RING && // not a RingID
703 uri_passed.schemeType() == URI::SchemeType::NONE // scheme type not specified
704 ){
705 // if no scheme type has been specified, determine ring vs sip by the first available account
706 auto idx = AvailableAccountModel::instance().index(0, 0);
707 if (idx.isValid()) {
708 auto account = idx.data((int)Ring::Role::Object).value<Account *>();
709 if (account && account->protocol() == Account::Protocol::RING)
710 lookup_username = TRUE;
711 }
712 }
Anthony LĂ©onardaa90e1a2016-10-12 11:24:17 -0400713
Olivier SOLDANO63178ee2016-11-04 16:50:08 -0400714 if (lookup_username){
715 NameDirectory::instance().lookupName(nullptr, QString(), uri_passed);
716 } else {
717 searchContactLineEditEntry(uri_passed);
718 }
Anthony LĂ©onardaa90e1a2016-10-12 11:24:17 -0400719 }
Nicolas Jager97a21b42015-12-03 16:55:45 -0500720}
721
722void
723CallWidget::on_btnCall_clicked()
724{
725 placeCall();
726}
727
728void
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500729CallWidget::btnComBarVideoClicked()
Nicolas Jager97a21b42015-12-03 16:55:45 -0500730{
731 if (not highLightedIndex_.isValid())
732 return;
733
734 on_smartList_doubleClicked(highLightedIndex_);
735}
Edric Milaretab12d022015-12-04 16:09:44 -0500736
737void
Edric Milaret6b68a482016-02-01 15:23:44 -0500738CallWidget::showIMOutOfCall(const QModelIndex& nodeIdx)
Edric Milaretab12d022015-12-04 16:09:44 -0500739{
Edric Milaretab12d022015-12-04 16:09:44 -0500740 ui->contactMethodComboBox->clear();
741
Edric Milareta0ebd062016-01-13 12:18:23 -0500742 ui->imNameLabel->setText(QString(tr("Conversation with %1", "%1 is the contact name"))
743 .arg(nodeIdx.data(static_cast<int>(Ring::Role::Name)).toString()));
Edric Milaretab12d022015-12-04 16:09:44 -0500744 auto cmVector = RecentModel::instance().getContactMethods(nodeIdx);
Edric Milareta0ebd062016-01-13 12:18:23 -0500745 ui->contactMethodComboBox->setEnabled(cmVector.size() > 1);
Edric Milaretab12d022015-12-04 16:09:44 -0500746 foreach (const ContactMethod* cm, cmVector) {
Edric Milareta0ebd062016-01-13 12:18:23 -0500747 ui->contactMethodComboBox->addItem(cm->uri());
Edric Milaretab12d022015-12-04 16:09:44 -0500748 }
Olivier SOLDANOad0fabb2016-11-25 09:08:01 -0500749 ui->stackedWidget->setCurrentWidget(ui->messagingPage);
Edric Milaret70ae8782016-04-18 16:10:44 -0400750 disconnect(imClickedConnection_);
751 imClickedConnection_ = connect(ui->listMessageView, &QListView::clicked, [this](const QModelIndex& index) {
752 auto urlList = index.data(static_cast<int>(Media::TextRecording::Role::LinkList)).value<QList<QUrl>>();
753 if (urlList.size() == 1)
754 QDesktopServices::openUrl(urlList.at(0));
755 else if (urlList.size()) {
756 //TODO Handle multiple url in one message
757 }
758 });
Edric Milaretab12d022015-12-04 16:09:44 -0500759}
760
761void
Edric Milaret6a785af2016-03-07 15:39:30 -0500762CallWidget::on_sendIMButton_clicked()
Edric Milaretab12d022015-12-04 16:09:44 -0500763{
Edric Milaret6a785af2016-03-07 15:39:30 -0500764 if (ui->imMessageEdit->text().trimmed().isEmpty())
Edric Milaretab12d022015-12-04 16:09:44 -0500765 return;
766 auto number = ui->contactMethodComboBox->currentText();
767 if (auto cm = PhoneDirectoryModel::instance().getNumber(number)) {
768 QMap<QString, QString> msg;
Edric Milaret6a785af2016-03-07 15:39:30 -0500769 msg["text/plain"] = ui->imMessageEdit->text();
Edric Milaretab12d022015-12-04 16:09:44 -0500770 cm->sendOfflineTextMessage(msg);
Edric Milaret6a785af2016-03-07 15:39:30 -0500771 ui->imMessageEdit->clear();
Edric Milaretab12d022015-12-04 16:09:44 -0500772 } else {
773 qWarning() << "Contact Method not found for " << number;
774 }
775}
776
777void
Edric Milaret6a785af2016-03-07 15:39:30 -0500778CallWidget::on_imMessageEdit_returnPressed()
Edric Milaretab12d022015-12-04 16:09:44 -0500779{
Edric Milaret6a785af2016-03-07 15:39:30 -0500780 on_sendIMButton_clicked();
Edric Milaretab12d022015-12-04 16:09:44 -0500781}
782
783void
784CallWidget::on_contactMethodComboBox_currentIndexChanged(const QString& number)
785{
786 auto cm = PhoneDirectoryModel::instance().getNumber(number);
787 if (auto txtRecording = cm->textRecording()) {
788 ui->listMessageView->setModel(txtRecording->instantMessagingModel());
Edric Milaret7ef617b2016-02-01 15:40:57 -0500789 if (imConnection_)
790 disconnect(imConnection_);
Edric Milaretab12d022015-12-04 16:09:44 -0500791 imConnection_ = connect(txtRecording,
Edric Milareta0ebd062016-01-13 12:18:23 -0500792 SIGNAL(messageInserted(QMap<QString,QString>,ContactMethod*,Media::Media::Direction)),
793 this,
794 SLOT(slotAccountMessageReceived(QMap<QString,QString>,ContactMethod*,Media::Media::Direction)));
Edric Milaret4be72022016-01-19 10:24:13 -0500795 auto messagesPresent = txtRecording->instantMessagingModel()->rowCount() > 0;
796 if (messagesPresent) {
797 ui->listMessageView->scrollToBottom();
798 txtRecording->setAllRead();
799 }
800 ui->listMessageView->setVisible(messagesPresent);
801 ui->noMessagesLabel->setVisible(!messagesPresent);
802 if (not messagesPresent) {
Edric Milaret49130472016-01-22 10:39:37 -0500803 imVisibleConnection_ = connect(txtRecording->instantMessagingModel(),
804 &QAbstractItemModel::rowsInserted,
805 [this, txtRecording]() {
806 if (imVisibleConnection_)
807 disconnect(imVisibleConnection_);
808 auto messagesPresent = txtRecording->instantMessagingModel()->rowCount() > 0;
Edric Milaret4be72022016-01-19 10:24:13 -0500809 ui->listMessageView->setVisible(messagesPresent);
810 ui->noMessagesLabel->setVisible(!messagesPresent);
Edric Milaret4be72022016-01-19 10:24:13 -0500811 });
812 }
Edric Milaretab12d022015-12-04 16:09:44 -0500813 }
814}
815
816void
817CallWidget::slotAccountMessageReceived(const QMap<QString,QString> message,
818 ContactMethod* cm,
819 Media::Media::Direction dir)
820{
821 Q_UNUSED(message)
Edric Milaretab12d022015-12-04 16:09:44 -0500822 Q_UNUSED(dir)
823
824 ui->listMessageView->scrollToBottom();
Edric Milaret23fd3fa2016-01-15 15:37:35 -0500825 cm->textRecording()->setAllRead();
Edric Milaretab12d022015-12-04 16:09:44 -0500826}
Edric Milaretfa05d972016-01-13 16:22:04 -0500827
828void
Edric Milaret8001f6f2016-01-27 09:55:12 -0500829CallWidget::on_ringContactLineEdit_textChanged(const QString& text)
Edric Milaretfa05d972016-01-13 16:22:04 -0500830{
831 RecentModel::instance().peopleProxy()->setFilterWildcard(text);
832}
Edric Milareta0ebd062016-01-13 12:18:23 -0500833
Nicolas Jagerca850292016-01-17 14:11:10 -0500834void
835CallWidget::on_imBackButton_clicked()
Edric Milareta0ebd062016-01-13 12:18:23 -0500836{
Edric Milaret6b68a482016-02-01 15:23:44 -0500837 RecentModel::instance().selectionModel()->clear();
838 slidePage(ui->welcomePage);
Nicolas Jagerca850292016-01-17 14:11:10 -0500839}
840
841void
Edric Milaret6b68a482016-02-01 15:23:44 -0500842CallWidget::slidePage(QWidget* widget, bool toRight)
Nicolas Jagerca850292016-01-17 14:11:10 -0500843{
Edric Milaret6b68a482016-02-01 15:23:44 -0500844 short dir = (toRight ? -1 : 1);
Nicolas Jagerca850292016-01-17 14:11:10 -0500845 ui->stackedWidget->setCurrentWidget(widget);
Edric Milaret6b68a482016-02-01 15:23:44 -0500846 pageAnim_->setTargetObject(widget);
847 pageAnim_->setDuration(animDuration_);
848 pageAnim_->setStartValue(QPoint(widget->width() * dir, widget->y()));
849 pageAnim_->setEndValue(QPoint(widget->x(), widget->y()));
850 pageAnim_->setEasingCurve(QEasingCurve::OutQuad);
851 pageAnim_->start();
Nicolas Jagerca850292016-01-17 14:11:10 -0500852}
853
854void
Edric Milaret6b68a482016-02-01 15:23:44 -0500855CallWidget::on_smartList_clicked(const QModelIndex& index)
Nicolas Jagerca850292016-01-17 14:11:10 -0500856{
Edric Milaret6b68a482016-02-01 15:23:44 -0500857 RecentModel::instance().selectionModel()->setCurrentIndex(
858 RecentModel::instance().peopleProxy()->mapToSource(index),
859 QItemSelectionModel::ClearAndSelect);
Edric Milareta0ebd062016-01-13 12:18:23 -0500860}
Edric Milaret7cf39e22016-02-02 12:44:03 -0500861
862void
863CallWidget::on_copyCMButton_clicked()
864{
865 auto text = ui->contactMethodComboBox->currentText();
866 QApplication::clipboard()->setText(text);
867}
Edric Milaret4097d2f2016-02-09 14:41:50 -0500868
869void
Edric Milaret1e598592016-09-02 10:10:01 -0400870CallWidget::on_qrButton_toggled(bool checked)
871{
872 ui->qrLabel->setVisible(checked);
873}
874
875void
Edric Milaret4097d2f2016-02-09 14:41:50 -0500876CallWidget::on_shareButton_clicked()
877{
Edric Milaret1e598592016-09-02 10:10:01 -0400878 Utils::InvokeMailto(tr("Contact me on Ring"), tr("My RingId is : ") + ui->ringIdLabel->text());
Edric Milaret4097d2f2016-02-09 14:41:50 -0500879}
Anthony LĂ©onardaa90e1a2016-10-12 11:24:17 -0400880
881void
882CallWidget::contactLineEdit_registeredNameFound(const Account* account,NameDirectory::LookupStatus status,
883 const QString& address,const QString& name)
884{
885 URI uri = URI(ui->ringContactLineEdit->text());
886 QString username_to_lookup = uri.userinfo();
887
888 if (username_to_lookup.compare(name) != 0){
889 return;
890 }
891
892 switch (status)
893 {
894 case NameDirectory::LookupStatus::SUCCESS:
895 {
896 uri = URI("ring:" + address);
897 qDebug() << uri;
898 searchContactLineEditEntry(uri);
899 break;
900 }
901 case NameDirectory::LookupStatus::INVALID_NAME:
902 {
903 qDebug() << "Invalid Ring username";
904 break;
905 }
906 case NameDirectory::LookupStatus::ERROR:
907 case NameDirectory::LookupStatus::NOT_FOUND:
908 default:
909 {
910 qDebug() << "Could not resolve Ring username";
911 break;
912 }
913 }
914}