File indexing completed on 2024-04-28 17:03:15
0001 /* 0002 * SPDX-FileCopyrightText: 2006 Peter Penz (peter.penz@gmx.at) and Patrice Tremblay 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "statusbarspaceinfo.h" 0008 0009 #include "spaceinfoobserver.h" 0010 0011 #include <KCapacityBar> 0012 #include <KIO/ApplicationLauncherJob> 0013 #include <KIO/Global> 0014 #include <KLocalizedString> 0015 #include <KService> 0016 0017 #include <QHBoxLayout> 0018 #include <QMenu> 0019 #include <QMouseEvent> 0020 #include <QStorageInfo> 0021 #include <QToolButton> 0022 0023 StatusBarSpaceInfo::StatusBarSpaceInfo(QWidget *parent) 0024 : QWidget(parent) 0025 , m_observer(nullptr) 0026 { 0027 m_capacityBar = new KCapacityBar(KCapacityBar::DrawTextInline, this); 0028 m_textInfoButton = new QToolButton(this); 0029 m_textInfoButton->setAutoRaise(true); 0030 m_textInfoButton->setPopupMode(QToolButton::InstantPopup); 0031 m_buttonMenu = new QMenu(this); 0032 m_textInfoButton->setMenu(m_buttonMenu); 0033 connect(m_buttonMenu, &QMenu::aboutToShow, this, &StatusBarSpaceInfo::updateMenu); 0034 0035 auto layout = new QHBoxLayout(this); 0036 // 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. 0037 layout->setContentsMargins(2, -1, 0, -1); // "-1" makes it so the fixed height won't be ignored. 0038 layout->addWidget(m_capacityBar); 0039 layout->addWidget(m_textInfoButton); 0040 } 0041 0042 StatusBarSpaceInfo::~StatusBarSpaceInfo() 0043 { 0044 } 0045 0046 void StatusBarSpaceInfo::setShown(bool shown) 0047 { 0048 m_shown = shown; 0049 if (!m_shown) { 0050 hide(); 0051 m_ready = false; 0052 } 0053 } 0054 0055 void StatusBarSpaceInfo::setUrl(const QUrl &url) 0056 { 0057 if (m_url != url) { 0058 m_url = url; 0059 m_ready = false; 0060 if (m_observer) { 0061 m_observer.reset(new SpaceInfoObserver(m_url, this)); 0062 connect(m_observer.data(), &SpaceInfoObserver::valuesChanged, this, &StatusBarSpaceInfo::slotValuesChanged); 0063 } 0064 } 0065 } 0066 0067 QUrl StatusBarSpaceInfo::url() const 0068 { 0069 return m_url; 0070 } 0071 0072 void StatusBarSpaceInfo::update() 0073 { 0074 if (m_observer) { 0075 m_observer->update(); 0076 } 0077 } 0078 0079 void StatusBarSpaceInfo::showEvent(QShowEvent *event) 0080 { 0081 if (m_shown) { 0082 if (m_ready) { 0083 QWidget::showEvent(event); 0084 } 0085 0086 if (m_observer.isNull()) { 0087 m_observer.reset(new SpaceInfoObserver(m_url, this)); 0088 connect(m_observer.data(), &SpaceInfoObserver::valuesChanged, this, &StatusBarSpaceInfo::slotValuesChanged); 0089 } 0090 } 0091 } 0092 0093 void StatusBarSpaceInfo::hideEvent(QHideEvent *event) 0094 { 0095 if (m_ready) { 0096 m_observer.reset(); 0097 m_ready = false; 0098 } 0099 QWidget::hideEvent(event); 0100 } 0101 0102 QSize StatusBarSpaceInfo::minimumSizeHint() const 0103 { 0104 return QSize(); 0105 } 0106 0107 void StatusBarSpaceInfo::updateMenu() 0108 { 0109 m_buttonMenu->clear(); 0110 0111 // Creates a menu with tools that help to find out more about free 0112 // disk space for the given url. 0113 0114 const KService::Ptr filelight = KService::serviceByDesktopName(QStringLiteral("org.kde.filelight")); 0115 const KService::Ptr kdiskfree = KService::serviceByDesktopName(QStringLiteral("org.kde.kdf")); 0116 0117 if (!filelight && !kdiskfree) { 0118 // nothing to show 0119 return; 0120 } 0121 0122 if (filelight) { 0123 QAction *filelightFolderAction = m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current folder")); 0124 0125 m_buttonMenu->connect(filelightFolderAction, &QAction::triggered, m_buttonMenu, [this, filelight](bool) { 0126 auto *job = new KIO::ApplicationLauncherJob(filelight); 0127 job->setUrls({m_url}); 0128 job->start(); 0129 }); 0130 0131 // For remote URLs like FTP analyzing the device makes no sense 0132 if (m_url.isLocalFile()) { 0133 QAction *filelightDiskAction = 0134 m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - current device")); 0135 0136 m_buttonMenu->connect(filelightDiskAction, &QAction::triggered, m_buttonMenu, [this, filelight](bool) { 0137 const QStorageInfo info(m_url.toLocalFile()); 0138 0139 if (info.isValid() && info.isReady()) { 0140 auto *job = new KIO::ApplicationLauncherJob(filelight); 0141 job->setUrls({QUrl::fromLocalFile(info.rootPath())}); 0142 job->start(); 0143 } 0144 }); 0145 } 0146 0147 QAction *filelightAllAction = m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("filelight")), i18n("Disk Usage Statistics - all devices")); 0148 0149 m_buttonMenu->connect(filelightAllAction, &QAction::triggered, m_buttonMenu, [this, filelight](bool) { 0150 const QStorageInfo info(m_url.toLocalFile()); 0151 0152 if (info.isValid() && info.isReady()) { 0153 auto *job = new KIO::ApplicationLauncherJob(filelight); 0154 job->start(); 0155 } 0156 }); 0157 } 0158 0159 if (kdiskfree) { 0160 QAction *kdiskfreeAction = m_buttonMenu->addAction(QIcon::fromTheme(QStringLiteral("kdf")), i18n("KDiskFree")); 0161 0162 connect(kdiskfreeAction, &QAction::triggered, this, [kdiskfree] { 0163 auto *job = new KIO::ApplicationLauncherJob(kdiskfree); 0164 job->start(); 0165 }); 0166 } 0167 } 0168 0169 void StatusBarSpaceInfo::slotValuesChanged() 0170 { 0171 Q_ASSERT(m_observer); 0172 const quint64 size = m_observer->size(); 0173 0174 if (!m_shown || size == 0) { 0175 hide(); 0176 return; 0177 } 0178 0179 m_ready = true; 0180 0181 const quint64 available = m_observer->available(); 0182 const quint64 used = size - available; 0183 const int percentUsed = qRound(100.0 * qreal(used) / qreal(size)); 0184 0185 m_textInfoButton->setText(i18nc("@info:status Free disk space", "%1 free", KIO::convertSize(available))); 0186 setToolTip(i18nc("tooltip:status Free disk space", "%1 free out of %2 (%3% used)", KIO::convertSize(available), KIO::convertSize(size), percentUsed)); 0187 m_textInfoButton->setToolTip(i18nc("@info:tooltip for the free disk space button", 0188 "%1 free out of %2 (%3% used)\nPress to manage disk space usage.", 0189 KIO::convertSize(available), 0190 KIO::convertSize(size), 0191 percentUsed)); 0192 setUpdatesEnabled(false); 0193 m_capacityBar->setValue(percentUsed); 0194 setUpdatesEnabled(true); 0195 0196 if (!isVisible()) { 0197 show(); 0198 } else { 0199 update(); 0200 } 0201 } 0202 0203 #include "moc_statusbarspaceinfo.cpp"