blob: 2fc7ae907d6570f711b98e380930cb6171aab80a [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 "configurationwidget.h"
20#include "ui_configurationwidget.h"
21
Edric Milaret1eece872015-06-10 13:37:51 -040022#include <QMessageBox>
Edric Milaretfd5a1f22016-02-05 15:30:00 -050023#include <QDir>
24#include <QStandardPaths>
25#include <QFileDialog>
Nicolas Jager74fe46f2016-02-29 14:55:09 -050026#include <QPropertyAnimation>
Edric Milaretce0ea472016-04-12 10:16:56 -040027#include <QtConcurrent/QtConcurrent>
Edric Milaret1eece872015-06-10 13:37:51 -040028
Edric Milaret627500d2015-03-27 16:41:40 -040029#include "video/devicemodel.h"
30#include "video/channel.h"
31#include "video/resolution.h"
32#include "video/rate.h"
Edric Milaret4bba46d2015-04-29 16:33:38 -040033#include "video/previewmanager.h"
Edric Milaret627500d2015-03-27 16:41:40 -040034
Edric Milaret47c40eb2016-03-14 15:06:22 -040035#include "audio/settings.h"
36#include "audio/outputdevicemodel.h"
37#include "audio/inputdevicemodel.h"
38
Edric Milaretfd5a1f22016-02-05 15:30:00 -050039#include "media/recordingmodel.h"
40
Edric Milaret3e6aefe2015-06-05 16:07:26 -040041#include "accountserializationadapter.h"
Edric Milaretb25af972015-06-17 16:55:45 -040042#include "accountstatedelegate.h"
43#include "settingskey.h"
Edric Milaret79d3f682015-12-09 12:32:52 -050044#include "utils.h"
Edric Milaretce0ea472016-04-12 10:16:56 -040045#include "pathpassworddialog.h"
Edric Milaret25236d92016-03-28 09:40:58 -040046#include "photoboothdialog.h"
Edric Milaret3e6aefe2015-06-05 16:07:26 -040047
Edric Milaret627500d2015-03-27 16:41:40 -040048#include "accountmodel.h"
49#include "protocolmodel.h"
50#include "accountdetails.h"
Edric Milaret3aeae3a2015-06-01 17:31:54 -040051#include "callmodel.h"
Edric Milaret1eece872015-06-10 13:37:51 -040052#include "ringtonemodel.h"
53#include "categorizedhistorymodel.h"
Edric Milaret25236d92016-03-28 09:40:58 -040054#include "profilemodel.h"
55#include "profile.h"
56#include "person.h"
Edric Milaret627500d2015-03-27 16:41:40 -040057
Edric Milaret79d3f682015-12-09 12:32:52 -050058#ifdef ENABLE_AUTOUPDATE
59#include "winsparkle.h"
60#endif
Edric Milaret627500d2015-03-27 16:41:40 -040061
62ConfigurationWidget::ConfigurationWidget(QWidget *parent) :
Nicolas Jager74fe46f2016-02-29 14:55:09 -050063 NavWidget(parent),
Edric Milaret627500d2015-03-27 16:41:40 -040064 ui(new Ui::ConfigurationWidget),
Edric Milareta3e47282015-10-23 15:20:30 -040065 accountModel_(&AccountModel::instance()),
66 deviceModel_(&Video::DeviceModel::instance()),
Edric Milaret627500d2015-03-27 16:41:40 -040067 accountDetails_(new AccountDetails())
68{
69 ui->setupUi(this);
70
Nicolas Jager74fe46f2016-02-29 14:55:09 -050071 connect(ui->exitSettingsButton, &QPushButton::clicked, this, [=]() {
72 if (CallModel::instance().getActiveCalls().size() == 0
73 && Video::PreviewManager::instance().isPreviewing()) {
74 Video::PreviewManager::instance().stopPreview();
75 }
76 accountModel_->save();
77 accountDetails_->save();
78 });
79
80 connect(accountDetails_->getDeleteAccountButton(), &QPushButton::clicked, this, [=]() {
81 auto account = accountModel_->getAccountByModelIndex(
82 ui->accountView->currentIndex());
Edric Milaretce0ea472016-04-12 10:16:56 -040083 accountModel_->remove(account);
84 accountModel_->save();
Nicolas Jager74fe46f2016-02-29 14:55:09 -050085 });
86
87 connect(ui->exitSettingsButton, &QPushButton::clicked, this, [=]() {
88 emit NavigationRequested(ScreenEnum::CallScreen);
89 });
90
Edric Milaret627500d2015-03-27 16:41:40 -040091 ui->accountView->setModel(accountModel_);
Edric Milaret01f23842015-06-22 14:46:01 -040092 accountStateDelegate_ = new AccountStateDelegate();
93 ui->accountView->setItemDelegate(accountStateDelegate_);
Edric Milaret627500d2015-03-27 16:41:40 -040094
Edric Milaret627500d2015-03-27 16:41:40 -040095 isLoading_ = true;
96 ui->deviceBox->setModel(deviceModel_);
Edric Milaret94b4aab2015-05-08 12:10:44 -040097 connect(deviceModel_, SIGNAL(currentIndexChanged(int)),
98 this, SLOT(deviceIndexChanged(int)));
Edric Milaret627500d2015-03-27 16:41:40 -040099
Edric Milaretce0ea472016-04-12 10:16:56 -0400100 ui->accountView->setSelectionModel(AccountModel::instance().selectionModel());
Edric Milaret627500d2015-03-27 16:41:40 -0400101 connect(ui->accountView->selectionModel(),
Edric Milaret3aeae3a2015-06-01 17:31:54 -0400102 SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
103 this, SLOT(accountSelected(QItemSelection)));
Edric Milaret627500d2015-03-27 16:41:40 -0400104
105 ui->accountView->setCurrentIndex(accountModel_->index(0));
106 ui->accountDetailLayout->addWidget(accountDetails_);
Edric Milaret627500d2015-03-27 16:41:40 -0400107 ui->accountTypeBox->setModel(accountModel_->protocolModel());
Edric Milaret4bba46d2015-04-29 16:33:38 -0400108 ui->startupBox->setChecked(Utils::CheckStartupLink());
Edric Milaret1eece872015-06-10 13:37:51 -0400109
Edric Milaretb25af972015-06-17 16:55:45 -0400110 ui->historyDaySettingsSpinBox->setValue(
Edric Milareta3e47282015-10-23 15:20:30 -0400111 CategorizedHistoryModel::instance().historyLimit());
Edric Milaretb25af972015-06-17 16:55:45 -0400112 ui->closeOrMinCheckBox->setChecked(settings_.value(
113 SettingsKey::closeOrMinimized).toBool());
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500114 connect(ui->stackedWidget, &QStackedWidget::currentChanged, [](int index) {
Edric Milaretfb5fc5c2015-09-24 14:32:49 -0400115 if (index == 1
Edric Milareta3e47282015-10-23 15:20:30 -0400116 && CallModel::instance().getActiveCalls().size() == 0) {
117 Video::PreviewManager::instance().startPreview();
Edric Milaretfb5fc5c2015-09-24 14:32:49 -0400118 } else {
Edric Milareta3e47282015-10-23 15:20:30 -0400119 if (CallModel::instance().getActiveCalls().size() == 0
120 && Video::PreviewManager::instance().isPreviewing()) {
121 Video::PreviewManager::instance().stopPreview();
Edric Milaretfb5fc5c2015-09-24 14:32:49 -0400122 }
123 }
124 });
Edric Milaret0b7fe5d2016-01-27 11:12:43 -0500125
126 ui->videoView->setIsFullPreview(true);
Edric Milaretfd5a1f22016-02-05 15:30:00 -0500127
128 auto recordPath = Media::RecordingModel::instance().recordPath();
129 if (recordPath.isEmpty()) {
130 recordPath = QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
131 Media::RecordingModel::instance().setRecordPath(recordPath);
132 }
133 ui->recordPath->setText(Media::RecordingModel::instance().recordPath());
134
135 ui->alwaysRecordCheckBox->setChecked(Media::RecordingModel::instance().isAlwaysRecording());
136 connect(ui->alwaysRecordCheckBox, &QCheckBox::clicked, [](bool checked){
137 Media::RecordingModel::instance().setAlwaysRecording(checked);
138 });
139
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500140 connect(ui->generalTabButton, &QPushButton::toggled, [=] (bool toggled) {
141 if (toggled) {
142 ui->stackedWidget->setCurrentWidget(ui->generalPage);
143 ui->videoTabButton->setChecked(false);
144 ui->accountTabButton->setChecked(false);
145 }
146 });
147
148 connect(ui->videoTabButton, &QPushButton::toggled, [=] (bool toggled) {
149 if (toggled) {
150 ui->stackedWidget->setCurrentWidget(ui->videoPage);
151 ui->accountTabButton->setChecked(false);
152 ui->generalTabButton->setChecked(false);
153 }
154 });
155
156 connect(ui->accountTabButton, &QPushButton::toggled, [=] (bool toggled) {
157 if (toggled) {
158 ui->stackedWidget->setCurrentWidget(ui->accountPage);
159 ui->videoTabButton->setChecked(false);
160 ui->generalTabButton->setChecked(false);
161 }
162 });
163
164 ui->generalTabButton->setChecked(true);
165
Edric Milaret47c40eb2016-03-14 15:06:22 -0400166 auto inputModel = Audio::Settings::instance().inputDeviceModel();
167 auto outputModel = Audio::Settings::instance().outputDeviceModel();
168
169 ui->outputComboBox->setModel(outputModel);
170 ui->inputComboBox->setModel(inputModel);
171 ui->outputComboBox->setCurrentIndex(outputModel->selectionModel()->currentIndex().row());
172 ui->inputComboBox->setCurrentIndex(inputModel->selectionModel()->currentIndex().row());
173 connect(ui->outputComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(outputIndexChanged(int)));
174 connect(ui->inputComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(inputIndexChanged(int)));
175
176
Edric Milaret79d3f682015-12-09 12:32:52 -0500177#ifndef ENABLE_AUTOUPDATE
178 ui->checkUpdateButton->hide();
179 ui->intervalUpdateCheckSpinBox->hide();
180 ui->updateDayLabel->hide();
181 ui->autoUpdateCheckBox->hide();
182#endif
Edric Milaret25236d92016-03-28 09:40:58 -0400183
184 auto profile = ProfileModel::instance().selectedProfile();
185 ui->avatarButton->setIcon(QPixmap::fromImage(Utils::getCirclePhoto(profile->person()->photo().value<QImage>(), ui->avatarButton->width())));
186 ui->profileNameEdit->setText(profile->person()->formattedName());
Edric Milaret627500d2015-03-27 16:41:40 -0400187}
188
Edric Milaretef9b85b2016-02-05 11:47:10 -0500189void ConfigurationWidget::showPreview()
190{
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500191 if (ui->stackedWidget->currentIndex() == 1
Edric Milaretef9b85b2016-02-05 11:47:10 -0500192 && CallModel::instance().getActiveCalls().size() == 0) {
193 ui->previewUnavailable->hide();
194 ui->videoView->show();
195 Video::PreviewManager::instance().startPreview();
196 } else {
197 ui->previewUnavailable->show();
198 ui->videoView->hide();
199 }
200}
201
Edric Milaretfb5fc5c2015-09-24 14:32:49 -0400202void
203ConfigurationWidget::showEvent(QShowEvent *event) {
Edric Milaret79d3f682015-12-09 12:32:52 -0500204
205#ifdef ENABLE_AUTOUPDATE
206 if (win_sparkle_get_automatic_check_for_updates()) {
207 ui->autoUpdateCheckBox->setChecked(true);
208 }
209 ui->intervalUpdateCheckSpinBox->setValue(win_sparkle_get_update_check_interval() / 86400);
210#endif
Edric Milaretfb5fc5c2015-09-24 14:32:49 -0400211 QWidget::showEvent(event);
Edric Milaretef9b85b2016-02-05 11:47:10 -0500212 showPreview();
Edric Milaretfb5fc5c2015-09-24 14:32:49 -0400213}
214
Edric Milaret627500d2015-03-27 16:41:40 -0400215ConfigurationWidget::~ConfigurationWidget()
216{
217 delete ui;
Edric Milaret01f23842015-06-22 14:46:01 -0400218 delete accountStateDelegate_;
Edric Milaret627500d2015-03-27 16:41:40 -0400219}
220
221void
Edric Milaret94b4aab2015-05-08 12:10:44 -0400222ConfigurationWidget::deviceIndexChanged(int index) {
223 ui->deviceBox->setCurrentIndex(index);
224}
225
226void
Edric Milaret627500d2015-03-27 16:41:40 -0400227ConfigurationWidget::on_deviceBox_currentIndexChanged(int index)
228{
229 if (index < 0)
230 return;
231
232 if (!isLoading_)
233 deviceModel_->setActive(index);
234
235 auto device = deviceModel_->activeDevice();
236
237 ui->sizeBox->clear();
238
239 isLoading_ = true;
240 if (device->channelList().size() > 0) {
241 for (auto resolution : device->channelList()[0]->validResolutions()) {
242 ui->sizeBox->addItem(resolution->name());
243 }
244 }
245 ui->sizeBox->setCurrentIndex(
246 device->channelList()[0]->activeResolution()->relativeIndex());
247 isLoading_ = false;
248}
249
250void
251ConfigurationWidget::on_sizeBox_currentIndexChanged(int index)
252{
253 auto device = deviceModel_->activeDevice();
254
Edric Milaret627500d2015-03-27 16:41:40 -0400255 if (index < 0)
256 return;
257 if (!isLoading_)
258 device->channelList()[0]->setActiveResolution(
259 device->channelList()[0]->validResolutions()[index]);
Edric Milaret627500d2015-03-27 16:41:40 -0400260}
261
262void
263ConfigurationWidget::accountSelected(QItemSelection itemSel) {
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400264
Edric Milaret627500d2015-03-27 16:41:40 -0400265 Q_UNUSED(itemSel)
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400266 auto account = accountModel_->getAccountByModelIndex(
267 ui->accountView->currentIndex());
268 accountDetails_->setAccount(account);
Edric Milaretce0ea472016-04-12 10:16:56 -0400269 if (account)
270 AccountSerializationAdapter adapter(account, accountDetails_);
Edric Milaret627500d2015-03-27 16:41:40 -0400271}
272
273void
Edric Milaret627500d2015-03-27 16:41:40 -0400274ConfigurationWidget::on_addAccountButton_clicked()
275{
Edric Milaret53ac6e52015-09-14 13:37:06 -0400276 auto account = accountModel_->add(tr("New Account"),
Edric Milaret3aeae3a2015-06-01 17:31:54 -0400277 ui->accountTypeBox->model()->index(
278 ui->accountTypeBox->currentIndex(), 0));
Edric Milaret031c3052015-04-29 18:14:18 -0400279 account->setRingtonePath(Utils::GetRingtonePath());
Edric Milaret627500d2015-03-27 16:41:40 -0400280 accountModel_->save();
281}
Edric Milaret4bba46d2015-04-29 16:33:38 -0400282
Edric Milaret3aeae3a2015-06-01 17:31:54 -0400283void
284ConfigurationWidget::on_startupBox_toggled(bool checked)
Edric Milaret4bba46d2015-04-29 16:33:38 -0400285{
286 if (checked)
287 Utils::CreateStartupLink();
288 else
289 Utils::DeleteStartupLink();
290}
Edric Milaret3aeae3a2015-06-01 17:31:54 -0400291
292void
Edric Milaret1eece872015-06-10 13:37:51 -0400293ConfigurationWidget::on_clearHistoryButton_clicked()
294{
295 QMessageBox confirmationDialog;
296
Edric Milaret53ac6e52015-09-14 13:37:06 -0400297 confirmationDialog.setText(tr("Are you sure you want to clear all your history?"));
Edric Milaret1eece872015-06-10 13:37:51 -0400298 confirmationDialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
299 auto ret = confirmationDialog.exec();
300
301 if (ret == QMessageBox::Ok)
Edric Milareta3e47282015-10-23 15:20:30 -0400302 CategorizedHistoryModel::instance().clearAllCollections();
Edric Milaret1eece872015-06-10 13:37:51 -0400303}
304
305void
306ConfigurationWidget::on_historyDaySettingsSpinBox_valueChanged(int limit)
307{
Edric Milareta3e47282015-10-23 15:20:30 -0400308 if (CategorizedHistoryModel::instance().historyLimit() != limit)
309 CategorizedHistoryModel::instance().setHistoryLimit(limit);
Edric Milaret1eece872015-06-10 13:37:51 -0400310}
Edric Milaretb25af972015-06-17 16:55:45 -0400311
312void
313ConfigurationWidget::on_closeOrMinCheckBox_toggled(bool checked)
314{
315 settings_.setValue(SettingsKey::closeOrMinimized, checked);
316}
Edric Milaret79d3f682015-12-09 12:32:52 -0500317
318void
319ConfigurationWidget::on_checkUpdateButton_clicked()
320{
321#ifdef ENABLE_AUTOUPDATE
322 win_sparkle_check_update_with_ui();
323#endif
324}
325
326void
327ConfigurationWidget::on_autoUpdateCheckBox_toggled(bool checked)
328{
329#ifdef ENABLE_AUTOUPDATE
330 win_sparkle_set_automatic_check_for_updates(checked);
331#endif
332}
333
334void
335ConfigurationWidget::on_intervalUpdateCheckSpinBox_valueChanged(int arg1)
336{
337#ifdef ENABLE_AUTOUPDATE
338 win_sparkle_set_update_check_interval(arg1 * 86400);
339#endif
340}
Edric Milaretef9b85b2016-02-05 11:47:10 -0500341
342void
Nicolas Jager74fe46f2016-02-29 14:55:09 -0500343ConfigurationWidget::on_stackedWidget_currentChanged(int index)
Edric Milaretef9b85b2016-02-05 11:47:10 -0500344{
345 Q_UNUSED(index)
346 showPreview();
347}
Edric Milaretfd5a1f22016-02-05 15:30:00 -0500348
349void
350ConfigurationWidget::on_recordPath_clicked()
351{
352 QString dir = QFileDialog::getExistingDirectory(this, tr("Choose Directory"),
353 Media::RecordingModel::instance().recordPath(),
354 QFileDialog::ShowDirsOnly
355 | QFileDialog::DontResolveSymlinks);
356 if (not dir.isEmpty()) {
357 Media::RecordingModel::instance().setRecordPath(dir);
358 ui->recordPath->setText(dir);
359 }
360}
Edric Milaret47c40eb2016-03-14 15:06:22 -0400361
362void
363ConfigurationWidget::outputIndexChanged(int index)
364{
365 auto outputModel = Audio::Settings::instance().outputDeviceModel();
366 outputModel->selectionModel()->setCurrentIndex(outputModel->index(index), QItemSelectionModel::ClearAndSelect);
367}
368
369void
370ConfigurationWidget::inputIndexChanged(int index)
371{
372 auto inputModel = Audio::Settings::instance().inputDeviceModel();
373 inputModel->selectionModel()->setCurrentIndex(inputModel->index(index), QItemSelectionModel::ClearAndSelect);
374}
Edric Milaretce0ea472016-04-12 10:16:56 -0400375
376void
377ConfigurationWidget::on_importButton_clicked()
378{
379 PathPasswordDialog dlg;
380 if (dlg.exec() == QDialog::Accepted)
381 if (AccountModel::instance().importAccounts(dlg.path_, dlg.password_) > 0)
382 errorDlg_.showMessage(tr("An error occured while importing account."));
383}
384
385void
386ConfigurationWidget::on_exportButton_clicked()
387{
388 PathPasswordDialog dlg;
389 dlg.exportMode = true;
390 if (dlg.exec() == QDialog::Accepted) {
391 auto func = [](QString path, QString password)
392 {
393 AccountModel::instance().exportAccounts(
394 {AccountModel::instance().selectedAccount()->id()},
395 path,
396 password);
397 };
398 QtConcurrent::run(func, dlg.path_, dlg.password_);
399 }
400}
Edric Milaret25236d92016-03-28 09:40:58 -0400401
402void
403ConfigurationWidget::on_avatarButton_clicked()
404{
405 PhotoBoothDialog dlg;
406 dlg.exec();
407 if (dlg.result() == QDialog::Accepted) {
408 auto image = QImage(dlg.fileName_);
409 auto avatar = image.scaled(100, 100, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
410 ProfileModel::instance().selectedProfile()->person()->setPhoto(avatar);
411 ProfileModel::instance().selectedProfile()->save();
412 ui->avatarButton->setIcon(QPixmap::fromImage(Utils::getCirclePhoto(avatar, ui->avatarButton->width())));
413 }
414}
415
416void
417ConfigurationWidget::on_profileNameEdit_textEdited(const QString& name)
418{
419 ProfileModel::instance().selectedProfile()->person()->setFormattedName(name);
420 ProfileModel::instance().selectedProfile()->save();
421}