File indexing completed on 2024-04-28 05:46:32

0001 /*
0002     SPDX-FileCopyrightText: 2010 Volker Lanz <vl@fidra.de>
0003     SPDX-FileCopyrightText: 2014-2018 Andrius Štikonas <andrius@stikonas.eu>
0004     SPDX-FileCopyrightText: 2016 Chantara Tith <tith.chantara@gmail.com>
0005     SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-3.0-or-later
0008 */
0009 
0010 #include "gui/infopane.h"
0011 
0012 #include <core/device.h>
0013 #include <core/diskdevice.h>
0014 #include <core/lvmdevice.h>
0015 #include <core/partition.h>
0016 #include <core/softwareraid.h>
0017 
0018 #include <fs/filesystem.h>
0019 #include <fs/luks.h>
0020 #include <fs/lvm2_pv.h>
0021 
0022 #include <util/capacity.h>
0023 #include <util/helpers.h>
0024 
0025 #include <QFontDatabase>
0026 #include <QFrame>
0027 #include <QGridLayout>
0028 #include <QLabel>
0029 #include <QLocale>
0030 #include <QPalette>
0031 
0032 #include <KLocalizedString>
0033 
0034 /** Creates a new InfoPane instance
0035     @param parent the parent widget
0036 */
0037 InfoPane::InfoPane(QWidget* parent) :
0038     QWidget(parent),
0039     m_GridLayout(new QGridLayout(this))
0040 {
0041     layout()->setContentsMargins(0, 0, 0, 0);
0042 }
0043 
0044 /** Clears the InfoPane, leaving it empty */
0045 void InfoPane::clear()
0046 {
0047     parentWidget()->parentWidget()->setWindowTitle(xi18nc("@title:window", "Information"));
0048     qDeleteAll(findChildren<QLabel*>());
0049     qDeleteAll(findChildren<QFrame*>());
0050 }
0051 
0052 int InfoPane::createHeader(const QString& title, const int num_cols)
0053 {
0054     int y = 0;
0055 
0056     QLabel* label = new QLabel(title, this);
0057     QFont font;
0058     font.setBold(true);
0059     font.setWeight(QFont::Bold);
0060     label->setFont(font);
0061     label->setAlignment(Qt::AlignCenter);
0062     gridLayout().addWidget(label, y++, 0, 1, num_cols);
0063 
0064     QFrame* line = new QFrame(this);
0065     line->setFrameShape(QFrame::HLine);
0066     line->setFrameShadow(QFrame::Sunken);
0067     gridLayout().addWidget(line, y++, 0, 1, num_cols);
0068 
0069     return y;
0070 }
0071 
0072 void InfoPane::createLabels(const QString& title, const QString& value, const int num_cols, int& x, int& y)
0073 {
0074     QLabel* labelTitle = new QLabel(title, this);
0075     labelTitle->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
0076     labelTitle->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
0077 
0078     QPalette palette = labelTitle->palette();
0079     QColor f = palette.color(QPalette::WindowText);
0080     f.setAlpha(128);
0081     palette.setColor(QPalette::WindowText, f);
0082     labelTitle->setPalette(palette);
0083 
0084     gridLayout().addWidget(labelTitle, y, x, 1, 1);
0085 
0086     QLabel* labelValue = new QLabel(value, this);
0087     labelValue->setTextInteractionFlags(Qt::TextBrowserInteraction);
0088     labelValue->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
0089     gridLayout().addWidget(labelValue, y, x + 1, 1, 1);
0090 
0091     x += 2;
0092 
0093     if (x % num_cols == 0) {
0094         x = 0;
0095         y++;
0096     }
0097 }
0098 
0099 /** Shows information about a Partition in the InfoPane
0100     @param area the current area the widget's dock is in
0101     @param p the Partition to show information about
0102 */
0103 void InfoPane::showPartition(Qt::DockWidgetArea area, const Partition& p)
0104 {
0105     clear();
0106     parentWidget()->parentWidget()->setWindowTitle(xi18nc("@title:window", "Partition Information"));
0107 
0108     int x = 0;
0109     int y = createHeader(p.deviceNode(), cols(area));
0110     if (p.fileSystem().type() == FileSystem::Type::Luks) { // inactive LUKS partition
0111         const FS::luks* luksFs = static_cast<const FS::luks*>(&p.fileSystem());
0112         QString deviceNode = p.partitionPath();
0113         createLabels(i18nc("@label partition", "File system:"), p.fileSystem().name(), cols(area), x, y);
0114         createLabels(i18nc("@label partition", "Capacity:"), Capacity::formatByteSize(p.capacity()), cols(area), x, y);
0115         createLabels(i18nc("@label partition", "Cipher name:"), luksFs->cipherName(), cols(area), x, y);
0116         createLabels(i18nc("@label partition", "Cipher mode:"), luksFs->cipherMode(), cols(area), x, y);
0117         createLabels(i18nc("@label partition", "Hash:"), luksFs->hashName(), cols(area), x, y);
0118         createLabels(i18nc("@label partition", "Key size:"), QString::number(luksFs->keySize()), cols(area), x, y);
0119         createLabels(i18nc("@label partition", "Payload offset:"), Capacity::formatByteSize(luksFs->payloadOffset()), cols(area), x, y);
0120         createLabels(i18nc("@label partition", "First sector:"), QLocale().toString(p.firstSector()), cols(area), x, y);
0121         createLabels(i18nc("@label partition", "Last sector:"), QLocale().toString(p.lastSector()), cols(area), x, y);
0122         createLabels(i18nc("@label partition", "Number of sectors:"), QLocale().toString(p.length()), cols(area), x, y);
0123     } else if (p.fileSystem().type() == FileSystem::Type::Lvm2_PV) {
0124         FS::lvm2_pv *lvm2PVFs;
0125         innerFS(&p, lvm2PVFs);
0126         QString deviceNode = p.partitionPath();
0127         createLabels(i18nc("@label partition", "File system:"), p.fileSystem().name(), cols(area), x, y);
0128         createLabels(i18nc("@label partition", "Capacity:"), Capacity::formatByteSize(p.capacity()), cols(area), x, y);
0129         createLabels(i18nc("@label partition", "Available:"), Capacity::formatByteSize(p.available()), cols(area), x, y);
0130         createLabels(i18nc("@label partition", "Used:"), Capacity::formatByteSize(p.used()), cols(area), x, y);
0131         createLabels(i18nc("@label partition", "PE Size:"), Capacity::formatByteSize(lvm2PVFs->peSize()), cols(area), x, y);
0132         createLabels(i18nc("@label partition", "Total PE:"), QString::number(lvm2PVFs->totalPE()), cols(area), x, y);
0133         createLabels(i18nc("@label partition", "Free PE:"), QString::number(lvm2PVFs->freePE()), cols(area), x, y);
0134         createLabels(i18nc("@label partition", "Allocated PE:"), QString::number(lvm2PVFs->allocatedPE()), cols(area), x, y);
0135         createLabels(i18nc("@label partition", "First sector:"), QLocale().toString(p.firstSector()), cols(area), x, y);
0136         createLabels(i18nc("@label partition", "Last sector:"), QLocale().toString(p.lastSector()), cols(area), x, y);
0137         createLabels(i18nc("@label partition", "Number of sectors:"), QLocale().toString(p.length()), cols(area), x, y);
0138     } else {
0139         createLabels(xi18nc("@label partition", "File system:"), p.fileSystem().name(), cols(area), x, y);
0140         createLabels(xi18nc("@label partition", "Capacity:"), Capacity::formatByteSize(p.capacity()), cols(area), x, y);
0141         createLabels(xi18nc("@label partition", "Available:"), Capacity::formatByteSize(p.available()), cols(area), x, y);
0142         createLabels(xi18nc("@label partition", "Used:"), Capacity::formatByteSize(p.used()), cols(area), x, y);
0143         createLabels(xi18nc("@label partition", "First sector:"), QLocale().toString(p.firstSector()), cols(area), x, y);
0144         createLabels(xi18nc("@label partition", "Last sector:"), QLocale().toString(p.lastSector()), cols(area), x, y);
0145         createLabels(xi18nc("@label partition", "Number of sectors:"), QLocale().toString(p.length()), cols(area), x, y);
0146     }
0147     gridLayout().setAlignment(Qt::AlignTop);
0148 }
0149 
0150 /** Shows information about a Device in the InfoPane
0151     @param area the current area the widget's dock is in
0152     @param d the Device to show information about
0153 */
0154 void InfoPane::showDevice(Qt::DockWidgetArea area, const Device& d)
0155 {
0156     clear();
0157     parentWidget()->parentWidget()->setWindowTitle(xi18nc("@title:window", "Device Information"));
0158 
0159     int x = 0;
0160     int y = createHeader(d.name(), cols(area));
0161     createLabels(xi18nc("@label device", "Path:"), d.deviceNode(), cols(area), x, y);
0162 
0163     QString type = QStringLiteral("---");
0164     QString maxPrimaries = QStringLiteral("---");
0165 
0166     if (d.partitionTable() != nullptr) {
0167         type = (d.partitionTable()->isReadOnly())
0168                ? xi18nc("@label device", "%1 (read only)", d.partitionTable()->typeName())
0169                : d.partitionTable()->typeName();
0170         maxPrimaries = QStringLiteral("%1/%2").arg(d.partitionTable()->numPrimaries()).arg(d.partitionTable()->maxPrimaries());
0171     }
0172 
0173     if (d.type() == Device::Type::Disk_Device) {
0174         const DiskDevice& disk = static_cast<const DiskDevice&>(d);
0175 
0176         createLabels(i18nc("@label device", "Type:"), type, cols(area), x, y);
0177         createLabels(i18nc("@label device", "Capacity:"), Capacity::formatByteSize(disk.capacity()), cols(area), x, y);
0178         createLabels(i18nc("@label device", "Total sectors:"), QLocale().toString(disk.totalSectors()), cols(area), x, y);
0179         createLabels(i18nc("@label device", "Logical sector size:"), Capacity::formatByteSize(disk.logicalSectorSize()), cols(area), x, y);
0180         createLabels(i18nc("@label device", "Physical sector size:"), Capacity::formatByteSize(disk.physicalSectorSize()), cols(area), x, y);
0181         createLabels(i18nc("@label device", "Primaries/Max:"), maxPrimaries, cols(area), x, y);
0182     } else if (d.type() == Device::Type::LVM_Device) {
0183         const LvmDevice& lvm = static_cast<const LvmDevice&>(d);
0184         createLabels(i18nc("@label device", "Volume Type:"), QStringLiteral("LVM"), cols(area), x, y);
0185         createLabels(i18nc("@label device", "Capacity:"), Capacity::formatByteSize(lvm.capacity()), cols(area), x, y);
0186         createLabels(i18nc("@label device", "PE Size:"), Capacity::formatByteSize(lvm.peSize()), cols(area), x, y);
0187         createLabels(i18nc("@label device", "Total PE:"),QString::number(lvm.totalPE()), cols(area), x, y);
0188         createLabels(i18nc("@label device", "Allocated PE:"), QString::number(lvm.allocatedPE()), cols(area), x, y);
0189         createLabels(i18nc("@label device", "Free PE:"), QString::number(lvm.freePE()), cols(area), x, y);
0190     } else if (d.type() == Device::Type::SoftwareRAID_Device) {
0191         const SoftwareRAID& raid = static_cast<const SoftwareRAID&>(d);
0192         createLabels(i18nc("@label device", "Volume Type:"), QStringLiteral("RAID"), cols(area), x, y);
0193         createLabels(i18nc("@label device", "Capacity:"), Capacity::formatByteSize(raid.capacity()), cols(area), x, y);
0194         createLabels(i18nc("@label device", "RAID Level:"), raid.raidLevel() < 0 ? QStringLiteral("---") : QString::number(raid.raidLevel()), cols(area), x, y);
0195         createLabels(i18nc("@label device", "Chunk Size:"),Capacity::formatByteSize(raid.chunkSize()), cols(area), x, y);
0196         createLabels(i18nc("@label device", "Total Chunk:"), Capacity::formatByteSize(raid.totalChunk()), cols(area), x, y);
0197         createLabels(i18nc("@label device", "Array Size:"), Capacity::formatByteSize(raid.arraySize()), cols(area), x, y);
0198     }
0199     gridLayout().setAlignment(Qt::AlignTop);
0200 }
0201 
0202 qint32 InfoPane::cols(Qt::DockWidgetArea area) const
0203 {
0204     if (area == Qt::LeftDockWidgetArea || area == Qt::RightDockWidgetArea)
0205         return 2;
0206 
0207     return 6;
0208 }