Select Git revision
settingswidget.cpp
Ming Rui Zhang authored
- create a pastAccount, if pastAccount matches the current account, setSelected will return as usual, and if not, it will reselect the correct account setting widget Change-Id: I870eb6d52d7e5f352489ddbd9347c3a5437e918d
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
settingswidget.cpp 38.79 KiB
/***************************************************************************
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Isa Nanic <isa.nanic@savoirfairelinux.com> *
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
* Author: Anthony L�onard <anthony.leonard@savoirfairelinux.com> *
* Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com> *
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> *
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
**************************************************************************/
#include "settingswidget.h"
#include "ui_settingswidget.h"
#include "deleteaccountdialog.h"
#include "nameregistrationdialog.h"
#include "passworddialog.h"
#include "settingskey.h"
#include "utils.h"
#include "deviceitemwidget.h"
#include "banneditemwidget.h"
#include "version.h"
#include "namedirectory.h"
#include "api/newdevicemodel.h"
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QModelIndex>
#include <QPixmap>
#include <QScrollBar>
#include <QSettings>
#include <QStandardPaths>
#include <QTimer>
#include <QtConcurrent/QtConcurrent>
SettingsWidget::SettingsWidget(QWidget* parent)
: NavWidget(parent)
, ui(new Ui::SettingsWidget)
, scrollArea_(new QScrollArea(this))
, scrollSIPArea_(new QScrollArea(this))
{
ui->setupUi(this);
ui->accountSettingsButton->setPixmap(QPixmap(":/images/icons/baseline-people-24px.svg"));
ui->generalSettingsButton->setPixmap(QPixmap(":/images/icons/round-settings-24px.svg"));
ui->mediaSettingsButton->setPixmap(QPixmap(":/images/icons/baseline-desktop_windows-24px.svg"));
ui->accountSettingsButton->setChecked(true);
ui->btnExitSettings->setIconSize(QSize(24, 24));
ui->btnExitSettings->setIcon(QIcon(":/images/icons/round-close-24px.svg"));
// avatar
avatarSize_ = 224;
///////////////////////////////////////////////////////////////////////////
// SIP
///////////////////////////////////////////////////////////////////////////
// Show Password
ui->passSIPlineEdit->setEchoMode(QLineEdit::Password);
// display name SIP
ui->displaySIPNameLineEdit->setAlignment(Qt::AlignHCenter);
ui->displaySIPNameLineEdit->setPlaceholderText(tr("Enter an alias"));
// SIP User Name
ui->usernameSIP->setStyleSheet("border : 0px;");
// SIP Advanced Setting initilization
ui->advancedAccountSettingsSIPButton->setIcon(QIcon(":/images/icons/round-arrow_drop_down-24px.svg"));
ui->scrollSIPArea->verticalScrollBar()->setEnabled(true);
ui->scrollSIPArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 10px; }");
ui->advancedSIPSettingsWidget->setVisible(false);
///////////////////////////////////////////////////////////////////////////
// Jami
///////////////////////////////////////////////////////////////////////////
// display name (aka alias)
ui->displayNameLineEdit->setAlignment(Qt::AlignHCenter);
ui->displayNameLineEdit->setPlaceholderText(tr("Enter an alias"));
ui->currentRegisteredID->setReadOnly(true);
ui->currentRegisteredID->setStyleSheet("border : 0px;");
ui->currentRingID->setReadOnly(true);
ui->advancedAccountSettingsPButton->setIcon(QIcon(":/images/icons/round-arrow_drop_down-24px.svg"));
ui->advancedAccountSettingsPButton->setIconSize(QSize(32, 32));
ui->linkDevPushButton->setIcon(QIcon(":/images/icons/round-add-24px.svg"));
ui->bannedContactsBtn->setIcon(QIcon(":/images/icons/round-arrow_drop_down-24px.svg"));
ui->scrollArea->verticalScrollBar()->setEnabled(true);
ui->scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 10px; }");
ui->advancedSettingsWidget->setVisible(false);
statusSuccessPixmap_ = Utils::generateTintedPixmap(":/images/icons/baseline-done-24px.svg", RingTheme::presenceGreen_);
statusInvalidPixmap_ = Utils::generateTintedPixmap(":/images/icons/baseline-error_outline-24px.svg", RingTheme::urgentOrange_);
statusErrorPixmap_ = Utils::generateTintedPixmap(":/images/icons/baseline-close-24px.svg", RingTheme::red_);
lookupSpinnerMovie_ = new QMovie(":/images/jami_rolling_spinner.gif");
lookupSpinnerMovie_->setScaledSize(QSize(30, 30));
ui->lookupStatusLabel->setMovie(lookupSpinnerMovie_);
ui->lookupStatusLabel->hide();
ui->containerWidget->setVisible(false);
}
void SettingsWidget::slotAccountOnBoarded()
{
setSelected(Button::accountSettingsButton);
setConnections();
}
void SettingsWidget::navigated(bool to)
{
ui->containerWidget->setVisible(to);
if (to) {
setSelected(Button::accountSettingsButton);
updateAccountInfoDisplayed();
// hide banned list
ui->bannedContactsListWidget->setVisible(false);
}
}
void SettingsWidget::updateCustomUI()
{
}
void SettingsWidget::leaveSettingsSlot()
{
if (advancedSettingsDropped_) {
toggleAdvancedSettings();
}
if (advancedSIPSettingsDropped_) {
toggleAdvancedSIPSettings();
}
QtConcurrent::run([this] { ui->currentAccountAvatar->stopBooth(); });
emit NavigationRequested(ScreenEnum::CallScreen);
}
SettingsWidget::~SettingsWidget()
{
delete ui;
}
void SettingsWidget::setSelected(Button sel)
{
switch (sel) {
case Button::accountSettingsButton:
ui->accountSettingsButton->setChecked(true);
ui->generalSettingsButton->setChecked(false);
ui->mediaSettingsButton->setChecked(false);
if (pastButton_ == sel && pastAccount_ == LRCInstance::getCurrentAccountInfo().profileInfo.type) {
return;
}
if (!LRCInstance::getActiveCalls().size()) {
QtConcurrent::run( [this] { LRCInstance::avModel().stopPreview(); });
}
if (LRCInstance::getCurrentAccountInfo().profileInfo.type == lrc::api::profile::Type::SIP) {
ui->stackedWidget->setCurrentWidget(ui->currentSIPAccountSettingsScrollWidget);
if (advancedSIPSettingsDropped_) {
toggleAdvancedSIPSettings();
}
pastAccount_ = lrc::api::profile::Type::SIP;
} else {
ui->stackedWidget->setCurrentWidget(ui->currentAccountSettingsScrollWidget);
if (advancedSettingsDropped_) {
toggleAdvancedSettings();
}
pastAccount_ = lrc::api::profile::Type::RING;
}
break;
case Button::generalSettingsButton:
ui->generalSettingsButton->setChecked(true);
ui->accountSettingsButton->setChecked(false);
ui->mediaSettingsButton->setChecked(false);
if (pastButton_ == sel) { return; }
if (!LRCInstance::getActiveCalls().size()) {
QtConcurrent::run([this] { LRCInstance::avModel().stopPreview(); });
}
ui->stackedWidget->setCurrentWidget(ui->generalSettings);
populateGeneralSettings();
break;
case Button::mediaSettingsButton:
ui->mediaSettingsButton->setChecked(true);
ui->generalSettingsButton->setChecked(false);
ui->accountSettingsButton->setChecked(false);
if (pastButton_ == sel) { return; }
ui->stackedWidget->setCurrentWidget(ui->avSettings);
currentDisplayedVideoDevice_.clear();
populateAVSettings();
break;
}
pastButton_ = sel;
}
// called to update current settings information when navigating to settingsWidget
void SettingsWidget::updateAccountInfoDisplayed()
{
auto& accInfo = LRCInstance::getCurrentAccountInfo();
auto accConfig = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
ui->usernameSIP->setText(QString::fromStdString(accConfig.username));
ui->hostnameSIP->setText(QString::fromStdString(accConfig.hostname));
ui->passSIPlineEdit->setText(QString::fromStdString(accConfig.password));
ui->ProxySIP->setText(QString::fromStdString(accConfig.proxyServer));
ui->currentRegisteredID->setText(QString::fromStdString(accInfo.registeredName));
ui->currentRingID->setText(QString::fromStdString(accInfo.profileInfo.uri));
// if no registered name is found for account
if (accInfo.registeredName.empty()) {
ui->btnRegisterName->show();
ui->btnRegisterName->setVisible(false);
ui->currentRegisteredID->setStyleSheet("font-weight: normal; background-color: rgb(240, 240, 240);border: 2px;");
ui->currentRegisteredID->setClearButtonEnabled(false);
ui->currentRegisteredID->setReadOnly(false);
setRegNameUi(RegName::BLANK);
} else {
ui->btnRegisterName->hide();
ui->currentRegisteredID->setStyleSheet("font-weight: bold; background-color: transparent;border: 0px;");
ui->currentRegisteredID->setClearButtonEnabled(false);
ui->currentRegisteredID->setReadOnly(true);
}
// sip avatar set
setAvatar(ui->currentSIPAccountAvatar);
// jami avatar set
setAvatar(ui->currentAccountAvatar);
ui->accountEnableCheckBox->setChecked(accInfo.enabled);
ui->accountSIPEnableCheckBox->setChecked(accInfo.enabled);
ui->displayNameLineEdit->setText(QString::fromStdString(accInfo.profileInfo.alias));
ui->displaySIPNameLineEdit->setText(QString::fromStdString(accInfo.profileInfo.alias));
updateAndShowDevicesSlot();
ui->bannedContactsListWidget->setVisible(false);
ui->bannedContactsBtn->setIcon(QIcon(":/images/icons/round-arrow_drop_down-24px.svg"));
ui->bannedContactsLayoutWidget->setVisible(accInfo.contactModel->getBannedContacts().size());
}
void SettingsWidget::setAvatar(PhotoboothWidget* avatarWidget)
{
auto& accountInfo = LRCInstance::getCurrentAccountInfo();
auto defaultAvatar = accountInfo.profileInfo.avatar.empty();
auto avatar = Utils::accountPhoto(accountInfo, {avatarSize_, avatarSize_});
avatarWidget->setAvatarPixmap(QPixmap::fromImage(avatar), defaultAvatar);
}
void SettingsWidget::passwordClicked()
{
PasswordDialog passwdDialog(this);
passwdDialog.exec();
}
void SettingsWidget::toggleAdvancedSIPSettings()
{
if (advancedSIPSettingsDropped_) {
ui->advancedAccountSettingsSIPButton->setIcon(QIcon(":/images/icons/round-arrow_drop_down-24px.svg"));
ui->scrollBarSIPLabel->show();
ui->advancedSIPSettingsWidget->setVisible(false);
} else {
ui->advancedAccountSettingsSIPButton->setIcon(QIcon(":/images/icons/round-arrow_drop_up-24px.svg"));
ui->scrollBarSIPLabel->hide();
ui->advancedSIPSettingsWidget->setVisible(true);
ui->advancedSIPSettingsWidget->updateAdvancedSIPSettings();
QTimer::singleShot(50, this,
[this] {
auto top = ui->advancedAccountSettingsSIPButton->frameGeometry().top();
ui->scrollSIPArea->verticalScrollBar()->setSliderPosition(top);
});
}
advancedSIPSettingsDropped_ = !advancedSIPSettingsDropped_;
}
void SettingsWidget::toggleAdvancedSettings()
{
if (advancedSettingsDropped_) {
ui->advancedAccountSettingsPButton->setIcon(QIcon(":/images/icons/round-arrow_drop_down-24px.svg"));
ui->scrollBarLabel->show();
ui->advancedSettingsWidget->setVisible(false);
} else {
ui->advancedAccountSettingsPButton->setIcon(QIcon(":/images/icons/round-arrow_drop_up-24px.svg"));
ui->scrollBarLabel->hide();
ui->advancedSettingsWidget->setVisible(true);
ui->advancedSettingsWidget->updateAdvancedSettings();
QTimer::singleShot(50, this,
[this] {
auto top = ui->advancedAccountSettingsPButton->frameGeometry().top();
ui->scrollArea->verticalScrollBar()->setSliderPosition(top);
});
}
advancedSettingsDropped_ = !advancedSettingsDropped_;
}
void SettingsWidget::toggleBannedContacts()
{
auto bannedContactsVisible = ui->bannedContactsListWidget->isVisible();
ui->bannedContactsListWidget->setVisible(!bannedContactsVisible);
updateAndShowBannedContactsSlot();
}
void SettingsWidget::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
scrollSIPArea_->resize(ui->currentSIPAccountSettingsScrollWidget->width(), this->height());
scrollArea_->resize(ui->currentAccountSettingsScrollWidget->width(), this->height());
}
void SettingsWidget::verifyRegisteredNameSlot()
{
if (!LRCInstance::getCurrentAccountInfo().registeredName.empty()) {
setRegNameUi(RegName::BLANK);
} else {
registeredName_ = ui->currentRegisteredID->text().simplified();
if (!registeredName_.isEmpty()) {
if (validateRegNameForm(registeredName_)) { // name has valid form
setRegNameUi(RegName::SEARCHING);
QTimer::singleShot(300, this, SLOT(beforeNameLookup()));
} else { // name does not have valid form
setRegNameUi(RegName::INVALIDFORM);
}
} else {
setRegNameUi(RegName::BLANK);
}
}
}
// returns true if name is valid registered name
bool SettingsWidget::validateRegNameForm(const QString& regName)
{
QRegularExpression regExp(" ");
if (regName.size() > 2 && !regName.contains(regExp)) {
return true;
} else {
return false;
}
}
void SettingsWidget::receiveRegNameSlot(const std::string& accountID,
lrc::api::account::LookupStatus status, const std::string& address, const std::string& name)
{
Q_UNUSED(accountID);
Q_UNUSED(address);
afterNameLookup(status, name);
}
void SettingsWidget::beforeNameLookup()
{
NameDirectory::instance().lookupName(QString(), registeredName_);
}
void SettingsWidget::afterNameLookup(lrc::api::account::LookupStatus status, const std::string& regName)
{
if (registeredName_.toStdString() == regName && regName.length() > 2) {
if (status == lrc::api::account::LookupStatus::NOT_FOUND) {
setRegNameUi(RegName::FREE);
} else {
setRegNameUi(RegName::TAKEN);
}
} else {
setRegNameUi(RegName::BLANK);
}
}
void SettingsWidget::setRegNameUi(RegName stat)
{
disconnect(ui->btnRegisterName, &QPushButton::clicked, this, &SettingsWidget::slotRegisterName);
switch (stat) {
case RegName::BLANK:
ui->btnRegisterName->setVisible(false);
ui->lookupStatusLabel->hide();
break;
case RegName::INVALIDFORM:
ui->btnRegisterName->setVisible(false);
ui->lookupStatusLabel->setPixmap(statusInvalidPixmap_);
ui->lookupStatusLabel->show();
ui->lookupStatusLabel->setToolTip(tr("A registered name should not have any spaces and must be at least three letters long"));
break;
case RegName::TAKEN:
ui->btnRegisterName->setVisible(false);
ui->lookupStatusLabel->setPixmap(statusErrorPixmap_);
ui->lookupStatusLabel->show();
ui->lookupStatusLabel->setToolTip(tr("This name is already taken"));
break;
case RegName::FREE:
ui->btnRegisterName->setVisible(true);
ui->lookupStatusLabel->setPixmap(statusSuccessPixmap_);
ui->lookupStatusLabel->show();
ui->lookupStatusLabel->setToolTip(tr("Register this name"));
connect(ui->btnRegisterName, &QPushButton::clicked, this, &SettingsWidget::slotRegisterName);
break;
case RegName::SEARCHING:
ui->btnRegisterName->setVisible(false);
ui->lookupStatusLabel->setMovie(lookupSpinnerMovie_);
lookupSpinnerMovie_->stop();
lookupSpinnerMovie_->start();
ui->lookupStatusLabel->show();
ui->lookupStatusLabel->setToolTip(tr(""));
break;
}
}
void
SettingsWidget::slotRegisterName()
{
NameRegistrationDialog nameRegistrationDialog(registeredName_, this);
if (nameRegistrationDialog.exec() == QDialog::Accepted) {
lrc::api::account::ConfProperties_t accountProperties = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), accountProperties);
ui->btnRegisterName->hide();
ui->currentRegisteredID->setStyleSheet("font-weight: bold; background-color: transparent;border: 0px;");
ui->currentRegisteredID->setClearButtonEnabled(false);
ui->currentRegisteredID->setReadOnly(true);
ui->lookupStatusLabel->hide();
} else {
ui->currentRegisteredID->setText("");
registeredName_ = "";
setRegNameUi(RegName::BLANK);
}
}
void SettingsWidget::setAccEnableSlot(int state)
{
LRCInstance::editableAccountModel()->enableAccount(LRCInstance::getCurrAccId(), (bool)state);
auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
LRCInstance::editableAccountModel()->setAccountConfig(LRCInstance::getCurrAccId(), confProps);
}
void SettingsWidget::delAccountSlot()
{
DeleteAccountDialog delDialog(this);
auto ret = delDialog.exec();
if (ret == QDialog::Accepted) {
LRCInstance::setSelectedAccountId("");
if (!LRCInstance::accountModel().getAccountList().size()) {
emit NavigationRequested(ScreenEnum::WizardScreen);
} else {
LRCInstance::setSelectedConvId("");
emit NavigationRequested(ScreenEnum::CallScreen);
}
}
}
void SettingsWidget::removeDeviceSlot(int index)
{
if (!index) {
return;
}
auto deviceList = LRCInstance::getCurrentAccountInfo().deviceModel->getAllDevices();
auto it = deviceList.begin();
std::advance(it, index);
QString password;
bool ok = false;
if (LRCInstance::getCurrAccConfig().archiveHasPassword) {
password = QInputDialog::getText(this, tr("Remove Device"),
tr("Enter this account's password to confirm the removal of this device"),
QLineEdit::Password,
QDir::home().dirName(), &ok);
} else {
password = "";
QMessageBox confirmDialog;
confirmDialog.setText(tr("Are you sure you wish to remove this device?"));
confirmDialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
confirmDialog.setDefaultButton(QMessageBox::Cancel);
if (confirmDialog.exec() == QMessageBox::Ok) {
goto delete_;
}
}
if (ok) {
delete_:
LRCInstance::getCurrentAccountInfo().deviceModel->revokeDevice(it->id, password.toStdString());
updateAndShowDevicesSlot();
}
}
void SettingsWidget::unban(int index)
{
auto bannedContactList = LRCInstance::getCurrentAccountInfo().contactModel->getBannedContacts();
auto it = bannedContactList.begin();
std::advance(it, index);
auto contactInfo = LRCInstance::getCurrentAccountInfo().contactModel->getContact(*it);
LRCInstance::getCurrentAccountInfo().contactModel->addContact(contactInfo);
updateAndShowBannedContactsSlot();
}
void SettingsWidget::exportAccountSlot()
{
QFileDialog dialog(this);
QString dir = QFileDialog::getExistingDirectory(this, tr("Export Account Here"),
QDir::homePath() + "/Desktop", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty()) {
LRCInstance::accountModel().exportToFile(LRCInstance::getCurrAccId(), (dir + "/export.gz").toStdString());
}
}
void SettingsWidget::updateAndShowDevicesSlot()
{
ui->settingsListWidget->clear();
ui->linkDevPushButton->show();
auto deviceList = LRCInstance::getCurrentAccountInfo().deviceModel->getAllDevices();
int i = 0;
for (auto it = deviceList.begin(); it != deviceList.end(); ++it, ++i) {
auto item = new QListWidgetItem(ui->settingsListWidget);
ui->settingsListWidget->addItem(item);
auto row = new DeviceItemWidget(QString::fromStdString(it->name),
QString::fromStdString(it->id),
it->isCurrent,
this);
item->setSizeHint(QSize(ui->settingsListWidget->width(),
row->minimumSizeHint().height()));
ui->settingsListWidget->setItemWidget(item, row);
connect(row, &DeviceItemWidget::btnRemoveDeviceClicked,
[this, i, isCurrent = it->isCurrent]() {
removeDeviceSlot(i);
});
}
}
void SettingsWidget::updateAndShowBannedContactsSlot()
{
if (!ui->bannedContactsListWidget->isVisible()) {
ui->bannedContactsBtn->setIcon(QIcon(":/images/icons/round-arrow_drop_down-24px.svg"));
return;
}
ui->bannedContactsBtn->setIcon(QIcon(":/images/icons/round-arrow_drop_up-24px.svg"));
auto bannedContactList = LRCInstance::getCurrentAccountInfo().contactModel->getBannedContacts();
if (!bannedContactList.size()) {
toggleBannedContacts();
ui->bannedContactsLayoutWidget->setVisible(false);
return;
}
ui->bannedListWidget->clear();
int i = 0;
for (auto it = bannedContactList.begin(); it != bannedContactList.end(); ++it, ++i) {
auto contactInfo = LRCInstance::getCurrentAccountInfo().contactModel->getContact(*it);
auto contactName = QString::fromStdString(contactInfo.registeredName);
auto contactId = QString::fromStdString(contactInfo.profileInfo.uri);
auto item = new QListWidgetItem(ui->bannedListWidget);
ui->bannedListWidget->addItem(item);
auto row = new BannedItemWidget(contactName,
contactId,
this);
item->setSizeHint(QSize(ui->bannedListWidget->width(),
row->minimumSizeHint().height()));
ui->bannedListWidget->setItemWidget(item, row);
connect(row, &BannedItemWidget::btnReAddContactClicked,
[this, i]() {
unban(i);
});
}
}
void SettingsWidget::showLinkDevSlot()
{
if (!advancedSettingsWidget_) {
delete advancedSettingsWidget_;
}
auto linkDeviceDialog = new LinkDeviceDialog(this);
linkDeviceDialog->exec();
}
void SettingsWidget::setConnections()
{
// btnExitSettings
connect(ui->btnExitSettings, &QPushButton::clicked, this, &SettingsWidget::leaveSettingsSlot);
connect(ui->accountSettingsButton, &QPushButton::clicked, [this]() {
setSelected(Button::accountSettingsButton);
});
connect(ui->generalSettingsButton, &QPushButton::clicked, [this]() {
setSelected(Button::generalSettingsButton);
});
connect(ui->mediaSettingsButton, &QPushButton::clicked, [this]() {
setSelected(Button::mediaSettingsButton);
});
/*connect(ui->currentSIPAccountAvatar, &QPushButton::clicked, [this]() {
avatarClicked();
});*/
connect(ui->advancedAccountSettingsSIPButton, &QPushButton::clicked, this, &SettingsWidget::toggleAdvancedSIPSettings);
// connect "delete SIP account" button
connect(ui->btnSIPDeletAccount, &QPushButton::clicked, this, &SettingsWidget::delAccountSlot);
connect(ui->accountSIPEnableCheckBox, &QCheckBox::clicked, this, &SettingsWidget::setAccEnableSlot);
connect(ui->displaySIPNameLineEdit, &QLineEdit::editingFinished,
[this] {
LRCInstance::setCurrAccDisplayName(ui->displaySIPNameLineEdit->text().toStdString());
});
connect(ui->passSIPlineEdit, &QLineEdit::editingFinished,
[this] {
confProps_ = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
confProps_.password = ui->passSIPlineEdit->text().toStdString();
LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps_);
});
connect(ui->ProxySIP, &QLineEdit::editingFinished,
[this] {
confProps_ = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
confProps_.proxyServer = ui->ProxySIP->text().toStdString();
LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps_);
});
connect(ui->passwdPushButton, &QPushButton::clicked,
[this]() {
passwordClicked();
});
connect(ui->currentAccountAvatar, &PhotoboothWidget::clearedPhoto,
[this] {
LRCInstance::setCurrAccAvatar(QPixmap());
setAvatar(ui->currentAccountAvatar);
});
connect(ui->currentAccountAvatar, &PhotoboothWidget::photoTaken,
[this] {
LRCInstance::setCurrAccAvatar(ui->currentAccountAvatar->getAvatarPixmap());
});
connect(ui->currentSIPAccountAvatar, &PhotoboothWidget::clearedPhoto,
[this] {
LRCInstance::setCurrAccAvatar(QPixmap());
setAvatar(ui->currentSIPAccountAvatar);
});
connect(ui->currentSIPAccountAvatar, &PhotoboothWidget::photoTaken,
[this] {
LRCInstance::setCurrAccAvatar(ui->currentSIPAccountAvatar->getAvatarPixmap());
});
connect(ui->advancedAccountSettingsPButton, &QPushButton::clicked, this, &SettingsWidget::toggleAdvancedSettings);
connect(ui->currentRegisteredID, &QLineEdit::textEdited, this, &SettingsWidget::verifyRegisteredNameSlot);
connect(&LRCInstance::accountModel(), &lrc::api::NewAccountModel::registeredNameFound,
this, &SettingsWidget::receiveRegNameSlot);
//connect "export account" button
connect(ui->btnExportAccount, &QPushButton::clicked, this, &SettingsWidget::exportAccountSlot);
// connect "delete account" button
connect(ui->btnDeletAccount, &QPushButton::clicked, this, &SettingsWidget::delAccountSlot);
// connect "banned contacts" button
connect(ui->bannedContactsBtn, &QPushButton::clicked, this, &SettingsWidget::toggleBannedContacts);
// connect "link device" button
connect(ui->linkDevPushButton, &QPushButton::clicked, this, &SettingsWidget::showLinkDevSlot);
// update banned accounts automatically
connect(LRCInstance::getCurrentAccountInfo().contactModel.get(), &lrc::api::ContactModel::modelUpdated,
this, &SettingsWidget::updateAndShowBannedContactsSlot);
// update linked devices automatically
QObject::connect(LRCInstance::getCurrentAccountInfo().deviceModel.get(), &lrc::api::NewDeviceModel::deviceUpdated,
this, &SettingsWidget::updateAndShowDevicesSlot);
// account settings setters {
connect(ui->accountEnableCheckBox, &QCheckBox::clicked, this, &SettingsWidget::setAccEnableSlot);
connect(ui->displayNameLineEdit, &QLineEdit::editingFinished,
[this] {
LRCInstance::setCurrAccDisplayName(ui->displayNameLineEdit->text().toStdString());
});
connect(ui->usernameSIP, &QLineEdit::editingFinished,
[this] {
confProps_ = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
confProps_.username = ui->usernameSIP->text().toStdString();
LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps_);
});
connect(ui->hostnameSIP, &QLineEdit::editingFinished,
[this] {
confProps_ = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
confProps_.hostname = ui->hostnameSIP->text().toStdString();
LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps_);
});
// general settings
connect(ui->notificationCheckBox, &QAbstractButton::clicked, this, &SettingsWidget::slotSetNotifications);
connect(ui->closeOrMinCheckBox, &QAbstractButton::clicked, this, &SettingsWidget::slotSetClosedOrMin);
connect(ui->downloadButton, &QAbstractButton::clicked, this, &SettingsWidget::openDownloadFolderSlot);
connect(ui->checkUpdateButton, &QAbstractButton::clicked, this, &SettingsWidget::checkForUpdateSlot);
connect(ui->autoUpdateCheckBox, &QAbstractButton::clicked, this, &SettingsWidget::slotSetUpdateAutomatic);
// audio / visual settings
connect(ui->recordPathButton, &QPushButton::clicked, this, &SettingsWidget::openRecordFolderSlot);
connect(ui->hardwareAccelCheckBox, &QAbstractButton::clicked, this, &SettingsWidget::slotSetHardwareAccel);
}
// ************************* General Settings *************************
void SettingsWidget::populateGeneralSettings()
{
QSettings settings("jami.net", "Jami");
// settings
QString downloadPath = QDir::toNativeSeparators(QString::fromStdString(LRCInstance::dataTransferModel().downloadDirectory));
int pos = downloadPath.lastIndexOf(QChar('\\'));
if (pos == downloadPath.length() - 1) {
downloadPath.truncate(pos);
}
Utils::setElidedText(ui->downloadButton, downloadPath);
ui->closeOrMinCheckBox->setChecked(settings.value(SettingsKey::closeOrMinimized).toBool());
auto notifs = settings.value(SettingsKey::enableNotifications).toBool();
ui->notificationCheckBox->setChecked(notifs);
//recordings
if (LRCInstance::avModel().getRecordPath().empty()) {
QString recordPath = QDir::toNativeSeparators(
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
LRCInstance::avModel().setRecordPath(recordPath.toStdString());
}
Utils::setElidedText(ui->recordPathButton,
QString::fromStdString(LRCInstance::avModel().getRecordPath()));
#ifdef Q_OS_WIN
ui->autoUpdateCheckBox->setChecked(settings.value(SettingsKey::autoUpdate).toBool());
#endif
}
void SettingsWidget::slotSetNotifications(bool state)
{
QSettings settings("jami.net", "Jami");
settings.setValue(SettingsKey::enableNotifications, state);
}
void SettingsWidget::slotSetClosedOrMin(bool state)
{
QSettings settings("jami.net", "Jami");
settings.setValue(SettingsKey::closeOrMinimized, state);
}
void SettingsWidget::checkForUpdateSlot()
{
#ifdef Q_OS_WIN
Utils::checkForUpdates(true, this);
#endif
}
void SettingsWidget::slotSetUpdateAutomatic(bool state)
{
#ifdef Q_OS_WIN
QSettings settings("jami.net", "Jami");
settings.setValue(SettingsKey::autoUpdate, state);
#endif
}
void SettingsWidget::openDownloadFolderSlot()
{
QSettings settings("jami.net", "Jami");
QString dir = QFileDialog::getExistingDirectory(this, tr("Select A Folder For Your Downloads"),
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty()) {
Utils::setElidedText(ui->downloadButton, dir);
settings.setValue(SettingsKey::downloadPath, dir);
LRCInstance::editableDataTransferModel()->downloadDirectory = dir.toStdString() + "/";
}
}
void SettingsWidget::openRecordFolderSlot()
{
QString dir = QFileDialog::getExistingDirectory(
this,
tr("Select A Folder For Your Recordings"),
QString::fromStdString(LRCInstance::avModel().getRecordPath()),
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
);
if (!dir.isEmpty()) {
LRCInstance::avModel().setRecordPath(dir.toStdString());
Utils::setElidedText(ui->recordPathButton,
QString::fromStdString(LRCInstance::avModel().getRecordPath())
);
}
}
// ************************* Audio/Visual Settings *************************
void SettingsWidget::populateAVSettings()
{
Utils::oneShotConnect(
&LRCInstance::avModel(),
&lrc::api::AVModel::deviceEvent,
[this] { populateAVSettings(); });
// audio input devices
disconnect(ui->inputComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsWidget::inputdevIndexChangedSlot);
ui->inputComboBox->clear();
auto inputDevices = LRCInstance::avModel().getAudioInputDevices();
auto inputDevice = LRCInstance::avModel().getInputDevice();
auto inputIndex = Utils::indexInVector(inputDevices, inputDevice);
for (auto id : inputDevices) {
ui->inputComboBox->addItem(QString::fromStdString(id).toUtf8());
}
ui->inputComboBox->setCurrentIndex(inputIndex != -1 ? inputIndex : 0);
connect(ui->inputComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsWidget::inputdevIndexChangedSlot);
// audio output devices
disconnect(ui->outputComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsWidget::outputDevIndexChangedSlot);
ui->outputComboBox->clear();
auto outputDevices = LRCInstance::avModel().getAudioOutputDevices();
auto outputDevice = LRCInstance::avModel().getOutputDevice();
auto outputIndex = Utils::indexInVector(outputDevices, outputDevice);
for (auto od : outputDevices) {
ui->outputComboBox->addItem(QString::fromStdString(od).toUtf8());
}
ui->outputComboBox->setCurrentIndex(outputIndex != -1 ? outputIndex : 0);
connect(ui->outputComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsWidget::outputDevIndexChangedSlot);
//// video
disconnect(ui->deviceBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsWidget::slotDeviceBoxCurrentIndexChanged);
disconnect(ui->formatBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsWidget::slotFormatBoxCurrentIndexChanged);
auto devices = LRCInstance::avModel().getDevices();
bool shouldReinitializePreview = true;
ui->deviceBox->clear();
ui->formatBox->clear();
bool hasVideoDevices = devices.size();
ui->deviceBox->setEnabled(hasVideoDevices);
ui->formatBox->setEnabled(hasVideoDevices);
ui->labelVideoDevice->setEnabled(hasVideoDevices);
ui->labelVideoFormat->setEnabled(hasVideoDevices);
if (hasVideoDevices) {
auto device = LRCInstance::avModel().getDefaultDeviceName();
shouldReinitializePreview = currentDisplayedVideoDevice_ != device;
currentDisplayedVideoDevice_ = device;
auto deviceIndex = Utils::indexInVector(devices, device);
for (auto d : devices) {
ui->deviceBox->addItem(QString::fromStdString(d).toUtf8());
}
ui->deviceBox->setCurrentIndex(deviceIndex);
setFormatListForDevice(device);
} else {
currentDisplayedVideoDevice_.clear();
ui->deviceBox->addItem(QObject::tr("None"));
ui->formatBox->addItem(QObject::tr("None"));
}
connect(ui->deviceBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsWidget::slotDeviceBoxCurrentIndexChanged);
connect(ui->formatBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsWidget::slotFormatBoxCurrentIndexChanged);
if (shouldReinitializePreview) {
showPreview();
}
auto encodeAccel = LRCInstance::avModel().getHardwareAcceleration();
ui->hardwareAccelCheckBox->setChecked(encodeAccel);
}
void SettingsWidget::outputDevIndexChangedSlot(int index)
{
auto selectedOutputDeviceName = ui->outputComboBox->itemData(index, Qt::DisplayRole).toString();
LRCInstance::avModel().setOutputDevice(selectedOutputDeviceName.toStdString());
}
void SettingsWidget::inputdevIndexChangedSlot(int index)
{
auto selectedInputDeviceName = ui->inputComboBox->itemData(index, Qt::DisplayRole)
.toString().toStdString();
LRCInstance::avModel().setInputDevice(selectedInputDeviceName);
}
void SettingsWidget::slotDeviceBoxCurrentIndexChanged(int index)
{
currentDisplayedVideoDevice_ = ui->deviceBox->itemData(index, Qt::DisplayRole)
.toString().toStdString();
LRCInstance::avModel().setDefaultDevice(currentDisplayedVideoDevice_);
setFormatListForDevice(currentDisplayedVideoDevice_);
if (!LRCInstance::getActiveCalls().size()) {
showPreview();
}
}
void SettingsWidget::slotFormatBoxCurrentIndexChanged(int index)
{
auto resolution = formatIndexList_.at(index).first;
auto rate = formatIndexList_.at(index).second;
auto currentSettings = LRCInstance::avModel().getDeviceSettings(currentDisplayedVideoDevice_);
lrc::api::video::Settings settings{ "", currentDisplayedVideoDevice_, rate, resolution };
ui->videoWidget->connectRendering();
LRCInstance::avModel().setDeviceSettings(settings);
}
void SettingsWidget::startVideo()
{
LRCInstance::avModel().stopPreview();
LRCInstance::avModel().startPreview();
}
void SettingsWidget::stopVideo()
{
LRCInstance::avModel().stopPreview();
}
void SettingsWidget::toggleVideoSettings(bool enabled)
{
ui->formatBox->clear();
ui->deviceBox->clear();
ui->formatBox->setEnabled(enabled);
ui->deviceBox->setEnabled(enabled);
}
void SettingsWidget::toggleVideoPreview(bool enabled)
{
ui->previewUnavailableLabel->setVisible(!enabled);
ui->videoLayoutWidget->setVisible(enabled);
}
void SettingsWidget::showPreview()
{
ui->videoWidget->connectRendering();
if (!LRCInstance::getActiveCalls().size()) {
ui->previewUnavailableLabel->hide();
ui->videoLayoutWidget->show();
startVideo();
ui->videoWidget->setIsFullPreview(true);
} else {
ui->previewUnavailableLabel->show();
ui->videoLayoutWidget->hide();
}
}
void SettingsWidget::setFormatListForDevice(const std::string& device)
{
auto deviceCapabilities = LRCInstance::avModel().getDeviceCapabilities(device);
if (deviceCapabilities.size() == 0) {
return;
}
auto currentSettings = LRCInstance::avModel().getDeviceSettings(device);
auto currentChannel = currentSettings.channel;
currentChannel = currentChannel.empty() ? "default" : currentChannel;
auto channelCaps = deviceCapabilities.at(currentChannel);
ui->formatBox->blockSignals(true);
ui->formatBox->clear();
formatIndexList_.clear();
for (auto [resolution, frameRateList] : channelCaps) {
for (auto rate : frameRateList) {
formatIndexList_.append(QPair<std::string , float> (resolution, rate));
auto sizeRateString = QString("%1 [%2 fps]")
.arg(QString::fromStdString(resolution))
.arg(round(rate));
ui->formatBox->addItem(sizeRateString.toUtf8());
if (resolution == currentSettings.size && rate == currentSettings.rate) {
ui->formatBox->setCurrentIndex(ui->formatBox->count() - 1);
}
}
}
ui->formatBox->blockSignals(false);
}
void SettingsWidget::slotSetHardwareAccel(bool state)
{
LRCInstance::avModel().setHardwareAcceleration(state);
}