1
0
mirror of https://invent.kde.org/system/dolphin synced 2024-07-04 17:30:55 +00:00

Turn free space label into a flat button

The usage of a label to show this space information is problematic
because there are features/actions hidden behind clicking the
label. A button makes this clear. It also fixes the accessibility
of this control because previously this info would never be read
out by screen readers as it couldn't get keyboard focus.

A side-effect of this change is that the free disk space bar looks
more normal with non-Breeze styles. This had been a long-standing
issue.
This commit is contained in:
Felix Ernst 2023-11-18 12:31:00 +01:00 committed by Felix Ernst
parent e8fcef32b2
commit d3637f380c
4 changed files with 88 additions and 55 deletions

View File

@ -46,8 +46,6 @@ DolphinStatusBar::DolphinStatusBar(QWidget *parent)
, m_delayUpdateTimer(nullptr)
, m_textTimestamp()
{
setContentsMargins(4, 0, 4, 0);
// Initialize text label
m_label = new KSqueezedTextLabel(m_text, this);
m_label->setWordWrap(true);
@ -117,7 +115,7 @@ DolphinStatusBar::DolphinStatusBar(QWidget *parent)
m_progressBar->setMaximumWidth(fontMetrics.averageCharWidth() * 20);
QHBoxLayout *topLayout = new QHBoxLayout(this);
topLayout->setContentsMargins(2, 0, 2, 0);
updateContentsMargins();
topLayout->setSpacing(4);
topLayout->addWidget(m_label, 1);
topLayout->addWidget(m_zoomLabel);
@ -284,6 +282,7 @@ void DolphinStatusBar::contextMenuEvent(QContextMenuEvent *event)
GeneralSettings::setShowSpaceInfo(visible);
m_spaceInfo->setVisible(visible);
}
updateContentsMargins();
}
void DolphinStatusBar::showZoomSliderToolTip(int zoomLevel)
@ -338,10 +337,22 @@ void DolphinStatusBar::setExtensionsVisible(bool visible)
m_spaceInfo->setVisible(showSpaceInfo);
m_zoomSlider->setVisible(showZoomSlider);
m_zoomLabel->setVisible(showZoomSlider);
updateContentsMargins();
}
void DolphinStatusBar::updateContentsMargins()
{
if (GeneralSettings::showSpaceInfo()) {
// We reduce the outside margin for the flat button so it visually has the same margin as the status bar text label on the other end of the bar.
layout()->setContentsMargins(6, 0, 2, 0);
} else {
layout()->setContentsMargins(6, 0, 6, 0);
}
}
void DolphinStatusBar::paintEvent(QPaintEvent *paintEvent)
{
Q_UNUSED(paintEvent)
QPainter p(this);
QStyleOption opt;
opt.initFrom(this);

View File

@ -121,6 +121,8 @@ private:
*/
void setExtensionsVisible(bool visible);
void updateContentsMargins();
private:
QString m_text;
QString m_defaultText;

View File

@ -8,20 +8,35 @@
#include "spaceinfoobserver.h"
#include <KCapacityBar>
#include <KIO/ApplicationLauncherJob>
#include <KIO/Global>
#include <KLocalizedString>
#include <KService>
#include <QHBoxLayout>
#include <QMenu>
#include <QMouseEvent>
#include <QStorageInfo>
#include <QToolButton>
StatusBarSpaceInfo::StatusBarSpaceInfo(QWidget *parent)
: KCapacityBar(KCapacityBar::DrawTextInline, parent)
: QWidget(parent)
, m_observer(nullptr)
{
setCursor(Qt::PointingHandCursor);
m_capacityBar = new KCapacityBar(KCapacityBar::DrawTextInline, this);
m_textInfoButton = new QToolButton(this);
m_textInfoButton->setAutoRaise(true);
m_textInfoButton->setPopupMode(QToolButton::InstantPopup);
m_buttonMenu = new QMenu(this);
m_textInfoButton->setMenu(m_buttonMenu);
connect(m_buttonMenu, &QMenu::aboutToShow, this, &StatusBarSpaceInfo::updateMenu);
auto layout = new QHBoxLayout(this);
// We reduce the outside margin of the flat button so it visually has the same margin as the status bar text label on the other end of the bar.
layout->setContentsMargins(2, -1, 0, -1); // "-1" makes it so the fixed height won't be ignored.
layout->addWidget(m_capacityBar);
layout->addWidget(m_textInfoButton);
}
StatusBarSpaceInfo::~StatusBarSpaceInfo()
@ -65,7 +80,7 @@ void StatusBarSpaceInfo::showEvent(QShowEvent *event)
{
if (m_shown) {
if (m_ready) {
KCapacityBar::showEvent(event);
QWidget::showEvent(event);
}
if (m_observer.isNull()) {
@ -81,71 +96,68 @@ void StatusBarSpaceInfo::hideEvent(QHideEvent *event)
m_observer.reset();
m_ready = false;
}
KCapacityBar::hideEvent(event);
QWidget::hideEvent(event);
}
void StatusBarSpaceInfo::mousePressEvent(QMouseEvent *event)
void StatusBarSpaceInfo::updateMenu()
{
if (event->button() == Qt::LeftButton) {
// Creates a menu with tools that help to find out more about free
// disk space for the given url.
m_buttonMenu->clear();
const KService::Ptr filelight = KService::serviceByDesktopName(QStringLiteral("org.kde.filelight"));
const KService::Ptr kdiskfree = KService::serviceByDesktopName(QStringLiteral("org.kde.kdf"));
// Creates a menu with tools that help to find out more about free
// disk space for the given url.
if (!filelight && !kdiskfree) {
// nothing to show
return;
}
const KService::Ptr filelight = KService::serviceByDesktopName(QStringLiteral("org.kde.filelight"));
const KService::Ptr kdiskfree = KService::serviceByDesktopName(QStringLiteral("org.kde.kdf"));
QMenu *menu = new QMenu(this);
if (!filelight && !kdiskfree) {
// nothing to show
return;
}
if (filelight) {
QAction *filelightFolderAction = menu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current folder"));
if (filelight) {
QAction *filelightFolderAction = m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current folder"));
menu->connect(filelightFolderAction, &QAction::triggered, menu, [this, filelight](bool) {
auto *job = new KIO::ApplicationLauncherJob(filelight);
job->setUrls({m_url});
job->start();
});
m_buttonMenu->connect(filelightFolderAction, &QAction::triggered, m_buttonMenu, [this, filelight](bool) {
auto *job = new KIO::ApplicationLauncherJob(filelight);
job->setUrls({m_url});
job->start();
});
// For remote URLs like FTP analyzing the device makes no sense
if (m_url.isLocalFile()) {
QAction *filelightDiskAction = menu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current device"));
// For remote URLs like FTP analyzing the device makes no sense
if (m_url.isLocalFile()) {
QAction *filelightDiskAction =
m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current device"));
menu->connect(filelightDiskAction, &QAction::triggered, menu, [this, filelight](bool) {
const QStorageInfo info(m_url.toLocalFile());
if (info.isValid() && info.isReady()) {
auto *job = new KIO::ApplicationLauncherJob(filelight);
job->setUrls({QUrl::fromLocalFile(info.rootPath())});
job->start();
}
});
}
QAction *filelightAllAction = menu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - all devices"));
menu->connect(filelightAllAction, &QAction::triggered, menu, [this, filelight](bool) {
m_buttonMenu->connect(filelightDiskAction, &QAction::triggered, m_buttonMenu, [this, filelight](bool) {
const QStorageInfo info(m_url.toLocalFile());
if (info.isValid() && info.isReady()) {
auto *job = new KIO::ApplicationLauncherJob(filelight);
job->setUrls({QUrl::fromLocalFile(info.rootPath())});
job->start();
}
});
}
if (kdiskfree) {
QAction *kdiskfreeAction = menu->addAction(QIcon::fromTheme(QStringLiteral("kdf")), i18n("KDiskFree"));
QAction *filelightAllAction = m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - all devices"));
connect(kdiskfreeAction, &QAction::triggered, this, [kdiskfree] {
auto *job = new KIO::ApplicationLauncherJob(kdiskfree);
m_buttonMenu->connect(filelightAllAction, &QAction::triggered, m_buttonMenu, [this, filelight](bool) {
const QStorageInfo info(m_url.toLocalFile());
if (info.isValid() && info.isReady()) {
auto *job = new KIO::ApplicationLauncherJob(filelight);
job->start();
});
}
}
});
}
menu->exec(QCursor::pos());
if (kdiskfree) {
QAction *kdiskfreeAction = m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("kdf")), i18n("KDiskFree"));
connect(kdiskfreeAction, &QAction::triggered, this, [kdiskfree] {
auto *job = new KIO::ApplicationLauncherJob(kdiskfree);
job->start();
});
}
}
@ -165,10 +177,11 @@ void StatusBarSpaceInfo::slotValuesChanged()
const quint64 used = size - available;
const int percentUsed = qRound(100.0 * qreal(used) / qreal(size));
setText(i18nc("@info:status Free disk space", "%1 free", KIO::convertSize(available)));
m_textInfoButton->setText(i18nc("@info:status Free disk space", "%1 free", KIO::convertSize(available)));
setToolTip(i18nc("tooltip:status Free disk space", "%1 free out of %2 (%3% used)", KIO::convertSize(available), KIO::convertSize(size), percentUsed));
m_textInfoButton->setToolTip(toolTip());
setUpdatesEnabled(false);
setValue(percentUsed);
m_capacityBar->setValue(percentUsed);
setUpdatesEnabled(true);
if (!isVisible()) {

View File

@ -6,13 +6,16 @@
#ifndef STATUSBARSPACEINFO_H
#define STATUSBARSPACEINFO_H
#include <KCapacityBar>
#include <QUrl>
#include <QWidget>
class QHideEvent;
class QShowEvent;
class QMenu;
class QMouseEvent;
class QToolButton;
class KCapacityBar;
class SpaceInfoObserver;
@ -20,7 +23,7 @@ class SpaceInfoObserver;
* @short Shows the available space for the volume represented
* by the given URL as part of the status bar.
*/
class StatusBarSpaceInfo : public KCapacityBar
class StatusBarSpaceInfo : public QWidget
{
Q_OBJECT
@ -40,13 +43,17 @@ public:
protected:
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void updateMenu();
private Q_SLOTS:
void slotValuesChanged();
private:
QScopedPointer<SpaceInfoObserver> m_observer;
KCapacityBar *m_capacityBar;
QToolButton *m_textInfoButton;
QMenu *m_buttonMenu;
QUrl m_url;
bool m_ready;
bool m_shown;