diff --git a/src/mumble/ListenerVolumeSlider.cpp b/src/mumble/ListenerVolumeSlider.cpp index 6db5a8fdd3e..031b35f1731 100644 --- a/src/mumble/ListenerVolumeSlider.cpp +++ b/src/mumble/ListenerVolumeSlider.cpp @@ -62,6 +62,8 @@ void ListenerVolumeSlider::on_VolumeSlider_changeCompleted() { Global::get().channelListenerManager->setListenerVolumeAdjustment(Global::get().uiSession, m_channel->iId, adjustment); } + + emit dbAdjustmentChanged(adjustment.dbAdjustment); } void ListenerVolumeSlider::sendToServer() { diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp index 6d5fa95fca7..23040a22da6 100644 --- a/src/mumble/MainWindow.cpp +++ b/src/mumble/MainWindow.cpp @@ -67,6 +67,7 @@ #endif #include +#include #include #include #include @@ -199,6 +200,20 @@ MainWindow::MainWindow(QWidget *p) QObject::connect(this, &MainWindow::serverSynchronized, Global::get().pluginManager, &PluginManager::on_serverSynchronized); + // Sadly, QWidgetActions have a poor accessibility as of Qt 5.15.10 + // The slider value will not be read under any circumstances, so we use the label + // above it to communicate that to the user. + // This is not pretty, but it seems to be the only option, if we want to keep + // the inline slider... + connect(m_userLocalVolumeSlider.get(), &VolumeSliderWidgetAction::dbAdjustmentChanged, this, + &MainWindow::on_volumeSlider_dbAdjustmentChanged, Qt::DirectConnection); + connect(m_listenerVolumeSlider.get(), &VolumeSliderWidgetAction::dbAdjustmentChanged, this, + &MainWindow::on_volumeSlider_dbAdjustmentChanged, Qt::DirectConnection); + on_volumeSlider_dbAdjustmentChanged(0); + m_localVolumeLabel->setAccessibleDescription( + tr("The next element in this menu is a slider to adjust the volume of the selected client. " + "Every tick increases or decreases the local volume by 1 decibel in real time.")); + QAccessible::installFactory(AccessibleSlider::semanticSliderFactory); } @@ -3858,6 +3873,38 @@ void MainWindow::on_qteLog_highlighted(const QUrl &url) { } } +void MainWindow::on_volumeSlider_dbAdjustmentChanged(int value) { + QString newText = QString("%1: (%2%3 dB)"); + newText = newText.arg(tr("Local Volume Adjustment")).arg(value > 0 ? QString("+") : QString("")).arg(value); + + if (newText == m_localVolumeLabel->text()) { + return; + } + + m_localVolumeLabel->setText(newText); + + QString newName = QString("%1 %2%3 %4"); + newName = newName.arg(tr("Local Volume Adjustment")).arg(value > 0 ? QString("+") : QString("")).arg(value).arg(tr("decibels")); + m_localVolumeLabel->setAccessibleName(newName); + + QSize new_size(qmUser->size().width() + 10, qmUser->size().height() + 10); + QResizeEvent event(new_size, qmUser->size()); + qApp->sendEvent(qmUser, &event); + + qmUser->update(); + qmUser->repaint(); + qApp->processEvents(); + /* + qmUser->blockSignals(true); + qmUser->show(); + qApp->processEvents(); + qmUser->hide(); + qApp->processEvents(); + qmUser->show(); + qmUser->blockSignals(false); + */ +} + void MainWindow::context_triggered() { QAction *a = qobject_cast< QAction * >(sender()); diff --git a/src/mumble/MainWindow.h b/src/mumble/MainWindow.h index 18f160d48e3..7401cac6e8d 100644 --- a/src/mumble/MainWindow.h +++ b/src/mumble/MainWindow.h @@ -299,6 +299,7 @@ public slots: void on_qteLog_customContextMenuRequested(const QPoint &pos); void on_qteLog_anchorClicked(const QUrl &); void on_qteLog_highlighted(const QUrl &link); + void on_volumeSlider_dbAdjustmentChanged(int value); void on_PushToTalk_triggered(bool, QVariant); void on_PushToMute_triggered(bool, QVariant); void on_VolumeUp_triggered(bool, QVariant); diff --git a/src/mumble/MenuLabel.cpp b/src/mumble/MenuLabel.cpp index 1655a5f5156..606fdefac94 100644 --- a/src/mumble/MenuLabel.cpp +++ b/src/mumble/MenuLabel.cpp @@ -6,8 +6,10 @@ #include "MenuLabel.h" #include +#include -MenuLabel::MenuLabel(const QString &text, QObject *parent) : QWidgetAction(parent), m_text(text) { +MenuLabel::MenuLabel(const QString &text, QObject *parent) + : QWidgetAction(parent), m_text(text), m_accessibleName(""), m_accessibleDescription("") { setMenuRole(QAction::NoRole); } @@ -15,5 +17,43 @@ QWidget *MenuLabel::createWidget(QWidget *parent) { QLabel *label = new QLabel(m_text, parent); label->setFocusPolicy(Qt::TabFocus); + label->setAccessibleName(m_accessibleName); + label->setAccessibleDescription(m_accessibleDescription); + return label; } + +QString MenuLabel::text() { + return m_text; +} + +void MenuLabel::setText(const QString &text) { + m_text = text; + + QLabel *label = qobject_cast< QLabel * >(defaultWidget()); + if (label) { + label->setText(text); + label->update(); + } +} + +void MenuLabel::setAccessibleName(const QString &name) { + m_accessibleName = name; + + QLabel *label = qobject_cast< QLabel * >(defaultWidget()); + if (label) { + label->setAccessibleName(m_accessibleName); + label->update(); + qDebug() << "Set to " << m_accessibleName; + } +} + +void MenuLabel::setAccessibleDescription(const QString &description) { + m_accessibleDescription = description; + + QLabel *label = qobject_cast< QLabel * >(defaultWidget()); + if (label) { + label->setAccessibleDescription(m_accessibleDescription); + label->update(); + } +} diff --git a/src/mumble/MenuLabel.h b/src/mumble/MenuLabel.h index 22aa6225659..a6803ea3d9c 100644 --- a/src/mumble/MenuLabel.h +++ b/src/mumble/MenuLabel.h @@ -17,11 +17,18 @@ class MenuLabel : public QWidgetAction { public: MenuLabel(const QString &text, QObject *parent = nullptr); + QString text(); + void setText(const QString &name); + void setAccessibleName(const QString &name); + void setAccessibleDescription(const QString &description); + protected: QWidget *createWidget(QWidget *parent) override; private: - const QString m_text; + QString m_text; + QString m_accessibleName; + QString m_accessibleDescription; }; #endif diff --git a/src/mumble/UserLocalVolumeSlider.cpp b/src/mumble/UserLocalVolumeSlider.cpp index ea3f23fa4a3..fa28a27733e 100644 --- a/src/mumble/UserLocalVolumeSlider.cpp +++ b/src/mumble/UserLocalVolumeSlider.cpp @@ -43,5 +43,7 @@ void UserLocalVolumeSlider::on_VolumeSlider_changeCompleted() { } else { Global::get().mw->logChangeNotPermanent(QObject::tr("Local Volume Adjustment..."), user); } + + emit dbAdjustmentChanged(VolumeAdjustment::toDBAdjustment(user->getLocalVolumeAdjustments())); } } diff --git a/src/mumble/VolumeSliderWidgetAction.cpp b/src/mumble/VolumeSliderWidgetAction.cpp index 7553ae68b9f..fcd6007412c 100644 --- a/src/mumble/VolumeSliderWidgetAction.cpp +++ b/src/mumble/VolumeSliderWidgetAction.cpp @@ -10,16 +10,22 @@ #include #include +#include +#include VolumeSliderWidgetAction::VolumeSliderWidgetAction(QWidget *parent) - : QWidgetAction(parent), m_volumeSlider(make_qt_unique< QSlider >(Qt::Horizontal, parent)) { + : QWidgetAction(parent), + m_widget(make_qt_unique< QWidget >(parent)), + m_volumeSlider(new QSlider(Qt::Horizontal, parent)), + m_label(new QLabel("0 db", parent)) { + m_volumeSlider->setMinimum(-30); m_volumeSlider->setMaximum(30); m_volumeSlider->setAccessibleName(tr("Slider for volume adjustment")); m_volumeSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); KeyEventObserver *keyEventFilter = new KeyEventObserver(this, QEvent::KeyRelease, false, - { Qt::Key_Left, Qt::Key_Right, Qt::Key_Up, Qt::Key_Down }); + { Qt::Key_Left, Qt::Key_Right }); m_volumeSlider->installEventFilter(keyEventFilter); // The list of wheel events observed seems odd at first. We have to check for multiple @@ -33,27 +39,34 @@ VolumeSliderWidgetAction::VolumeSliderWidgetAction(QWidget *parent) new MouseWheelEventObserver(this, { Qt::ScrollMomentum, Qt::ScrollUpdate, Qt::ScrollEnd }, false); m_volumeSlider->installEventFilter(wheelEventFilter); - connect(m_volumeSlider.get(), &QSlider::valueChanged, this, + connect(m_volumeSlider, &QSlider::valueChanged, this, &VolumeSliderWidgetAction::on_VolumeSlider_valueChanged); - connect(m_volumeSlider.get(), &QSlider::sliderReleased, this, + connect(m_volumeSlider, &QSlider::sliderReleased, this, &VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted); connect(keyEventFilter, &KeyEventObserver::keyEventObserved, this, &VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted); connect(wheelEventFilter, &MouseWheelEventObserver::wheelEventObserved, this, &VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted); - setDefaultWidget(m_volumeSlider.get()); - UpDownKeyEventFilter *eventFilter = new UpDownKeyEventFilter(this); m_volumeSlider->installEventFilter(eventFilter); m_volumeSlider->setProperty("mouseTracking", true); + + QHBoxLayout *layout = new QHBoxLayout(); + layout->addWidget(m_volumeSlider); + layout->addWidget(m_label); + m_widget->setLayout(layout); + + setDefaultWidget(m_widget.get()); } void VolumeSliderWidgetAction::updateSliderValue(float value) { int dbShift = VolumeAdjustment::toIntegerDBAdjustment(value); m_volumeSlider->setValue(dbShift); updateTooltip(dbShift); + + emit dbAdjustmentChanged(dbShift); } void VolumeSliderWidgetAction::updateTooltip(int value) { diff --git a/src/mumble/VolumeSliderWidgetAction.h b/src/mumble/VolumeSliderWidgetAction.h index 25bb408670f..e15c10692e3 100644 --- a/src/mumble/VolumeSliderWidgetAction.h +++ b/src/mumble/VolumeSliderWidgetAction.h @@ -11,6 +11,8 @@ #include "QtUtils.h" class QSlider; +class QHBoxLayout; +class QLabel; class VolumeSliderWidgetAction : public QWidgetAction { Q_OBJECT @@ -19,12 +21,17 @@ class VolumeSliderWidgetAction : public QWidgetAction { VolumeSliderWidgetAction(QWidget *parent = nullptr); protected: - qt_unique_ptr< QSlider > m_volumeSlider; + qt_unique_ptr< QWidget > m_widget; + QSlider* m_volumeSlider; + QLabel* m_label; void updateSliderValue(float value); void displayTooltip(int value); void updateTooltip(int value); +signals: + void dbAdjustmentChanged(int value); + protected slots: virtual void on_VolumeSlider_valueChanged(int){}; virtual void on_VolumeSlider_changeCompleted(){};