mirror of
https://invent.kde.org/system/dolphin
synced 2024-10-05 16:19:10 +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:
parent
e8fcef32b2
commit
d3637f380c
|
@ -46,8 +46,6 @@ DolphinStatusBar::DolphinStatusBar(QWidget *parent)
|
||||||
, m_delayUpdateTimer(nullptr)
|
, m_delayUpdateTimer(nullptr)
|
||||||
, m_textTimestamp()
|
, m_textTimestamp()
|
||||||
{
|
{
|
||||||
setContentsMargins(4, 0, 4, 0);
|
|
||||||
|
|
||||||
// Initialize text label
|
// Initialize text label
|
||||||
m_label = new KSqueezedTextLabel(m_text, this);
|
m_label = new KSqueezedTextLabel(m_text, this);
|
||||||
m_label->setWordWrap(true);
|
m_label->setWordWrap(true);
|
||||||
|
@ -117,7 +115,7 @@ DolphinStatusBar::DolphinStatusBar(QWidget *parent)
|
||||||
m_progressBar->setMaximumWidth(fontMetrics.averageCharWidth() * 20);
|
m_progressBar->setMaximumWidth(fontMetrics.averageCharWidth() * 20);
|
||||||
|
|
||||||
QHBoxLayout *topLayout = new QHBoxLayout(this);
|
QHBoxLayout *topLayout = new QHBoxLayout(this);
|
||||||
topLayout->setContentsMargins(2, 0, 2, 0);
|
updateContentsMargins();
|
||||||
topLayout->setSpacing(4);
|
topLayout->setSpacing(4);
|
||||||
topLayout->addWidget(m_label, 1);
|
topLayout->addWidget(m_label, 1);
|
||||||
topLayout->addWidget(m_zoomLabel);
|
topLayout->addWidget(m_zoomLabel);
|
||||||
|
@ -284,6 +282,7 @@ void DolphinStatusBar::contextMenuEvent(QContextMenuEvent *event)
|
||||||
GeneralSettings::setShowSpaceInfo(visible);
|
GeneralSettings::setShowSpaceInfo(visible);
|
||||||
m_spaceInfo->setVisible(visible);
|
m_spaceInfo->setVisible(visible);
|
||||||
}
|
}
|
||||||
|
updateContentsMargins();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DolphinStatusBar::showZoomSliderToolTip(int zoomLevel)
|
void DolphinStatusBar::showZoomSliderToolTip(int zoomLevel)
|
||||||
|
@ -338,10 +337,22 @@ void DolphinStatusBar::setExtensionsVisible(bool visible)
|
||||||
m_spaceInfo->setVisible(showSpaceInfo);
|
m_spaceInfo->setVisible(showSpaceInfo);
|
||||||
m_zoomSlider->setVisible(showZoomSlider);
|
m_zoomSlider->setVisible(showZoomSlider);
|
||||||
m_zoomLabel->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)
|
void DolphinStatusBar::paintEvent(QPaintEvent *paintEvent)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(paintEvent)
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
QStyleOption opt;
|
QStyleOption opt;
|
||||||
opt.initFrom(this);
|
opt.initFrom(this);
|
||||||
|
|
|
@ -121,6 +121,8 @@ private:
|
||||||
*/
|
*/
|
||||||
void setExtensionsVisible(bool visible);
|
void setExtensionsVisible(bool visible);
|
||||||
|
|
||||||
|
void updateContentsMargins();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_text;
|
QString m_text;
|
||||||
QString m_defaultText;
|
QString m_defaultText;
|
||||||
|
|
|
@ -8,20 +8,35 @@
|
||||||
|
|
||||||
#include "spaceinfoobserver.h"
|
#include "spaceinfoobserver.h"
|
||||||
|
|
||||||
|
#include <KCapacityBar>
|
||||||
#include <KIO/ApplicationLauncherJob>
|
#include <KIO/ApplicationLauncherJob>
|
||||||
#include <KIO/Global>
|
#include <KIO/Global>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KService>
|
#include <KService>
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QStorageInfo>
|
#include <QStorageInfo>
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
StatusBarSpaceInfo::StatusBarSpaceInfo(QWidget *parent)
|
StatusBarSpaceInfo::StatusBarSpaceInfo(QWidget *parent)
|
||||||
: KCapacityBar(KCapacityBar::DrawTextInline, parent)
|
: QWidget(parent)
|
||||||
, m_observer(nullptr)
|
, 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()
|
StatusBarSpaceInfo::~StatusBarSpaceInfo()
|
||||||
|
@ -65,7 +80,7 @@ void StatusBarSpaceInfo::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
if (m_shown) {
|
if (m_shown) {
|
||||||
if (m_ready) {
|
if (m_ready) {
|
||||||
KCapacityBar::showEvent(event);
|
QWidget::showEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_observer.isNull()) {
|
if (m_observer.isNull()) {
|
||||||
|
@ -81,71 +96,68 @@ void StatusBarSpaceInfo::hideEvent(QHideEvent *event)
|
||||||
m_observer.reset();
|
m_observer.reset();
|
||||||
m_ready = false;
|
m_ready = false;
|
||||||
}
|
}
|
||||||
KCapacityBar::hideEvent(event);
|
QWidget::hideEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBarSpaceInfo::mousePressEvent(QMouseEvent *event)
|
void StatusBarSpaceInfo::updateMenu()
|
||||||
{
|
{
|
||||||
if (event->button() == Qt::LeftButton) {
|
m_buttonMenu->clear();
|
||||||
// Creates a menu with tools that help to find out more about free
|
|
||||||
// disk space for the given url.
|
|
||||||
|
|
||||||
const KService::Ptr filelight = KService::serviceByDesktopName(QStringLiteral("org.kde.filelight"));
|
// Creates a menu with tools that help to find out more about free
|
||||||
const KService::Ptr kdiskfree = KService::serviceByDesktopName(QStringLiteral("org.kde.kdf"));
|
// disk space for the given url.
|
||||||
|
|
||||||
if (!filelight && !kdiskfree) {
|
const KService::Ptr filelight = KService::serviceByDesktopName(QStringLiteral("org.kde.filelight"));
|
||||||
// nothing to show
|
const KService::Ptr kdiskfree = KService::serviceByDesktopName(QStringLiteral("org.kde.kdf"));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMenu *menu = new QMenu(this);
|
if (!filelight && !kdiskfree) {
|
||||||
|
// nothing to show
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (filelight) {
|
if (filelight) {
|
||||||
QAction *filelightFolderAction = menu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current folder"));
|
QAction *filelightFolderAction = m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current folder"));
|
||||||
|
|
||||||
menu->connect(filelightFolderAction, &QAction::triggered, menu, [this, filelight](bool) {
|
m_buttonMenu->connect(filelightFolderAction, &QAction::triggered, m_buttonMenu, [this, filelight](bool) {
|
||||||
auto *job = new KIO::ApplicationLauncherJob(filelight);
|
auto *job = new KIO::ApplicationLauncherJob(filelight);
|
||||||
job->setUrls({m_url});
|
job->setUrls({m_url});
|
||||||
job->start();
|
job->start();
|
||||||
});
|
});
|
||||||
|
|
||||||
// For remote URLs like FTP analyzing the device makes no sense
|
// For remote URLs like FTP analyzing the device makes no sense
|
||||||
if (m_url.isLocalFile()) {
|
if (m_url.isLocalFile()) {
|
||||||
QAction *filelightDiskAction = menu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current device"));
|
QAction *filelightDiskAction =
|
||||||
|
m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current device"));
|
||||||
|
|
||||||
menu->connect(filelightDiskAction, &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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction *filelightAllAction = menu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - all devices"));
|
|
||||||
|
|
||||||
menu->connect(filelightAllAction, &QAction::triggered, menu, [this, filelight](bool) {
|
|
||||||
const QStorageInfo info(m_url.toLocalFile());
|
const QStorageInfo info(m_url.toLocalFile());
|
||||||
|
|
||||||
if (info.isValid() && info.isReady()) {
|
if (info.isValid() && info.isReady()) {
|
||||||
auto *job = new KIO::ApplicationLauncherJob(filelight);
|
auto *job = new KIO::ApplicationLauncherJob(filelight);
|
||||||
|
job->setUrls({QUrl::fromLocalFile(info.rootPath())});
|
||||||
job->start();
|
job->start();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kdiskfree) {
|
QAction *filelightAllAction = m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - all devices"));
|
||||||
QAction *kdiskfreeAction = menu->addAction(QIcon::fromTheme(QStringLiteral("kdf")), i18n("KDiskFree"));
|
|
||||||
|
|
||||||
connect(kdiskfreeAction, &QAction::triggered, this, [kdiskfree] {
|
m_buttonMenu->connect(filelightAllAction, &QAction::triggered, m_buttonMenu, [this, filelight](bool) {
|
||||||
auto *job = new KIO::ApplicationLauncherJob(kdiskfree);
|
const QStorageInfo info(m_url.toLocalFile());
|
||||||
|
|
||||||
|
if (info.isValid() && info.isReady()) {
|
||||||
|
auto *job = new KIO::ApplicationLauncherJob(filelight);
|
||||||
job->start();
|
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 quint64 used = size - available;
|
||||||
const int percentUsed = qRound(100.0 * qreal(used) / qreal(size));
|
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));
|
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);
|
setUpdatesEnabled(false);
|
||||||
setValue(percentUsed);
|
m_capacityBar->setValue(percentUsed);
|
||||||
setUpdatesEnabled(true);
|
setUpdatesEnabled(true);
|
||||||
|
|
||||||
if (!isVisible()) {
|
if (!isVisible()) {
|
||||||
|
|
|
@ -6,13 +6,16 @@
|
||||||
#ifndef STATUSBARSPACEINFO_H
|
#ifndef STATUSBARSPACEINFO_H
|
||||||
#define STATUSBARSPACEINFO_H
|
#define STATUSBARSPACEINFO_H
|
||||||
|
|
||||||
#include <KCapacityBar>
|
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
class QHideEvent;
|
class QHideEvent;
|
||||||
class QShowEvent;
|
class QShowEvent;
|
||||||
|
class QMenu;
|
||||||
class QMouseEvent;
|
class QMouseEvent;
|
||||||
|
class QToolButton;
|
||||||
|
|
||||||
|
class KCapacityBar;
|
||||||
|
|
||||||
class SpaceInfoObserver;
|
class SpaceInfoObserver;
|
||||||
|
|
||||||
|
@ -20,7 +23,7 @@ class SpaceInfoObserver;
|
||||||
* @short Shows the available space for the volume represented
|
* @short Shows the available space for the volume represented
|
||||||
* by the given URL as part of the status bar.
|
* by the given URL as part of the status bar.
|
||||||
*/
|
*/
|
||||||
class StatusBarSpaceInfo : public KCapacityBar
|
class StatusBarSpaceInfo : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -40,13 +43,17 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
void hideEvent(QHideEvent *event) override;
|
void hideEvent(QHideEvent *event) override;
|
||||||
void mousePressEvent(QMouseEvent *event) override;
|
|
||||||
|
void updateMenu();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void slotValuesChanged();
|
void slotValuesChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<SpaceInfoObserver> m_observer;
|
QScopedPointer<SpaceInfoObserver> m_observer;
|
||||||
|
KCapacityBar *m_capacityBar;
|
||||||
|
QToolButton *m_textInfoButton;
|
||||||
|
QMenu *m_buttonMenu;
|
||||||
QUrl m_url;
|
QUrl m_url;
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
bool m_shown;
|
bool m_shown;
|
||||||
|
|
Loading…
Reference in a new issue