diff options
author | Robert Adam <dev@robert-adam.de> | 2022-09-09 14:00:01 +0300 |
---|---|---|
committer | Robert Adam <dev@robert-adam.de> | 2022-09-09 14:03:49 +0300 |
commit | 62f087fb3acf697c00245063ed297ee942217bfc (patch) | |
tree | 22c578c4a62c64ff75a4295fd2495505979fde56 /src/mumble | |
parent | a8b98487d49f536097eb248dd8a2d02c06cba155 (diff) |
FEAT(client): Add shortcut to listen to a channel
This introduces a new global shortcut that can be used to start or stop
listening to a configured channel.
Fixes #4486
Co-Authored-By: timjwkim <timjwkim@umich.edu>
Diffstat (limited to 'src/mumble')
-rw-r--r-- | src/mumble/GlobalShortcut.cpp | 38 | ||||
-rw-r--r-- | src/mumble/GlobalShortcut.h | 13 | ||||
-rw-r--r-- | src/mumble/GlobalShortcutTypes.h | 1 | ||||
-rw-r--r-- | src/mumble/MainWindow.cpp | 19 | ||||
-rw-r--r-- | src/mumble/MainWindow.h | 3 | ||||
-rw-r--r-- | src/mumble/Settings.cpp | 25 | ||||
-rw-r--r-- | src/mumble/Settings.h | 15 |
7 files changed, 113 insertions, 1 deletions
diff --git a/src/mumble/GlobalShortcut.cpp b/src/mumble/GlobalShortcut.cpp index 04bbe4f91..e6f849f18 100644 --- a/src/mumble/GlobalShortcut.cpp +++ b/src/mumble/GlobalShortcut.cpp @@ -26,6 +26,8 @@ # include <QtCore/QOperatingSystemVersion> #endif +#include <cassert> + const QString GlobalShortcutConfig::name = QLatin1String("GlobalShortcutConfig"); /** @@ -104,6 +106,31 @@ int ShortcutToggleWidget::index() const { return itemData(currentIndex()).toInt(); } +ChannelSelectWidget::ChannelSelectWidget(QWidget *parent) : MUComboBox(parent) { + QReadLocker lock(&Channel::c_qrwlChannels); + + int index = 0; + + for (const Channel *currentChannel : Channel::c_qhChannels) { + assert(currentChannel); + + insertItem(index, currentChannel->qsName); + setItemData(index, currentChannel->iId); + + index++; + } + + model()->sort(0); +} + +void ChannelSelectWidget::setCurrentChannel(const ChannelTarget &target) { + setCurrentIndex(findData(target.channelID)); +} + +ChannelTarget ChannelSelectWidget::currentChannel() const { + return itemData(currentIndex()).toInt(); +} + void iterateChannelChildren(QTreeWidgetItem *root, Channel *chan, QMap< int, QTreeWidgetItem * > &map) { foreach (Channel *c, chan->qlChannels) { QTreeWidgetItem *sub = new QTreeWidgetItem(root, QStringList(c->qsName)); @@ -432,6 +459,8 @@ ShortcutDelegate::ShortcutDelegate(QObject *p) : QStyledItemDelegate(p) { factory->registerEditor(QVariant::Int, new QStandardItemEditorCreator< ShortcutToggleWidget >()); factory->registerEditor(static_cast< QVariant::Type >(QVariant::fromValue(ShortcutTarget()).userType()), new QStandardItemEditorCreator< ShortcutTargetWidget >()); + factory->registerEditor(static_cast< QVariant::Type >(QVariant::fromValue(ChannelTarget()).userType()), + new QStandardItemEditorCreator< ChannelSelectWidget >()); factory->registerEditor(QVariant::String, new QStandardItemEditorCreator< QLineEdit >()); factory->registerEditor(QVariant::Invalid, new QStandardItemEditorCreator< QWidget >()); setItemEditorFactory(factory); @@ -448,6 +477,15 @@ ShortcutDelegate::~ShortcutDelegate() { QString ShortcutDelegate::displayText(const QVariant &item, const QLocale &loc) const { if (item.userType() == QVariant::fromValue(ShortcutTarget()).userType()) { return ShortcutTargetWidget::targetString(item.value< ShortcutTarget >()); + } else if (item.userType() == QVariant::fromValue(ChannelTarget()).userType()) { + ChannelTarget target = item.value< ChannelTarget >(); + + const Channel *c = Channel::get(target.channelID); + if (c) { + return c->qsName; + } else { + return tr("< Unknown Channel >"); + } } switch (item.type()) { diff --git a/src/mumble/GlobalShortcut.h b/src/mumble/GlobalShortcut.h index aad5e89f0..9ba689719 100644 --- a/src/mumble/GlobalShortcut.h +++ b/src/mumble/GlobalShortcut.h @@ -11,6 +11,7 @@ #include <QtWidgets/QStyledItemDelegate> #include <QtWidgets/QToolButton> +#include "Channel.h" #include "ConfigDialog.h" #include "MUComboBox.h" #include "Timer.h" @@ -72,6 +73,17 @@ public: void setIndex(int); }; +class ChannelSelectWidget : public MUComboBox { + Q_OBJECT + Q_DISABLE_COPY(ChannelSelectWidget) + Q_PROPERTY(ChannelTarget currentChannel READ currentChannel WRITE setCurrentChannel USER true) +public: + ChannelSelectWidget(QWidget *parent = nullptr); + + ChannelTarget currentChannel() const; + void setCurrentChannel(const ChannelTarget &); +}; + /** * Dialog which is used to select the targets of a targeted shortcut like Whisper. */ @@ -136,6 +148,7 @@ public slots: * @see ShortcutKeyWidget * @see ShortcutActionWidget * @see ShortcutTargetWidget + * @see ChannelSelectWidget */ class ShortcutDelegate : public QStyledItemDelegate { Q_OBJECT diff --git a/src/mumble/GlobalShortcutTypes.h b/src/mumble/GlobalShortcutTypes.h index 6fb54400d..6fbf49eb0 100644 --- a/src/mumble/GlobalShortcutTypes.h +++ b/src/mumble/GlobalShortcutTypes.h @@ -36,6 +36,7 @@ enum Type { SendTextMessageClipboard, ToggleTalkingUI, ToggleSearch, + ListenToChannel, }; // A few assertions meant to catch, if anyone inserts a new value in-between instead of appending diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp index f9c42c63d..1774c74c2 100644 --- a/src/mumble/MainWindow.cpp +++ b/src/mumble/MainWindow.cpp @@ -239,6 +239,12 @@ void MainWindow::createActions() { gsJoinChannel->setObjectName(QLatin1String("MetaChannel")); gsJoinChannel->qsToolTip = tr("Use in conjunction with Whisper to.", "Global Shortcut"); + gsListenChannel = + new GlobalShortcut(this, GlobalShortcutType::ListenToChannel, tr("Listen to Channel", "Global Shortcut"), + QVariant::fromValue(ChannelTarget())); + gsListenChannel->setObjectName(QLatin1String("gsListenChannel")); + gsListenChannel->qsToolTip = tr("Toggles listening to the given channel.", "Global Shortcut"); + #ifdef USE_OVERLAY gsToggleOverlay = new GlobalShortcut(this, GlobalShortcutType::ToggleOverlay, tr("Toggle Overlay", "Global Shortcut")); @@ -3101,6 +3107,19 @@ void MainWindow::on_gsToggleMainWindowVisibility_triggered(bool down, QVariant) } } +void MainWindow::on_gsListenChannel_triggered(bool down, QVariant scdata) { + ChannelTarget target = scdata.value< ChannelTarget >(); + const Channel *c = Channel::get(target.channelID); + + if (down && c) { + if (!Global::get().channelListenerManager->isListening(Global::get().uiSession, c->iId)) { + Global::get().sh->startListeningToChannel(c->iId); + } else { + Global::get().sh->stopListeningToChannel(c->iId); + } + } +} + void MainWindow::on_gsTransmitModePushToTalk_triggered(bool down, QVariant) { if (down) { setTransmissionMode(Settings::PushToTalk); diff --git a/src/mumble/MainWindow.h b/src/mumble/MainWindow.h index fde90c5ef..880b33239 100644 --- a/src/mumble/MainWindow.h +++ b/src/mumble/MainWindow.h @@ -93,7 +93,7 @@ public: #ifdef USE_OVERLAY GlobalShortcut *gsToggleOverlay; #endif - GlobalShortcut *gsMinimal, *gsVolumeUp, *gsVolumeDown, *gsWhisper, *gsLinkChannel; + GlobalShortcut *gsMinimal, *gsVolumeUp, *gsVolumeDown, *gsWhisper, *gsLinkChannel, *gsListenChannel; GlobalShortcut *gsCycleTransmitMode, *gsToggleMainWindowVisibility, *gsTransmitModePushToTalk, *gsTransmitModeContinuous, *gsTransmitModeVAD; GlobalShortcut *gsSendTextMessage, *gsSendClipboardTextMessage; @@ -296,6 +296,7 @@ public slots: void on_gsWhisper_triggered(bool, QVariant); void addTarget(ShortcutTarget *); void removeTarget(ShortcutTarget *); + void on_gsListenChannel_triggered(bool, QVariant); void on_gsCycleTransmitMode_triggered(bool, QVariant); void on_gsToggleMainWindowVisibility_triggered(bool, QVariant); void on_gsTransmitModePushToTalk_triggered(bool, QVariant); diff --git a/src/mumble/Settings.cpp b/src/mumble/Settings.cpp index 09b5aff75..15e7e7a90 100644 --- a/src/mumble/Settings.cpp +++ b/src/mumble/Settings.cpp @@ -59,6 +59,9 @@ bool Shortcut::isServerSpecific() const { const ShortcutTarget &sc = qvariant_cast< ShortcutTarget >(qvData); return sc.isServerSpecific(); } + if (qvData.canConvert< ChannelTarget >()) { + return true; + } return false; } @@ -378,6 +381,26 @@ QDataStream &operator>>(QDataStream &qds, ShortcutTarget &st) { } } +QDataStream &operator<<(QDataStream &qds, const ChannelTarget &target) { + return qds << target.channelID; +} + +QDataStream &operator>>(QDataStream &qds, ChannelTarget &target) { + return qds >> target.channelID; +} + +bool operator==(const ChannelTarget &lhs, const ChannelTarget &rhs) { + return lhs.channelID == rhs.channelID; +} + +bool operator<(const ChannelTarget &lhs, const ChannelTarget &rhs) { + return lhs.channelID < rhs.channelID; +} + +quint32 qHash(const ChannelTarget &target) { + return qHash(target.channelID); +} + const QString Settings::cqsDefaultPushClickOn = QLatin1String(":/on.ogg"); const QString Settings::cqsDefaultPushClickOff = QLatin1String(":/off.ogg"); @@ -492,6 +515,8 @@ Settings::Settings() { #endif qRegisterMetaType< ShortcutTarget >("ShortcutTarget"); qRegisterMetaTypeStreamOperators< ShortcutTarget >("ShortcutTarget"); + qRegisterMetaType< ChannelTarget >("ChannelTarget"); + qRegisterMetaTypeStreamOperators< ChannelTarget >("ChannelTarget"); qRegisterMetaType< QVariant >("QVariant"); qRegisterMetaType< PluginSetting >("PluginSetting"); qRegisterMetaTypeStreamOperators< PluginSetting >("PluginSetting"); diff --git a/src/mumble/Settings.h b/src/mumble/Settings.h index 6d37b77fb..6d5a4ee4b 100644 --- a/src/mumble/Settings.h +++ b/src/mumble/Settings.h @@ -23,6 +23,7 @@ #include <QVariant> #include <Qt> +#include "Channel.h" #include "EchoCancelOption.h" #include "SSL.h" #include "SearchDialog.h" @@ -52,6 +53,20 @@ struct Shortcut { bool operator==(const Shortcut &) const; }; +struct ChannelTarget { + int channelID = Channel::ROOT_ID; + + ChannelTarget() = default; + ChannelTarget(int id) : channelID(id) {} + + friend bool operator==(const ChannelTarget &lhs, const ChannelTarget &rhs); + friend bool operator<(const ChannelTarget &lhs, const ChannelTarget &rhs); +}; + +Q_DECLARE_METATYPE(ChannelTarget) + +quint32 qHash(const ChannelTarget &); + struct ShortcutTarget { bool bCurrentSelection = false; bool bUsers = true; |