diff --git a/src/utils/scrollarea.cpp b/src/utils/scrollarea.cpp index 0e79b535a..9ae6f2c09 100644 --- a/src/utils/scrollarea.cpp +++ b/src/utils/scrollarea.cpp @@ -1,102 +1,98 @@ /* -*- mode: c++; c-basic-offset:4 -*- utils/scrollarea.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB SPDX-FileCopyrightText: 2022 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "scrollarea.h" #include #include #include #include #include using namespace Kleo; ScrollArea::ScrollArea(QWidget *parent) : QScrollArea{parent} { auto w = new QWidget; w->setObjectName(QLatin1String("scrollarea_widget")); new QVBoxLayout{w}; setWidget(w); setWidgetResizable(true); w->installEventFilter(this); connect(qApp, &QApplication::focusChanged, this, [this](QWidget *old, QWidget *now) { Q_UNUSED(old); ensureWidgetVisible(now); }); } ScrollArea::~ScrollArea() { widget()->removeEventFilter(this); } -void ScrollArea::setMaximumAutoAdjustHeight(int maxHeight) -{ - mMaximumAutoAdjustHeight = maxHeight; -} - -int ScrollArea::maximumAutoAdjustHeight() const -{ - if (mMaximumAutoAdjustHeight < 0) { - // if no height is set then use 2/3 of the desktop's height, i.e. - // the same as Qt uses for top-level widgets - return screen()->availableGeometry().height() * 2 / 3; - } - return mMaximumAutoAdjustHeight; -} - QSize ScrollArea::minimumSizeHint() const { const int fw = frameWidth(); QSize sz{2 * fw, 2 * fw}; sz += widget()->minimumSizeHint(); if (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff) { sz.setWidth(sz.width() + verticalScrollBar()->sizeHint().width()); } if (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff) { sz.setHeight(sz.height() + horizontalScrollBar()->sizeHint().height()); } return QScrollArea::minimumSizeHint().expandedTo(sz); } QSize ScrollArea::sizeHint() const { const int fw = frameWidth(); QSize sz{2 * fw, 2 * fw}; sz += viewportSizeHint(); if (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff) { sz.setWidth(sz.width() + verticalScrollBar()->sizeHint().width()); } if (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff) { sz.setHeight(sz.height() + horizontalScrollBar()->sizeHint().height()); } sz = QScrollArea::sizeHint().expandedTo(sz); return sz; } +void ScrollArea::adjustSizeOfWindowBy(const QSize &extent) +{ + if (auto w = window()) { + // we limit the automatic size adjustment to 2/3 of the screen's size + const auto maxWindowSize = screen()->geometry().size() * 2 / 3; + const auto newWindowSize = (w->size() + extent).boundedTo(maxWindowSize); + w->resize(newWindowSize); + } +} + bool ScrollArea::eventFilter(QObject *obj, QEvent *ev) { if (ev->type() == QEvent::Resize && obj == widget() && sizeAdjustPolicy() == AdjustToContents) { const auto *const event = static_cast(ev); if (event->size().height() > event->oldSize().height()) { const auto currentViewportHeight = viewport()->height(); - const auto wantedViewportHeight = std::min(event->size().height(), maximumAutoAdjustHeight()); - if (currentViewportHeight < wantedViewportHeight) { - setMinimumHeight(height() - currentViewportHeight + wantedViewportHeight); + const auto wantedViewportHeight = event->size().height(); + const auto wantedAdditionalHeight = wantedViewportHeight - currentViewportHeight; + if (wantedAdditionalHeight > 0) { + adjustSizeOfWindowBy(QSize{0, wantedAdditionalHeight}); } } } return QScrollArea::eventFilter(obj, ev); } diff --git a/src/utils/scrollarea.h b/src/utils/scrollarea.h index d542c37b4..852ecb347 100644 --- a/src/utils/scrollarea.h +++ b/src/utils/scrollarea.h @@ -1,73 +1,58 @@ /* -*- mode: c++; c-basic-offset:4 -*- utils/scrollarea.h This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB SPDX-FileCopyrightText: 2022 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include namespace Kleo { /** * This class improves a few aspects of QScrollArea for usage by us, in * particular, for vertically scrollable widgets. * * If sizeAdjustPolicy is set to QAbstractScrollArea::AdjustToContents, * then the scroll area will (try to) adjust its size to the widget to avoid * scroll bars as much as possible. */ class ScrollArea : public QScrollArea { Q_OBJECT public: /** * Creates a scroll area with a QWidget with QVBoxLayout that is flagged * as resizable. */ explicit ScrollArea(QWidget *parent = nullptr); ~ScrollArea() override; - /** - * Sets the maximum height that the scroll area should automatically resize - * to to \p maxHeight. By default, or if \p maxHeight is negative, the - * scroll area will resize to at most 2/3 of the desktop's height. - */ - void setMaximumAutoAdjustHeight(int maxHeight); - - /** - * Returns the maximum height that the scroll area will automatically resize - * to. - */ - int maximumAutoAdjustHeight() const; - /** * Reimplemented to add the minimum size hint of the widget. */ QSize minimumSizeHint() const override; /** * Reimplemented to remove the caching of the size/size hint of the * widget and to add the horizontal size hint of the vertical scroll bar * unless it is explicitly turned off. */ QSize sizeHint() const override; private: + void adjustSizeOfWindowBy(const QSize &extent); bool eventFilter(QObject *obj, QEvent *ev) override; - -private: - int mMaximumAutoAdjustHeight = -1; }; }