diff --git a/icons/tango/status/text-missing.svg b/icons/tango/status/text-missing.svg new file mode 100644 index 000000000..d5587e525 --- /dev/null +++ b/icons/tango/status/text-missing.svg @@ -0,0 +1,416 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Broken Image + + + image + picture + photo + missing + broken + 404 + + + + + Garrett LeSage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mumble/Audio.cpp b/src/mumble/Audio.cpp index b8456b096..43908379f 100644 --- a/src/mumble/Audio.cpp +++ b/src/mumble/Audio.cpp @@ -316,7 +316,7 @@ LoopUser::LoopUser() { uiSession = 0; iId = 0; bMute = bDeaf = bSuppress = false; - bLocalMute = bSelfDeaf = false; + bLocalIgnore = bLocalMute = bSelfDeaf = false; tsState = Settings::Passive; cChannel = NULL; qtTicker.start(); diff --git a/src/mumble/ClientUser.cpp b/src/mumble/ClientUser.cpp index 3e89ea11f..d2c2dc077 100644 --- a/src/mumble/ClientUser.cpp +++ b/src/mumble/ClientUser.cpp @@ -42,6 +42,7 @@ QReadWriteLock ClientUser::c_qrwlTalking; ClientUser::ClientUser(QObject *p) : QObject(p), tsState(Settings::Passive), tLastTalkStateChange(false), + bLocalIgnore(false), bLocalMute(false), fPowerMin(0.0f), fPowerMax(0.0f), @@ -150,6 +151,8 @@ QString ClientUser::getFlagsString() const { flags << ClientUser::tr("Muted (server)"); if (bDeaf) flags << ClientUser::tr("Deafened (server)"); + if (bLocalIgnore) + flags << ClientUser::tr("Local Ignore (Text messages)"); if (bLocalMute) flags << ClientUser::tr("Local Mute"); if (bSelfMute) @@ -199,6 +202,13 @@ void ClientUser::setSuppress(bool suppress) { emit muteDeafChanged(); } +void ClientUser::setLocalIgnore(bool ignore) { + if (bLocalIgnore == ignore) + return; + bLocalIgnore = ignore; + emit muteDeafChanged(); +} + void ClientUser::setLocalMute(bool mute) { if (bLocalMute == mute) return; diff --git a/src/mumble/ClientUser.h b/src/mumble/ClientUser.h index 2c7abcdf3..ba196e2c3 100644 --- a/src/mumble/ClientUser.h +++ b/src/mumble/ClientUser.h @@ -48,6 +48,7 @@ class ClientUser : public QObject, public User { Settings::TalkState tsState; Timer tLastTalkStateChange; + bool bLocalIgnore; bool bLocalMute; float fPowerMin, fPowerMax; @@ -97,6 +98,7 @@ class ClientUser : public QObject, public User { void setMute(bool mute); void setDeaf(bool deaf); void setSuppress(bool suppress); + void setLocalIgnore(bool ignore); void setLocalMute(bool mute); void setSelfMute(bool mute); void setSelfDeaf(bool deaf); diff --git a/src/mumble/Database.cpp b/src/mumble/Database.cpp index 8c3854fd2..0624e8eba 100644 --- a/src/mumble/Database.cpp +++ b/src/mumble/Database.cpp @@ -128,6 +128,9 @@ Database::Database() { query.exec(QLatin1String("CREATE UNIQUE INDEX IF NOT EXISTS `friends_name` ON `friends`(`name`)")); query.exec(QLatin1String("CREATE UNIQUE INDEX IF NOT EXISTS `friends_hash` ON `friends`(`hash`)")); + query.exec(QLatin1String("CREATE TABLE IF NOT EXISTS `ignored` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT)")); + query.exec(QLatin1String("CREATE UNIQUE INDEX IF NOT EXISTS `ignored_hash` ON `ignored`(`hash`)")); + query.exec(QLatin1String("CREATE TABLE IF NOT EXISTS `muted` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT)")); query.exec(QLatin1String("CREATE UNIQUE INDEX IF NOT EXISTS `muted_hash` ON `muted`(`hash`)")); @@ -193,6 +196,29 @@ void Database::setFavorites(const QList &servers) { QSqlDatabase::database().commit(); } +bool Database::isLocalIgnored(const QString &hash) { + QSqlQuery query; + + query.prepare(QLatin1String("SELECT `hash` FROM `ignored` WHERE `hash` = ?")); + query.addBindValue(hash); + query.exec(); + while (query.next()) { + return true; + } + return false; +} + +void Database::setLocalIgnored(const QString &hash, bool ignored) { + QSqlQuery query; + + if (ignored) + query.prepare(QLatin1String("INSERT INTO `ignored` (`hash`) VALUES (?)")); + else + query.prepare(QLatin1String("DELETE FROM `ignored` WHERE `hash` = ?")); + query.addBindValue(hash); + query.exec(); +} + bool Database::isLocalMuted(const QString &hash) { QSqlQuery query; diff --git a/src/mumble/Database.h b/src/mumble/Database.h index 357f6a5c1..075258e78 100644 --- a/src/mumble/Database.h +++ b/src/mumble/Database.h @@ -55,6 +55,9 @@ class Database : public QObject { static void setPassword(const QString &host, unsigned short port, const QString &user, const QString &pw); static bool fuzzyMatch(QString &name, QString &user, QString &pw, QString &host, unsigned short port); + static bool isLocalIgnored(const QString &hash); + static void setLocalIgnored(const QString &hash, bool ignored); + static bool isLocalMuted(const QString &hash); static void setLocalMuted(const QString &hash, bool muted); diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp index 8e65be08a..36bb4bba1 100644 --- a/src/mumble/MainWindow.cpp +++ b/src/mumble/MainWindow.cpp @@ -1192,6 +1192,7 @@ void MainWindow::qmUser_aboutToShow() { if (g.sh && g.sh->uiVersion >= 0x010203) qmUser->addAction(qaUserPrioritySpeaker); qmUser->addAction(qaUserLocalMute); + qmUser->addAction(qaUserLocalIgnore); if (self) qmUser->addAction(qaSelfComment); @@ -1247,6 +1248,7 @@ void MainWindow::qmUser_aboutToShow() { qaUserBan->setEnabled(false); qaUserTextMessage->setEnabled(false); qaUserLocalMute->setEnabled(false); + qaUserLocalIgnore->setEnabled(false); qaUserCommentReset->setEnabled(false); qaUserCommentView->setEnabled(false); } else { @@ -1254,6 +1256,7 @@ void MainWindow::qmUser_aboutToShow() { qaUserBan->setEnabled(! self); qaUserTextMessage->setEnabled(true); qaUserLocalMute->setEnabled(! self); + qaUserLocalIgnore->setEnabled(! self); qaUserCommentReset->setEnabled(! p->qbaCommentHash.isEmpty() && (g.pPermissions & (ChanACL::Move | ChanACL::Write))); qaUserCommentView->setEnabled(! p->qbaCommentHash.isEmpty()); @@ -1261,6 +1264,7 @@ void MainWindow::qmUser_aboutToShow() { qaUserDeaf->setChecked(p->bDeaf); qaUserPrioritySpeaker->setChecked(p->bPrioritySpeaker); qaUserLocalMute->setChecked(p->bLocalMute); + qaUserLocalIgnore->setChecked(p->bLocalIgnore); } updateMenuPermissions(); } @@ -1295,6 +1299,18 @@ void MainWindow::on_qaUserLocalMute_triggered() { Database::setLocalMuted(p->qsHash, muted); } +void MainWindow::on_qaUserLocalIgnore_triggered() { + ClientUser *p = getContextMenuUser(); + if (!p) + return; + + bool ignored = qaUserLocalIgnore->isChecked(); + + p->setLocalIgnore(ignored); + if (! p->qsHash.isEmpty()) + Database::setLocalIgnored(p->qsHash, ignored); +} + void MainWindow::on_qaUserDeaf_triggered() { ClientUser *p = getContextMenuUser(); if (!p) @@ -1765,7 +1781,6 @@ void MainWindow::on_qaChannelCopyURL_triggered() { return; g.sh->getConnectionInfo(host, port, uname, pw); - // walk back up the channel list to build the URL. while (c->cParent != NULL) { channel.prepend(c->qsName); diff --git a/src/mumble/MainWindow.h b/src/mumble/MainWindow.h index 4bd18fa37..0769bac47 100644 --- a/src/mumble/MainWindow.h +++ b/src/mumble/MainWindow.h @@ -175,6 +175,7 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin void on_qaUserDeaf_triggered(); void on_qaSelfPrioritySpeaker_triggered(); void on_qaUserPrioritySpeaker_triggered(); + void on_qaUserLocalIgnore_triggered(); void on_qaUserLocalMute_triggered(); void on_qaUserTextMessage_triggered(); void on_qaUserRegister_triggered(); diff --git a/src/mumble/MainWindow.ui b/src/mumble/MainWindow.ui index 6703274be..6c881fabf 100644 --- a/src/mumble/MainWindow.ui +++ b/src/mumble/MainWindow.ui @@ -316,6 +316,20 @@ Deafen or undeafen user on server. Deafening a user will also mute them. + + + true + + + Ignore Messages + + + Locally ignore user's text chat messages. + + + Silently drops all text messages from the user. + + true diff --git a/src/mumble/Messages.cpp b/src/mumble/Messages.cpp index 5fb8ab80d..04766d9e5 100644 --- a/src/mumble/Messages.cpp +++ b/src/mumble/Messages.cpp @@ -262,6 +262,8 @@ void MainWindow::msgUserState(const MumbleProto::UserState &msg) { pmModel->setFriendName(pDst, name); if (Database::isLocalMuted(pDst->qsHash)) pDst->setLocalMute(true); + if (Database::isLocalIgnored(pDst->qsHash)) + pDst->setLocalIgnore(true); } if (bNewUser) @@ -569,6 +571,11 @@ void MainWindow::msgChannelRemove(const MumbleProto::ChannelRemove &msg) { void MainWindow::msgTextMessage(const MumbleProto::TextMessage &msg) { ACTOR_INIT; QString target; + + // Silently drop the message if this user is set to "ignore" + if (pSrc->bLocalIgnore) + return; + const QString &plainName = pSrc ? pSrc->qsName : tr("Server", "message from"); const QString &name = pSrc ? Log::formatClientUser(pSrc, Log::Source) : tr("Server", "message from"); diff --git a/src/mumble/UserModel.cpp b/src/mumble/UserModel.cpp index 2a29c1d9b..24fd31d02 100644 --- a/src/mumble/UserModel.cpp +++ b/src/mumble/UserModel.cpp @@ -220,6 +220,7 @@ UserModel::UserModel(QObject *p) : QAbstractItemModel(p) { qiMutedSelf=QIcon(QLatin1String("skin:muted_self.svg")); qiMutedServer=QIcon(QLatin1String("skin:muted_server.svg")); qiMutedLocal=QIcon(QLatin1String("skin:muted_local.svg")); + qiIgnoredLocal=QIcon(QLatin1String("skin:status/text-missing.svg")); qiMutedSuppressed=QIcon(QLatin1String("skin:muted_suppressed.svg")); qiDeafenedSelf=QIcon(QLatin1String("skin:deafened_self.svg")); qiDeafenedServer=QIcon(QLatin1String("skin:deafened_server.svg")); @@ -408,6 +409,8 @@ QVariant UserModel::data(const QModelIndex &idx, int role) const { l << qiMutedSelf; if (p->bLocalMute) l << qiMutedLocal; + if (p->bLocalIgnore) + l << qiIgnoredLocal; if (p->bDeaf) l << qiDeafenedServer; if (p->bSelfDeaf) @@ -611,13 +614,15 @@ QVariant UserModel::otherRoles(const QModelIndex &idx, int role) const { "%9" "%10" "%11" + "%12" "").arg(tr("This shows the flags the user has on the server, if any:"), tr("On your friend list"), tr("Authenticated user"), tr("Muted (manually muted by self)"), tr("Muted (manually muted by admin)"), tr("Muted (not allowed to speak in current channel)"), - tr("Muted (muted by you, only on your machine)") + tr("Muted (muted by you, only on your machine)"), + tr("Ignoring Text Messages") ).arg( tr("Deafened (by self)"), tr("Deafened (by admin)"), diff --git a/src/mumble/UserModel.h b/src/mumble/UserModel.h index 09429fc41..9310535b0 100644 --- a/src/mumble/UserModel.h +++ b/src/mumble/UserModel.h @@ -84,7 +84,7 @@ class UserModel : public QAbstractItemModel { Q_DISABLE_COPY(UserModel) protected: QIcon qiTalkingOn, qiTalkingWhisper, qiTalkingShout, qiTalkingOff; - QIcon qiMutedSelf, qiMutedServer, qiMutedLocal, qiMutedSuppressed; + QIcon qiMutedSelf, qiMutedServer, qiMutedLocal, qiIgnoredLocal, qiMutedSuppressed; QIcon qiPrioritySpeaker; QIcon qiRecording; QIcon qiDeafenedSelf, qiDeafenedServer; diff --git a/src/mumble/mumble_tango.qrc b/src/mumble/mumble_tango.qrc index 7fd06e770..d00edc2e5 100644 --- a/src/mumble/mumble_tango.qrc +++ b/src/mumble/mumble_tango.qrc @@ -15,5 +15,6 @@ ../../icons/tango/places/network-workgroup.svg ../../icons/tango/mimetypes/image-x-generic.svg ../../icons/tango/mimetypes/text-html.svg + ../../icons/tango/status/text-missing.svg