218 lines
5.9 KiB
C++
218 lines
5.9 KiB
C++
// Copyright 2024 The Mumble Developers. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license
|
|
// that can be found in the LICENSE file at the root of the
|
|
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
|
|
|
|
#include "Accessibility.h"
|
|
#include "ChannelFilterMode.h"
|
|
#include "Global.h"
|
|
|
|
#include <QAbstractButton>
|
|
#include <QAccessible>
|
|
#include <QAccessibleEvent>
|
|
#include <QObject>
|
|
#include <QWidget>
|
|
|
|
#include <queue>
|
|
|
|
namespace Mumble {
|
|
namespace Accessibility {
|
|
|
|
QString removeHTMLTags(QString value) { return value.remove(QRegExp("<[^>]*>")); }
|
|
|
|
void setDescriptionFromLabel(QWidget *widget, const QLabel *label) {
|
|
widget->setAccessibleDescription(removeHTMLTags(label->text()));
|
|
}
|
|
|
|
void fixWizardButtonLabels(QWizard *wizard) {
|
|
wizard->button(QWizard::NextButton)->setAccessibleName(QObject::tr("Next"));
|
|
wizard->button(QWizard::BackButton)->setAccessibleName(QObject::tr("Back"));
|
|
}
|
|
|
|
QString userToText(const ClientUser *user) {
|
|
if (Global::get().uiSession != 0) {
|
|
const ClientUser *self = ClientUser::get(Global::get().uiSession);
|
|
if (self == user) {
|
|
return QString("%1, %2").arg(QObject::tr("This is you")).arg(user->qsName);
|
|
}
|
|
}
|
|
|
|
QString name;
|
|
QString prefix;
|
|
|
|
if (!user->qsFriendName.isEmpty()) {
|
|
prefix = QObject::tr("friend");
|
|
name = user->qsFriendName;
|
|
} else if (!user->getLocalNickname().isEmpty()) {
|
|
prefix = QObject::tr("user");
|
|
name = user->getLocalNickname();
|
|
} else {
|
|
prefix = QObject::tr("user");
|
|
name = user->qsName;
|
|
}
|
|
|
|
return QString("%1 %2").arg(prefix).arg(name);
|
|
}
|
|
|
|
QString userToDescription(const ClientUser *user) {
|
|
QString description;
|
|
|
|
if (user->bMute || user->bSuppress || user->bSelfMute) {
|
|
if (user->bDeaf || user->bSelfDeaf) {
|
|
description = QString("%1 %2,").arg(QObject::tr("status")).arg(QObject::tr("muted and deafened"));
|
|
} else {
|
|
description = QString("%1 %2,").arg(QObject::tr("status")).arg(QObject::tr("muted"));
|
|
}
|
|
} else if (user->bLocalMute) {
|
|
description = QString("%1 %2,").arg(QObject::tr("status")).arg(QObject::tr("locally muted"));
|
|
} else {
|
|
description = QString("%1 %2,").arg(QObject::tr("status")).arg(QObject::tr("unmuted"));
|
|
}
|
|
|
|
if (user->bRecording) {
|
|
description += QString("%1,").arg(QObject::tr("recording"));
|
|
}
|
|
|
|
if (user->bPrioritySpeaker) {
|
|
description += QString("%1,").arg(QObject::tr("priority speaker"));
|
|
}
|
|
|
|
if (!user->qsComment.isEmpty()) {
|
|
if (user->qsComment.length() <= 20) {
|
|
description += QString("%1,").arg(user->qsComment);
|
|
} else {
|
|
description += QString("%1,").arg(QObject::tr("has a long comment"));
|
|
}
|
|
}
|
|
|
|
if (user->bLocalIgnore) {
|
|
description += QString("%1,").arg(QObject::tr("text messages ignored"));
|
|
}
|
|
|
|
if (user->iId >= 0) {
|
|
description += QString("%1,").arg(QObject::tr("registered"));
|
|
}
|
|
|
|
return description;
|
|
}
|
|
|
|
QString channelToText(const Channel *channel) {
|
|
return QString("%1 %2").arg(QObject::tr("channel")).arg(channel->qsName);
|
|
}
|
|
|
|
QString channelToDescription(const Channel *channel) {
|
|
QString description;
|
|
bool selfChannel = false;
|
|
|
|
if (Global::get().uiSession != 0) {
|
|
const ClientUser *self = ClientUser::get(Global::get().uiSession);
|
|
if (self->cChannel == channel) {
|
|
selfChannel = true;
|
|
}
|
|
}
|
|
|
|
if (selfChannel) {
|
|
description = QString("%1 %2,").arg(QObject::tr("status")).arg(QObject::tr("your channel"));
|
|
} else if (channel->hasEnterRestrictions.load()) {
|
|
if (channel->localUserCanEnter.load()) {
|
|
description = QString("%1 %2,").arg(QObject::tr("status")).arg(QObject::tr("accessible"));
|
|
} else {
|
|
description = QString("%1 %2,").arg(QObject::tr("status")).arg(QObject::tr("inaccessible"));
|
|
}
|
|
} else {
|
|
description = QString("%1 %2,").arg(QObject::tr("status")).arg(QObject::tr("public"));
|
|
}
|
|
|
|
switch (channel->m_filterMode) {
|
|
case ChannelFilterMode::HIDE:
|
|
description += QString("%1,").arg(QObject::tr("filtered"));
|
|
break;
|
|
case ChannelFilterMode::PIN:
|
|
description += QString("%1,").arg(QObject::tr("pinned"));
|
|
break;
|
|
case ChannelFilterMode::NORMAL:
|
|
// NOOP
|
|
break;
|
|
}
|
|
|
|
if (!channel->qsDesc.isEmpty()) {
|
|
description += QString(": %1").arg(channel->qsDesc);
|
|
}
|
|
|
|
return description;
|
|
}
|
|
|
|
void setSliderSemanticValue(SemanticSlider *slider, QString value) {
|
|
slider->m_semanticValue = value;
|
|
|
|
QAccessibleEvent nameEvent(slider, QAccessible::NameChanged);
|
|
QAccessible::updateAccessibility(&nameEvent);
|
|
}
|
|
|
|
void setSliderSemanticValue(SemanticSlider *slider, SliderMode mode, QString suffix) {
|
|
QString description = QString("%1 %2");
|
|
|
|
switch (mode) {
|
|
case SliderMode::NONE:
|
|
description = description.arg("");
|
|
break;
|
|
case SliderMode::READ_RELATIVE:
|
|
description = description.arg(
|
|
QString::number(slider->value() / static_cast< double >(slider->maximum()), 'f', 2));
|
|
break;
|
|
case SliderMode::READ_PERCENT:
|
|
description = description.arg(
|
|
static_cast< int32_t >((slider->value() / static_cast< double >(slider->maximum())) * 100));
|
|
break;
|
|
case SliderMode::READ_ABSOLUTE:
|
|
description = description.arg(slider->value());
|
|
break;
|
|
}
|
|
description = description.arg(suffix);
|
|
|
|
setSliderSemanticValue(slider, description);
|
|
}
|
|
|
|
QWidget *getFirstFocusableChild(QObject *object) {
|
|
std::queue< QObject * > search;
|
|
search.push(object);
|
|
|
|
QWidget *selectedWidget = nullptr;
|
|
|
|
while (!search.empty()) {
|
|
QObject *o = search.front();
|
|
search.pop();
|
|
|
|
for (QObject *child : o->children()) {
|
|
search.push(child);
|
|
}
|
|
|
|
selectedWidget = qobject_cast< QWidget * >(o);
|
|
if (!selectedWidget) {
|
|
continue;
|
|
}
|
|
|
|
if (!selectedWidget->isEnabled()) {
|
|
selectedWidget = nullptr;
|
|
continue;
|
|
}
|
|
|
|
if (selectedWidget->focusPolicy() == Qt::NoFocus) {
|
|
selectedWidget = nullptr;
|
|
continue;
|
|
}
|
|
|
|
if (qobject_cast< QLabel * >(selectedWidget)) {
|
|
selectedWidget = nullptr;
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return selectedWidget;
|
|
}
|
|
|
|
} // namespace Accessibility
|
|
} // namespace Mumble
|