mirror of
https://github.com/mumble-voip/mumble.git
synced 2025-10-26 11:19:16 +00:00
FEAT(tts): Allow disabling Text-To-Speech per user
These changes make it possible to turn of TTS for a specific user while still receiving their messages. This setting can be managed from the context menu of a user that is connected to the server and is only visible when TTS is enabled globally. A new DB table called 'ignored_tts' had to be created to persist this setting.
This commit is contained in:
parent
d73465e3a2
commit
1a4d134a35
@ -19,6 +19,7 @@ ClientUser::ClientUser(QObject *p) : QObject(p),
|
||||
tsState(Settings::Passive),
|
||||
tLastTalkStateChange(false),
|
||||
bLocalIgnore(false),
|
||||
bLocalIgnoreTTS(false),
|
||||
bLocalMute(false),
|
||||
fPowerMin(0.0f),
|
||||
fPowerMax(0.0f),
|
||||
@ -134,6 +135,8 @@ QString ClientUser::getFlagsString() const {
|
||||
flags << ClientUser::tr("Deafened (server)");
|
||||
if (bLocalIgnore)
|
||||
flags << ClientUser::tr("Local Ignore (Text messages)");
|
||||
if (bLocalIgnoreTTS)
|
||||
flags << ClientUser::tr("Local Ignore (Text-To-Speech)");
|
||||
if (bLocalMute)
|
||||
flags << ClientUser::tr("Local Mute");
|
||||
if (bSelfMute)
|
||||
@ -190,6 +193,10 @@ void ClientUser::setLocalIgnore(bool ignore) {
|
||||
emit muteDeafStateChanged();
|
||||
}
|
||||
|
||||
void ClientUser::setLocalIgnoreTTS(bool ignoreTTS) {
|
||||
bLocalIgnoreTTS = ignoreTTS;
|
||||
}
|
||||
|
||||
void ClientUser::setLocalMute(bool mute) {
|
||||
if (bLocalMute == mute)
|
||||
return;
|
||||
|
||||
@ -21,6 +21,7 @@ class ClientUser : public QObject, public User {
|
||||
Settings::TalkState tsState;
|
||||
Timer tLastTalkStateChange;
|
||||
bool bLocalIgnore;
|
||||
bool bLocalIgnoreTTS;
|
||||
bool bLocalMute;
|
||||
|
||||
float fPowerMin, fPowerMax;
|
||||
@ -67,6 +68,7 @@ class ClientUser : public QObject, public User {
|
||||
void setDeaf(bool deaf);
|
||||
void setSuppress(bool suppress);
|
||||
void setLocalIgnore(bool ignore);
|
||||
void setLocalIgnoreTTS(bool ignoreTTS);
|
||||
void setLocalMute(bool mute);
|
||||
void setSelfMute(bool mute);
|
||||
void setSelfDeaf(bool deaf);
|
||||
|
||||
@ -137,6 +137,9 @@ Database::Database(const QString &dbname) {
|
||||
execQueryAndLogFailure(query, QLatin1String("CREATE TABLE IF NOT EXISTS `ignored` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT)"));
|
||||
execQueryAndLogFailure(query, QLatin1String("CREATE UNIQUE INDEX IF NOT EXISTS `ignored_hash` ON `ignored`(`hash`)"));
|
||||
|
||||
execQueryAndLogFailure(query, QLatin1String("CREATE TABLE IF NOT EXISTS `ignored_tts` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT)"));
|
||||
execQueryAndLogFailure(query, QLatin1String("CREATE UNIQUE INDEX IF NOT EXISTS `ignored_tts_hash` ON `ignored_tts`(`hash`)"));
|
||||
|
||||
execQueryAndLogFailure(query, QLatin1String("CREATE TABLE IF NOT EXISTS `muted` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT)"));
|
||||
execQueryAndLogFailure(query, QLatin1String("CREATE UNIQUE INDEX IF NOT EXISTS `muted_hash` ON `muted`(`hash`)"));
|
||||
execQueryAndLogFailure(query, QLatin1String("CREATE TABLE IF NOT EXISTS `volume` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT, `volume` FLOAT)"));
|
||||
@ -238,6 +241,26 @@ void Database::setLocalIgnored(const QString &hash, bool ignored) {
|
||||
execQueryAndLogFailure(query);
|
||||
}
|
||||
|
||||
bool Database::isLocalIgnoredTTS(const QString &hash) {
|
||||
QSqlQuery query(db);
|
||||
|
||||
query.prepare(QLatin1String("SELECT `hash` FROM `ignored_tts` WHERE `hash` = ?"));
|
||||
query.addBindValue(hash);
|
||||
execQueryAndLogFailure(query);
|
||||
return query.next();
|
||||
}
|
||||
|
||||
void Database::setLocalIgnoredTTS(const QString &hash, bool ignoredTTS) {
|
||||
QSqlQuery query(db);
|
||||
|
||||
if (ignoredTTS)
|
||||
query.prepare(QLatin1String("INSERT INTO `ignored_tts` (`hash`) VALUES (?)"));
|
||||
else
|
||||
query.prepare(QLatin1String("DELETE FROM `ignored_tts` WHERE `hash` = ?"));
|
||||
query.addBindValue(hash);
|
||||
execQueryAndLogFailure(query);
|
||||
}
|
||||
|
||||
bool Database::isLocalMuted(const QString &hash) {
|
||||
QSqlQuery query(db);
|
||||
|
||||
|
||||
@ -37,6 +37,9 @@ class Database : public QObject {
|
||||
bool isLocalIgnored(const QString &hash);
|
||||
void setLocalIgnored(const QString &hash, bool ignored);
|
||||
|
||||
bool isLocalIgnoredTTS(const QString &hash);
|
||||
void setLocalIgnoredTTS(const QString &hash, bool ignoredTTS);
|
||||
|
||||
bool isLocalMuted(const QString &hash);
|
||||
void setLocalMuted(const QString &hash, bool muted);
|
||||
|
||||
|
||||
@ -324,15 +324,15 @@ QString Log::formatChannel(::Channel *c) {
|
||||
return QString::fromLatin1("<a href='channelid://%1/%3' class='log-channel'>%2</a>").arg(c->iId).arg(c->qsName.toHtmlEscaped()).arg(QString::fromLatin1(g.sh->qbaDigest.toBase64()));
|
||||
}
|
||||
|
||||
void Log::logOrDefer(Log::MsgType mt, const QString &console, const QString &terse, bool ownMessage, const QString &overrideTTS) {
|
||||
void Log::logOrDefer(Log::MsgType mt, const QString &console, const QString &terse, bool ownMessage, const QString &overrideTTS, bool ignoreTTS) {
|
||||
if (g.l) {
|
||||
// log directly as it seems the log-UI has been set-up already
|
||||
g.l->log(mt, console, terse, ownMessage, overrideTTS);
|
||||
g.l->log(mt, console, terse, ownMessage, overrideTTS, ignoreTTS);
|
||||
} else {
|
||||
// defer the log
|
||||
QMutexLocker mLock(&Log::qmDeferredLogs);
|
||||
|
||||
qvDeferredLogs.append(LogMessage(mt, console, terse, ownMessage, overrideTTS));
|
||||
qvDeferredLogs.append(LogMessage(mt, console, terse, ownMessage, overrideTTS, ignoreTTS));
|
||||
}
|
||||
}
|
||||
|
||||
@ -494,7 +494,7 @@ QString Log::validHtml(const QString &html, QTextCursor *tc) {
|
||||
}
|
||||
}
|
||||
|
||||
void Log::log(MsgType mt, const QString &console, const QString &terse, bool ownMessage, const QString &overrideTTS) {
|
||||
void Log::log(MsgType mt, const QString &console, const QString &terse, bool ownMessage, const QString &overrideTTS, bool ignoreTTS) {
|
||||
QDateTime dt = QDateTime::currentDateTime();
|
||||
|
||||
int ignore = qmIgnore.value(mt);
|
||||
@ -601,7 +601,7 @@ void Log::log(MsgType mt, const QString &console, const QString &terse, bool own
|
||||
}
|
||||
|
||||
// Message notification with Text-To-Speech
|
||||
if (g.s.bDeaf || !g.s.bTTS || !(flags & Settings::LogTTS)) {
|
||||
if (g.s.bDeaf || !g.s.bTTS || !(flags & Settings::LogTTS) || ignoreTTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -658,7 +658,7 @@ void Log::processDeferredLogs() {
|
||||
while (!qvDeferredLogs.isEmpty()) {
|
||||
LogMessage msg = qvDeferredLogs.takeFirst();
|
||||
|
||||
log(msg.mt, msg.console, msg.terse, msg.ownMessage, msg.overrideTTS);
|
||||
log(msg.mt, msg.console, msg.terse, msg.ownMessage, msg.overrideTTS, msg.ignoreTTS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -682,8 +682,8 @@ void Log::postQtNotification(MsgType mt, const QString &plain) {
|
||||
}
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(Log::MsgType mt, const QString &console, const QString &terse, bool ownMessage, const QString &overrideTTS) : mt(mt), console(console),
|
||||
terse(terse), ownMessage(ownMessage), overrideTTS(overrideTTS) {
|
||||
LogMessage::LogMessage(Log::MsgType mt, const QString &console, const QString &terse, bool ownMessage, const QString &overrideTTS, bool ignoreTTS) : mt(mt), console(console),
|
||||
terse(terse), ownMessage(ownMessage), overrideTTS(overrideTTS), ignoreTTS(ignoreTTS) {
|
||||
}
|
||||
|
||||
LogDocument::LogDocument(QObject *p)
|
||||
|
||||
@ -90,9 +90,9 @@ class Log : public QObject {
|
||||
static QString formatChannel(::Channel *c);
|
||||
/// Either defers the LogMessage or defers it, depending on whether Global::l is created already
|
||||
/// (if it is, it is used to directly log the msg)
|
||||
static void logOrDefer(Log::MsgType mt, const QString &console, const QString &terse=QString(), bool ownMessage = false, const QString &overrideTTS=QString());
|
||||
static void logOrDefer(Log::MsgType mt, const QString &console, const QString &terse=QString(), bool ownMessage = false, const QString &overrideTTS=QString(), bool ignoreTTS = false);
|
||||
public slots:
|
||||
void log(MsgType mt, const QString &console, const QString &terse=QString(), bool ownMessage = false, const QString &overrideTTS=QString());
|
||||
void log(MsgType mt, const QString &console, const QString &terse=QString(), bool ownMessage = false, const QString &overrideTTS=QString(), bool ignoreTTS = false);
|
||||
/// Logs LogMessages that have been deferred so far
|
||||
void processDeferredLogs();
|
||||
};
|
||||
@ -104,9 +104,10 @@ class LogMessage {
|
||||
QString terse;
|
||||
bool ownMessage;
|
||||
QString overrideTTS;
|
||||
bool ignoreTTS;
|
||||
|
||||
LogMessage() = default;
|
||||
LogMessage(Log::MsgType mt, const QString &console, const QString &terse, bool ownMessage, const QString &overrideTTS);
|
||||
LogMessage(Log::MsgType mt, const QString &console, const QString &terse, bool ownMessage, const QString &overrideTTS, bool ignoreTTS);
|
||||
};
|
||||
|
||||
class LogDocument : public QTextDocument {
|
||||
|
||||
@ -1526,6 +1526,8 @@ void MainWindow::qmUser_aboutToShow() {
|
||||
qmUser->addAction(qaUserPrioritySpeaker);
|
||||
qmUser->addAction(qaUserLocalMute);
|
||||
qmUser->addAction(qaUserLocalIgnore);
|
||||
if (g.s.bTTS)
|
||||
qmUser->addAction(qaUserLocalIgnoreTTS);
|
||||
qmUser->addAction(qaUserLocalVolume);
|
||||
|
||||
if (isSelf)
|
||||
@ -1585,6 +1587,7 @@ void MainWindow::qmUser_aboutToShow() {
|
||||
qaUserLocalMute->setEnabled(false);
|
||||
qaUserLocalVolume->setEnabled(false);
|
||||
qaUserLocalIgnore->setEnabled(false);
|
||||
qaUserLocalIgnoreTTS->setEnabled(false);
|
||||
qaUserCommentReset->setEnabled(false);
|
||||
qaUserTextureReset->setEnabled(false);
|
||||
qaUserCommentView->setEnabled(false);
|
||||
@ -1595,6 +1598,7 @@ void MainWindow::qmUser_aboutToShow() {
|
||||
qaUserLocalMute->setEnabled(! isSelf);
|
||||
qaUserLocalVolume->setEnabled(! isSelf);
|
||||
qaUserLocalIgnore->setEnabled(! isSelf);
|
||||
qaUserLocalIgnoreTTS->setEnabled(! isSelf);
|
||||
// If the server's version is less than 1.4.0 it won't support the new permission to reset a comment/avatar, so fall back to the old method
|
||||
if (g.sh->uiVersion < 0x010400) {
|
||||
qaUserCommentReset->setEnabled(! p->qbaCommentHash.isEmpty() && (g.pPermissions & (ChanACL::Move | ChanACL::Write)));
|
||||
@ -1610,6 +1614,7 @@ void MainWindow::qmUser_aboutToShow() {
|
||||
qaUserPrioritySpeaker->setChecked(p->bPrioritySpeaker);
|
||||
qaUserLocalMute->setChecked(p->bLocalMute);
|
||||
qaUserLocalIgnore->setChecked(p->bLocalIgnore);
|
||||
qaUserLocalIgnoreTTS->setChecked(p->bLocalIgnoreTTS);
|
||||
}
|
||||
updateMenuPermissions();
|
||||
}
|
||||
@ -1690,6 +1695,18 @@ void MainWindow::on_qaUserLocalIgnore_triggered() {
|
||||
g.db->setLocalIgnored(p->qsHash, ignored);
|
||||
}
|
||||
|
||||
void MainWindow::on_qaUserLocalIgnoreTTS_triggered() {
|
||||
ClientUser *p = getContextMenuUser();
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
bool ignoredTTS = qaUserLocalIgnoreTTS->isChecked();
|
||||
|
||||
p->setLocalIgnoreTTS(ignoredTTS);
|
||||
if (! p->qsHash.isEmpty())
|
||||
g.db->setLocalIgnoredTTS(p->qsHash, ignoredTTS);
|
||||
}
|
||||
|
||||
void MainWindow::on_qaUserLocalVolume_triggered() {
|
||||
ClientUser *p = getContextMenuUser();
|
||||
if (!p) {
|
||||
|
||||
@ -206,6 +206,7 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin
|
||||
void on_qaSelfPrioritySpeaker_triggered();
|
||||
void on_qaUserPrioritySpeaker_triggered();
|
||||
void on_qaUserLocalIgnore_triggered();
|
||||
void on_qaUserLocalIgnoreTTS_triggered();
|
||||
void on_qaUserLocalMute_triggered();
|
||||
void on_qaUserLocalVolume_triggered();
|
||||
void on_qaUserTextMessage_triggered();
|
||||
|
||||
@ -955,6 +955,20 @@ the channel's context menu.</string>
|
||||
<string>Joins the channel of this user.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="qaUserLocalIgnoreTTS">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable Text-To-Speech</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Locally disable Text-To-Speech for this user's text chat messages.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Silently disables Text-To-Speech for all text messages from the user.</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
||||
@ -504,6 +504,8 @@ void MainWindow::msgUserState(const MumbleProto::UserState &msg) {
|
||||
pDst->setLocalMute(true);
|
||||
if (g.db->isLocalIgnored(pDst->qsHash))
|
||||
pDst->setLocalIgnore(true);
|
||||
if (g.db->isLocalIgnoredTTS(pDst->qsHash))
|
||||
pDst->setLocalIgnoreTTS(true);
|
||||
pDst->fLocalVolume = g.db->getUserLocalVolume(pDst->qsHash);
|
||||
}
|
||||
|
||||
@ -909,7 +911,8 @@ void MainWindow::msgTextMessage(const MumbleProto::TextMessage &msg) {
|
||||
tr("%2%1: %3").arg(name).arg(target).arg(u8(msg.message())),
|
||||
tr("Message from %1").arg(plainName),
|
||||
false,
|
||||
overrideTTS.isNull() ? QString() : overrideTTS);
|
||||
overrideTTS.isNull() ? QString() : overrideTTS,
|
||||
pSrc->bLocalIgnoreTTS);
|
||||
}
|
||||
|
||||
/// This message is being received when the server informs the client about the access control list (ACL) for
|
||||
|
||||
Loading…
Reference in New Issue
Block a user