From 7fe8a86c0329481cd34f5ed4e134d2db7a11d096 Mon Sep 17 00:00:00 2001 From: Jeanbon Date: Sat, 25 Jun 2016 21:03:52 +0200 Subject: [PATCH] feat(autoAnswer): add auto answer feature --- doc/user_manual_en.md | 7 ++++ src/persistence/settings.cpp | 31 ++++++++++++++++ src/persistence/settings.h | 15 ++++++++ src/widget/about/aboutuser.cpp | 34 +++++++++++------- src/widget/about/aboutuser.h | 3 +- src/widget/about/aboutuser.ui | 48 ++++++++++++++++++++----- src/widget/form/chatform.cpp | 66 +++++++++++++++++++--------------- 7 files changed, 154 insertions(+), 50 deletions(-) diff --git a/doc/user_manual_en.md b/doc/user_manual_en.md index e041b4502..5053a62f7 100644 --- a/doc/user_manual_en.md +++ b/doc/user_manual_en.md @@ -76,6 +76,13 @@ can have different nicknames, status messages and friends. + _Change password:_ Allows you to either change an existing password, or create a new password if your profile does not have one. +## Friends' options +In the friend's window you can customize some options for this friend specifically. +* _Auto answer:_ chooses the way to autoaccept audio and video calls. + * _Manual:_ All calls must be manually accepted. + * _Audio:_ Only audio calls will be automatically accepted. Video calls must be manually accepted. + * _Audio + video:_ All calls will be automatically accepted. + ## Settings ### General diff --git a/src/persistence/settings.cpp b/src/persistence/settings.cpp index 343cd802c..2b051e449 100644 --- a/src/persistence/settings.cpp +++ b/src/persistence/settings.cpp @@ -338,6 +338,11 @@ void Settings::loadPersonal(Profile* profile) fp.alias = ps.value("alias").toString(); fp.note = ps.value("note").toString(); fp.autoAcceptDir = ps.value("autoAcceptDir").toString(); + + if(fp.autoAcceptDir == "") + fp.autoAcceptDir = ps.value("autoAccept").toString(); + + fp.autoAcceptCall = Settings::AutoAcceptCallFlags(QFlag(ps.value("autoAcceptCall", 0).toInt())); fp.circleID = ps.value("circle", -1).toInt(); if (getEnableLogging()) @@ -558,6 +563,7 @@ void Settings::savePersonal(QString profileName, const QString &password) ps.setValue("alias", frnd.alias); ps.setValue("note", frnd.note); ps.setValue("autoAcceptDir", frnd.autoAcceptDir); + ps.setValue("autoAcceptCall", static_cast(frnd.autoAcceptCall)); ps.setValue("circle", frnd.circleID); if (getEnableLogging()) @@ -1312,6 +1318,31 @@ void Settings::setAutoAcceptDir(const ToxId &id, const QString& dir) } } +Settings::AutoAcceptCallFlags Settings::getAutoAcceptCall(const ToxId &id) const +{ + QMutexLocker locker{&bigLock}; + QString key = id.publicKey; + + auto it = friendLst.find(key); + if (it != friendLst.end()) + return it->autoAcceptCall; + + return Settings::AutoAcceptCallFlags(); +} + +void Settings::setAutoAcceptCall(const ToxId& id, AutoAcceptCallFlags accept) +{ + QMutexLocker locker{&bigLock}; + QString key = id.publicKey; + + auto it = friendLst.find(key); + if(it != friendLst.end()) + { + it->autoAcceptCall = accept; + emit autoAcceptCallChanged(id, accept); + } +} + QString Settings::getContactNote(const ToxId &id) const { QMutexLocker locker{&bigLock}; diff --git a/src/persistence/settings.h b/src/persistence/settings.h index f7146d802..5d7276919 100644 --- a/src/persistence/settings.h +++ b/src/persistence/settings.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "src/core/corestructs.h" class ToxId; @@ -131,6 +132,14 @@ class Settings : public QObject public: enum class ProxyType {ptNone = 0, ptSOCKS5 = 1, ptHTTP = 2}; enum class StyleType {NONE = 0, WITH_CHARS = 1, WITHOUT_CHARS = 2}; + enum class AutoAcceptCall + { + None = 0x00, + Audio = 0x01, + Video = 0x02, + AV = Audio | Video + }; + Q_DECLARE_FLAGS(AutoAcceptCallFlags, AutoAcceptCall); public: static Settings& getInstance(); @@ -192,6 +201,7 @@ signals: void globalAutoAcceptDirChanged(const QString& path); void checkUpdatesChanged(bool enabled); void widgetDataChanged(const QString& key); + void autoAcceptCallChanged(const ToxId& id, AutoAcceptCallFlags accept); // GUI void autoLoginChanged(bool enabled); @@ -397,6 +407,9 @@ public: QString getAutoAcceptDir(const ToxId& id) const; void setAutoAcceptDir(const ToxId& id, const QString& dir); + AutoAcceptCallFlags getAutoAcceptCall(const ToxId& id) const; + void setAutoAcceptCall(const ToxId& id, AutoAcceptCallFlags accept); + QString getGlobalAutoAcceptDir() const; void setGlobalAutoAcceptDir(const QString& dir); @@ -620,6 +633,7 @@ private: QString note; int circleID = -1; QDate activity = QDate(); + AutoAcceptCallFlags autoAcceptCall; }; struct circleProp @@ -640,4 +654,5 @@ private: static QThread* settingsThread; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(Settings::AutoAcceptCallFlags) #endif // SETTINGS_HPP diff --git a/src/widget/about/aboutuser.cpp b/src/widget/about/aboutuser.cpp index da51ed64b..c51a29615 100644 --- a/src/widget/about/aboutuser.cpp +++ b/src/widget/about/aboutuser.cpp @@ -17,16 +17,20 @@ AboutUser::AboutUser(ToxId &toxId, QWidget *parent) : ui->aliases->hide(); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &AboutUser::onAcceptedClicked); - connect(ui->autoaccept, &QCheckBox::clicked, this, &AboutUser::onAutoAcceptClicked); + connect(ui->autoacceptfile, &QCheckBox::clicked, this, &AboutUser::onAutoAcceptDirClicked); + connect(ui->autoacceptcall, SIGNAL(activated(int)), this, SLOT(onAutoAcceptCallClicked(void))); connect(ui->selectSaveDir, &QPushButton::clicked, this, &AboutUser::onSelectDirClicked); connect(ui->removeHistory, &QPushButton::clicked, this, &AboutUser::onRemoveHistoryClicked); this->toxId = toxId; QString dir = Settings::getInstance().getAutoAcceptDir(this->toxId); - ui->autoaccept->setChecked(!dir.isEmpty()); - ui->selectSaveDir->setEnabled(ui->autoaccept->isChecked()); + ui->autoacceptfile->setChecked(!dir.isEmpty()); - if(ui->autoaccept->isChecked()) + ui->autoacceptcall->setCurrentIndex(Settings::getInstance().getAutoAcceptCall(this->toxId)); + + ui->selectSaveDir->setEnabled(ui->autoacceptfile->isChecked()); + + if(ui->autoacceptfile->isChecked()) ui->selectSaveDir->setText(Settings::getInstance().getAutoAcceptDir(this->toxId)); } @@ -48,17 +52,17 @@ void AboutUser::setFriend(Friend *f) } -void AboutUser::onAutoAcceptClicked() +void AboutUser::onAutoAcceptDirClicked() { QString dir; - if (!ui->autoaccept->isChecked()) + if (!ui->autoacceptfile->isChecked()) { dir = QDir::homePath(); - ui->autoaccept->setChecked(false); + ui->autoacceptfile->setChecked(false); Settings::getInstance().setAutoAcceptDir(this->toxId, ""); ui->selectSaveDir->setText(tr("Auto accept for this contact is disabled")); } - else if (ui->autoaccept->isChecked()) + else if (ui->autoacceptfile->isChecked()) { dir = QFileDialog::getExistingDirectory(this, tr("Choose an auto accept directory", "popup title"), @@ -66,14 +70,20 @@ void AboutUser::onAutoAcceptClicked() QFileDialog::DontUseNativeDialog); if(dir.isEmpty()) { - ui->autoaccept->setChecked(false); + ui->autoacceptfile->setChecked(false); return; // user canellced } Settings::getInstance().setAutoAcceptDir(this->toxId, dir); ui->selectSaveDir->setText(Settings::getInstance().getAutoAcceptDir(this->toxId)); } Settings::getInstance().saveGlobal(); - ui->selectSaveDir->setEnabled(ui->autoaccept->isChecked()); + ui->selectSaveDir->setEnabled(ui->autoacceptfile->isChecked()); +} + +void AboutUser::onAutoAcceptCallClicked() +{ + Settings::getInstance().setAutoAcceptCall(this->toxId,Settings::AutoAcceptCallFlags(QFlag(ui->autoacceptcall->currentIndex()))); + Settings::getInstance().savePersonal(); } void AboutUser::onSelectDirClicked() @@ -83,9 +93,9 @@ void AboutUser::onSelectDirClicked() tr("Choose an auto accept directory", "popup title"), dir, QFileDialog::DontUseNativeDialog); - ui->autoaccept->setChecked(true); + ui->autoacceptfile->setChecked(true); Settings::getInstance().setAutoAcceptDir(this->toxId, dir); - Settings::getInstance().saveGlobal(); + Settings::getInstance().savePersonal(); } /** diff --git a/src/widget/about/aboutuser.h b/src/widget/about/aboutuser.h index b206b0395..177a2edf3 100644 --- a/src/widget/about/aboutuser.h +++ b/src/widget/about/aboutuser.h @@ -24,7 +24,8 @@ private: private slots: void onAcceptedClicked(); - void onAutoAcceptClicked(); + void onAutoAcceptDirClicked(); + void onAutoAcceptCallClicked(); void onSelectDirClicked(); void onRemoveHistoryClicked(); }; diff --git a/src/widget/about/aboutuser.ui b/src/widget/about/aboutuser.ui index 7ae77ec68..f74c02b6d 100644 --- a/src/widget/about/aboutuser.ui +++ b/src/widget/about/aboutuser.ui @@ -7,7 +7,7 @@ 0 0 465 - 406 + 460 @@ -164,26 +164,56 @@ - + + + + Auto accept file + + + + Default directory to save files: - + Auto accept for this contact is disabled - - - - Auto accept files - - + + + + + + Auto accept call : + + + + + + + + Manual + + + + + Audio + + + + + Audio + Video + + + + + diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 36b85b2d8..fc1e65070 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -280,39 +280,49 @@ void ChatForm::onAvInvite(uint32_t FriendId, bool video) return; qDebug() << "onAvInvite"; - disableCallButtons(); - if (video) - { - callConfirm = new CallConfirmWidget(videoButton, *f); - videoButton->setObjectName("yellow"); - videoButton->setToolTip(tr("Accept video call")); - videoButton->style()->polish(videoButton); - connect(videoButton, &QPushButton::clicked, this, &ChatForm::onAnswerCallTriggered); - } - else - { - callConfirm = new CallConfirmWidget(callButton, *f); - callButton->setObjectName("yellow"); - callButton->setToolTip(tr("Accept audio call")); - callButton->style()->polish(callButton); - connect(callButton, &QPushButton::clicked, this, &ChatForm::onAnswerCallTriggered); - } - - if (f->getFriendWidget()->chatFormIsSet(false)) - callConfirm->show(); - - connect(callConfirm, &CallConfirmWidget::accepted, this, &ChatForm::onAnswerCallTriggered); - connect(callConfirm, &CallConfirmWidget::rejected, this, &ChatForm::onRejectCallTriggered); - insertChatMessage(ChatMessage::createChatInfoMessage(tr("%1 calling").arg(f->getDisplayedName()), ChatMessage::INFO, QDateTime::currentDateTime())); + /* AutoAcceptCall is set for this friend */ + if ((video && Settings::getInstance().getAutoAcceptCall(f->getToxId()).testFlag(Settings::AutoAcceptCall::Video)) || + (!video && Settings::getInstance().getAutoAcceptCall(f->getToxId()).testFlag(Settings::AutoAcceptCall::Audio))) + { + uint32_t friendId = f->getFriendID(); + qDebug() << "automatic call answer"; + QMetaObject::invokeMethod(coreav, "answerCall", Qt::QueuedConnection, Q_ARG(uint32_t, friendId)); + onAvStart(friendId,video); + } + else + { + if (video) + { + callConfirm = new CallConfirmWidget(videoButton, *f); + videoButton->setObjectName("yellow"); + videoButton->setToolTip(tr("Accept video call")); + videoButton->style()->polish(videoButton); + connect(videoButton, &QPushButton::clicked, this, &ChatForm::onAnswerCallTriggered); + } + else + { + callConfirm = new CallConfirmWidget(callButton, *f); + callButton->setObjectName("yellow"); + callButton->setToolTip(tr("Accept audio call")); + callButton->style()->polish(callButton); + connect(callButton, &QPushButton::clicked, this, &ChatForm::onAnswerCallTriggered); + } - Widget::getInstance()->newFriendMessageAlert(FriendId, false); - Audio& audio = Audio::getInstance(); - audio.startLoop(); - audio.playMono16Sound(QStringLiteral(":/audio/ToxicIncomingCall.pcm")); + if (f->getFriendWidget()->chatFormIsSet(false)) + callConfirm->show(); + + connect(callConfirm, &CallConfirmWidget::accepted, this, &ChatForm::onAnswerCallTriggered); + connect(callConfirm, &CallConfirmWidget::rejected, this, &ChatForm::onRejectCallTriggered); + + Widget::getInstance()->newFriendMessageAlert(FriendId, false); + Audio& audio = Audio::getInstance(); + audio.startLoop(); + audio.playMono16Sound(QStringLiteral(":/audio/ToxicIncomingCall.pcm")); + } } void ChatForm::onAvStart(uint32_t FriendId, bool video)