File indexing completed on 2024-04-28 05:45:53

0001 /*
0002     SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
0003     SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
0004     SPDX-FileCopyrightText: 2012-2020 Andrius Štikonas <andrius@stikonas.eu
0005     SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
0006     SPDX-FileCopyrightText: 2020 David Faure <faure@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-3.0-or-later
0009 */
0010 
0011 #include "gui/partwidget.h"
0012 
0013 #include "core/partition.h"
0014 #include "fs/filesystem.h"
0015 #include "util/capacity.h"
0016 
0017 #include <QApplication>
0018 #include <QFontDatabase>
0019 #include <QPainter>
0020 #include <QStyleOptionButton>
0021 
0022 /** Creates a new PartWidget
0023     @param parent pointer to the parent widget
0024     @param p pointer to the Partition this widget will show. must not be nullptr.
0025 */
0026 PartWidget::PartWidget(QWidget* parent, Partition* p) :
0027     PartWidgetBase(parent),
0028     m_Partition(nullptr),
0029     m_Active(false)
0030 {
0031     setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
0032     init(p);
0033     m_fileSystemColorCode = FileSystem::defaultColorCode;
0034 }
0035 
0036 void PartWidget::init(Partition* p)
0037 {
0038     m_Partition = p;
0039 
0040     if (partition())
0041         setToolTip(partition()->deviceNode() + QStringLiteral("\n") + partition()->fileSystem().name() + QStringLiteral(" ") + QString(Capacity::formatByteSize(partition()->capacity())));
0042     else
0043         setToolTip(QString());
0044 
0045     updateChildren();
0046 }
0047 
0048 /** Updates the widget's children */
0049 void PartWidget::updateChildren()
0050 {
0051     if (partition()) {
0052         for (const auto &w : childWidgets()) {
0053             w->setVisible(false);
0054             w->deleteLater();
0055             w->setParent(nullptr);
0056         }
0057 
0058         for (const auto &child : partition()->children()) {
0059             QWidget* w = new PartWidget(this, child);
0060             w->setVisible(true);
0061         }
0062 
0063         positionChildren(this, partition()->children(), childWidgets());
0064     }
0065 }
0066 
0067 void PartWidget::setFileSystemColorCode(const std::vector<QColor>& colorCode)
0068 {
0069     m_fileSystemColorCode = colorCode;
0070     repaint();
0071 }
0072 
0073 void PartWidget::resizeEvent(QResizeEvent*)
0074 {
0075     if (partition())
0076         positionChildren(this, partition()->children(), childWidgets());
0077 }
0078 
0079 QColor PartWidget::activeColor(const QColor& col) const
0080 {
0081     return isActive() ? col.darker(190) : col;
0082 }
0083 
0084 void PartWidget::paintEvent(QPaintEvent*)
0085 {
0086     if (partition() == nullptr)
0087         return;
0088 
0089     auto partitionCapacity = partition()->capacity();
0090     if (partitionCapacity <= 0)
0091         return;
0092 
0093     const int usedPercentage = static_cast<int>(partition()->used() * 100 / partitionCapacity);
0094     const int w = width() * usedPercentage / 100;
0095 
0096     QPainter painter(this);
0097     painter.setRenderHints(QPainter::Antialiasing);
0098 
0099     const QColor base = activeColor(m_fileSystemColorCode[ static_cast<int>(partition()->fileSystem().type()) ]);
0100     if (partition()->roles().has(PartitionRole::Extended)) {
0101         drawGradient(&painter, base, QRect(0, 0, width(), height()));
0102         return;
0103     }
0104 
0105     if (!partition()->roles().has(PartitionRole::Unallocated)) {
0106         const QColor dark = base.darker(105);
0107         const QColor light = base.lighter(120);
0108 
0109         // draw free space background
0110         drawGradient(&painter, light, QRect(0, 0, width(), height()), isActive());
0111 
0112         // draw used space in front of that
0113         drawGradient(&painter, dark, QRect(0, 0, w, height() - 1));
0114     } else
0115         drawGradient(&painter, base, QRect(0, 0, width(), height()), isActive());
0116 
0117     // draw name and size
0118     QString text = partition()->deviceNode().remove(QStringLiteral("/dev/")) + QStringLiteral("\n") + QString(Capacity::formatByteSize(partition()->capacity()));
0119 
0120     const QRect textRect(0, 0, width() - 1, height() - 1);
0121     const QRect boundingRect = painter.boundingRect(textRect, Qt::AlignCenter, text);
0122     if (boundingRect.x() > PartWidgetBase::borderWidth() && boundingRect.y() > PartWidgetBase::borderHeight()) {
0123         if (isActive())
0124             painter.setPen(Qt::white);
0125         painter.drawText(textRect, Qt::AlignCenter, text);
0126     }
0127 }
0128 
0129 void PartWidget::drawGradient(QPainter* painter, const QColor& color, const QRect& rect, bool active) const
0130 {
0131     if (rect.width() < 8)
0132         return;
0133 
0134     QStyleOptionButton option;
0135     option.initFrom(this);
0136     option.rect = rect;
0137     option.palette.setColor(QPalette::Button, color);
0138     option.palette.setColor(QPalette::Window, color);
0139     option.state |= QStyle::State_Raised;
0140     if (!active)
0141         option.state &= ~QStyle::State_MouseOver;
0142     else
0143         option.state |= QStyle::State_MouseOver;
0144 
0145     style()->drawControl(QStyle::CE_PushButtonBevel, &option, painter, this);
0146 }
0147 
0148 #include "moc_partwidget.cpp"