Commit 69aa9861 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Improve accessibility of decryption result overview and details

* Add HtmlLabel which
  * sends a text selection event to the accessibility clients when
    a link is selected,
  * allows setting the color to use for links when rendering HTML
* Use HtmlLabel instead of QLabel for the decryption result overview
  and the decryption result details

GnuPG-bug-id: 5535
parent a40973a6
Pipeline #79029 passed with stage
in 15 minutes and 18 seconds
......@@ -111,6 +111,7 @@ set(_kleopatra_SRCS
${_kleopatra_extra_SRCS}
view/htmllabel.cpp
view/keylistcontroller.cpp
view/keytreeview.cpp
view/searchbar.cpp
......
......@@ -11,6 +11,7 @@
#include "accessiblewidgetfactory.h"
#include "accessiblerichtextlabel_p.h"
#include "view/htmllabel.h"
#include "view/urllabel.h"
QAccessibleInterface *Kleo::accessibleWidgetFactory(const QString &classname, QObject *object)
......@@ -20,7 +21,9 @@ QAccessibleInterface *Kleo::accessibleWidgetFactory(const QString &classname, QO
return iface;
QWidget *widget = static_cast<QWidget*>(object);
if (classname == QString::fromLatin1(Kleo::UrlLabel::staticMetaObject.className())) {
if (classname == QString::fromLatin1(Kleo::HtmlLabel::staticMetaObject.className())
|| classname == QString::fromLatin1(Kleo::UrlLabel::staticMetaObject.className())) {
iface = new AccessibleRichTextLabel{widget};
}
......
......@@ -19,6 +19,7 @@
#include "commands/importcertificatefromfilecommand.h"
#include "commands/lookupcertificatescommand.h"
#include "crypto/decryptverifytask.h"
#include "view/htmllabel.h"
#include "view/urllabel.h"
#include <Libkleo/MessageBox>
......@@ -95,7 +96,6 @@ public:
void oneImportFinished();
const std::shared_ptr<const Task::Result> m_result;
QLabel *m_detailsLabel = nullptr;
UrlLabel *m_auditLogLabel = nullptr;
QPushButton *m_closeButton = nullptr;
bool m_importCanceled = false;
......@@ -236,6 +236,7 @@ ResultItemWidget::ResultItemWidget(const std::shared_ptr<const Task::Result> &re
{
const QColor color = colorForVisualCode(d->m_result->code());
const QColor txtColor = txtColorForVisualCode(d->m_result->code());
const QColor linkColor = txtColor;
const QString styleSheet = QStringLiteral("QFrame,QLabel { background-color: %1; margin: 0px; }"
"QFrame#resultFrame{ border-color: %2; border-style: solid; border-radius: 3px; border-width: 1px }"
"QLabel { color: %3; padding: 5px; border-radius: 3px }").arg(color.name()).arg(color.darker(150).name()).arg(txtColor.name());
......@@ -246,21 +247,19 @@ ResultItemWidget::ResultItemWidget(const std::shared_ptr<const Task::Result> &re
topLayout->addWidget(frame);
auto layout = new QHBoxLayout(frame);
auto vlay = new QVBoxLayout();
auto overview = new QLabel;
auto overview = new HtmlLabel;
overview->setWordWrap(true);
overview->setTextFormat(Qt::RichText);
overview->setText(d->m_result->overview());
overview->setFocusPolicy(Qt::StrongFocus);
overview->setHtml(d->m_result->overview());
overview->setStyleSheet(styleSheet);
overview->setLinkColor(linkColor);
setFocusPolicy(overview->focusPolicy());
setFocusProxy(overview);
connect(overview, SIGNAL(linkActivated(QString)), this, SLOT(slotLinkActivated(QString)));
connect(overview, &QLabel::linkActivated,
this, [this](const auto &link) { d->slotLinkActivated(link); });
vlay->addWidget(overview);
layout->addLayout(vlay);
const QString details = d->m_result->details();
auto actionLayout = new QVBoxLayout;
layout->addLayout(actionLayout);
......@@ -271,22 +270,20 @@ ResultItemWidget::ResultItemWidget(const std::shared_ptr<const Task::Result> &re
d->addIgnoreMDCButton(actionLayout);
d->m_auditLogLabel = new UrlLabel;
connect(d->m_auditLogLabel, &UrlLabel::linkActivated,
connect(d->m_auditLogLabel, &QLabel::linkActivated,
this, [this](const auto &link) { d->slotLinkActivated(link); });
actionLayout->addWidget(d->m_auditLogLabel);
d->m_auditLogLabel->setStyleSheet(styleSheet);
d->m_auditLogLabel->setLinkColor(txtColor);
d->m_detailsLabel = new QLabel;
d->m_detailsLabel->setWordWrap(true);
d->m_detailsLabel->setTextFormat(Qt::RichText);
d->m_detailsLabel->setText(details);
d->m_detailsLabel->setFocusPolicy(Qt::StrongFocus);
d->m_detailsLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
d->m_detailsLabel->setStyleSheet(styleSheet);
connect(d->m_detailsLabel, SIGNAL(linkActivated(QString)), this, SLOT(slotLinkActivated(QString)));
vlay->addWidget(d->m_detailsLabel);
d->m_auditLogLabel->setLinkColor(linkColor);
auto detailsLabel = new HtmlLabel;
detailsLabel->setWordWrap(true);
detailsLabel->setHtml(d->m_result->details());
detailsLabel->setStyleSheet(styleSheet);
detailsLabel->setLinkColor(linkColor);
connect(detailsLabel, &QLabel::linkActivated,
this, [this](const auto &link) { d->slotLinkActivated(link); });
vlay->addWidget(detailsLabel);
d->m_closeButton = new QPushButton;
KGuiItem::assign(d->m_closeButton, KStandardGuiItem::close());
......
/*
view/htmllabel.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2021 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "htmllabel.h"
#include <QAccessible>
using namespace Kleo;
class HtmlLabel::Private
{
HtmlLabel *q;
public:
Private(HtmlLabel *q) : q{q} {}
void updateText(const QString &newText = {});
QColor linkColor;
};
void HtmlLabel::Private::updateText(const QString &newText)
{
static const QString styleTemplate{QLatin1String{"<style type=\"text/css\">a {color: %1;}</style>"}};
if (newText.isEmpty() && q->text().isEmpty()) {
return;
}
const auto styleTag = styleTemplate.arg(linkColor.isValid() ? linkColor.name() : q->palette().link().color().name());
if (newText.isEmpty()) {
q->setText(styleTag + q->text().mid(styleTag.size()));
} else {
q->setText(styleTag + newText);
}
}
HtmlLabel::HtmlLabel(QWidget *parent)
: HtmlLabel{{}, parent}
{
}
HtmlLabel::HtmlLabel(const QString &html, QWidget *parent)
: QLabel{parent}
, d{new Private{this}}
{
setTextFormat(Qt::RichText);
setTextInteractionFlags(Qt::TextBrowserInteraction);
setHtml(html);
}
HtmlLabel::~HtmlLabel() = default;
void HtmlLabel::setHtml(const QString &html)
{
if (html.isEmpty()) {
clear();
return;
}
d->updateText(html);
}
void HtmlLabel::setLinkColor(const QColor &color)
{
d->linkColor = color;
d->updateText();
}
bool HtmlLabel::focusNextPrevChild(bool next)
{
const bool result = QLabel::focusNextPrevChild(next);
if (hasFocus() && hasSelectedText()) {
QAccessibleTextSelectionEvent ev(this, selectionStart(), selectionStart() + selectedText().size());
QAccessible::updateAccessibility(&ev);
}
return result;
}
/*
view/htmllabel.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2021 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QLabel>
#include <memory>
namespace Kleo
{
class HtmlLabel : public QLabel
{
Q_OBJECT
public:
explicit HtmlLabel(QWidget *parent = nullptr);
explicit HtmlLabel(const QString &html, QWidget *parent = nullptr);
~HtmlLabel() override;
void setHtml(const QString &html);
void setLinkColor(const QColor &color);
protected:
bool focusNextPrevChild(bool next) override;
private:
using QLabel::setText;
private:
class Private;
std::unique_ptr<Private> d;
};
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment