Commit 3464ec14 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Ensure correct focus order of the result item widgets

* Make ResultItemWidget a composite widget that can receive focus.
* Ensure correct focus order when adding a new result item widget.
* Add forceSetTabOrder helper for setting the focus order of widgets
  with any focus policy (including Qt::NoFocus).

GnuPG-bug-id: 5535
parent 49cd0070
......@@ -252,6 +252,8 @@ ResultItemWidget::ResultItemWidget(const std::shared_ptr<const Task::Result> &re
overview->setText(d->m_result->overview());
overview->setFocusPolicy(Qt::StrongFocus);
overview->setStyleSheet(styleSheet);
setFocusPolicy(overview->focusPolicy());
setFocusProxy(overview);
connect(overview, SIGNAL(linkActivated(QString)), this, SLOT(slotLinkActivated(QString)));
vlay->addWidget(overview);
......
......@@ -15,6 +15,7 @@
#include <crypto/gui/resultitemwidget.h>
#include <utils/gui-helper.h>
#include <utils/scrollarea.h>
#include <Libkleo/Stl_Util>
......@@ -113,9 +114,17 @@ void ResultListWidget::Private::addResultWidget(ResultItemWidget *widget)
Q_ASSERT(m_scrollArea);
Q_ASSERT(m_scrollArea->widget());
Q_ASSERT(qobject_cast<QBoxLayout *>(m_scrollArea->widget()->layout()));
QBoxLayout &blay = *static_cast<QBoxLayout *>(m_scrollArea->widget()->layout());
blay.insertWidget(widget->hasErrorResult() ? m_lastErrorItemIndex++ : (blay.count() - 1), widget);
auto scrollAreaLayout = qobject_cast<QBoxLayout *>(m_scrollArea->widget()->layout());
Q_ASSERT(scrollAreaLayout);
// insert new widget after last widget showing error or before the trailing stretch
const auto insertIndex = widget->hasErrorResult() ? m_lastErrorItemIndex++ : scrollAreaLayout->count() - 1;
scrollAreaLayout->insertWidget(insertIndex, widget);
if (insertIndex == 0) {
forceSetTabOrder(m_scrollArea->widget(), widget);
} else {
auto previousResultWidget = qobject_cast<ResultItemWidget *>(scrollAreaLayout->itemAt(insertIndex - 1)->widget());
QWidget::setTabOrder(previousResultWidget, widget);
}
widget->show();
resizeIfStandalone();
......
......@@ -81,3 +81,27 @@ void Kleo::aggressive_raise(QWidget *w, bool stayOnTop)
#endif
}
void Kleo::forceSetTabOrder(QWidget *first, QWidget *second)
{
if (!first || !second || first == second) {
return;
}
// temporarily change the focus policy of the two widgets to something
// other than Qt::NoFocus because QWidget::setTabOrder() does nothing
// if either widget has focus policy Qt::NoFocus
const auto firstFocusPolicy = first->focusPolicy();
const auto secondFocusPolicy = second->focusPolicy();
if (firstFocusPolicy == Qt::NoFocus) {
first->setFocusPolicy(Qt::StrongFocus);
}
if (secondFocusPolicy == Qt::NoFocus) {
second->setFocusPolicy(Qt::StrongFocus);
}
QWidget::setTabOrder(first, second);
if (first->focusPolicy() != firstFocusPolicy) {
first->setFocusPolicy(firstFocusPolicy);
}
if (second->focusPolicy() != secondFocusPolicy) {
second->setFocusPolicy(secondFocusPolicy);
}
}
......@@ -35,5 +35,17 @@ static inline bool xconnect(const QObject *a, const char *signal,
* specific. */
void aggressive_raise(QWidget *w, bool stayOnTop);
}
/**
* Puts the second widget after the first widget in the focus order.
*
* In contrast to QWidget::setTabOrder(), this function also changes the
* focus order if the first widget or the second widget has focus policy
* Qt::NoFocus.
*
* Note: After calling this function all widgets in the focus proxy chain
* of the first widget have focus policy Qt::NoFocus if the first widget
* has this focus policy. Correspondingly, for the second widget.
*/
void forceSetTabOrder(QWidget *first, QWidget *second);
}
Supports Markdown
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