File indexing completed on 2024-05-19 09:42:48
0001 /* 0002 SPDX-FileCopyrightText: 2016 Chantara Tith <tith.chantara@gmail.com> 0003 SPDX-FileCopyrightText: 2016-2018 Andrius Štikonas <andrius@stikonas.eu> 0004 SPDX-FileCopyrightText: 2018 Yuri Chornoivan <yurchor@ukr.net> 0005 0006 SPDX-License-Identifier: GPL-3.0-or-later 0007 */ 0008 0009 #include "gui/volumegroupdialog.h" 0010 #include "gui/volumegroupwidget.h" 0011 0012 #include <core/partitiontable.h> 0013 #include <core/lvmdevice.h> 0014 #include <fs/lvm2_pv.h> 0015 0016 #include <util/capacity.h> 0017 #include <util/helpers.h> 0018 0019 #include <KConfigGroup> 0020 #include <KLocalizedString> 0021 #include <KSharedConfig> 0022 0023 #include <QtGlobal> 0024 #include <QListWidgetItem> 0025 #include <QRegularExpressionValidator> 0026 0027 /** Creates a new VolumeGroupDialog 0028 @param parent pointer to the parent widget 0029 @param vgName Volume Group name 0030 @param pvList List of LVM Physical Volumes used to create Volume Group 0031 */ 0032 VolumeGroupDialog::VolumeGroupDialog(QWidget* parent, QString& vgName, QVector<const Partition*>& pvList) : 0033 QDialog(parent), 0034 m_DialogWidget(new VolumeGroupWidget(this)), 0035 m_TargetName(vgName), 0036 m_TargetPVList(pvList), 0037 m_IsValidSize(false), 0038 m_IsValidName(true), 0039 m_TotalSize(0), 0040 m_TotalUsedSize(0), 0041 m_ExtentSize(0) 0042 { 0043 mainLayout = new QVBoxLayout(this); 0044 setLayout(mainLayout); 0045 mainLayout->addWidget(&dialogWidget()); 0046 0047 dialogButtonBox = new QDialogButtonBox; 0048 okButton = dialogButtonBox->addButton(QDialogButtonBox::Ok); 0049 cancelButton = dialogButtonBox->addButton(QDialogButtonBox::Cancel); 0050 mainLayout->addWidget(dialogButtonBox); 0051 0052 cancelButton->setFocus(); 0053 cancelButton->setDefault(true); 0054 0055 setupDialog(); 0056 setupConstraints(); 0057 setupConnections(); 0058 } 0059 0060 /** Destroys a VolumeGroupDialog */ 0061 VolumeGroupDialog::~VolumeGroupDialog() 0062 { 0063 KConfigGroup kcg(KSharedConfig::openConfig(), QStringLiteral("createVolumeGroupDialog")); 0064 kcg.writeEntry("Geometry", saveGeometry()); 0065 } 0066 0067 void VolumeGroupDialog::setupDialog() 0068 { 0069 /* LVM Volume group name can consist of: letters numbers _ . - + 0070 * It cannot start with underscore _ and must not be equal to . or .. or any entry in /dev/ 0071 * QLineEdit accepts QValidator::Intermediate, so we just disable . at the beginning */ 0072 QRegularExpression re(QStringLiteral(R"(^(?!_|\.)[\w\-.+]+)")); 0073 QRegularExpressionValidator *validator = new QRegularExpressionValidator(re, this); 0074 dialogWidget().vgName().setValidator(validator); 0075 dialogWidget().vgName().setText(targetName()); 0076 0077 dialogWidget().volumeType().addItem(QStringLiteral("LVM")); 0078 dialogWidget().volumeType().addItem(QStringLiteral("RAID")); 0079 dialogWidget().volumeType().setCurrentIndex(0); 0080 0081 setMinimumSize(dialogWidget().size()); 0082 resize(dialogWidget().size()); 0083 } 0084 0085 void VolumeGroupDialog::setupConnections() 0086 { 0087 connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &VolumeGroupDialog::accept); 0088 connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &VolumeGroupDialog::reject); 0089 connect(&dialogWidget().volumeType(), &QComboBox::currentIndexChanged, this, &VolumeGroupDialog::onVolumeTypeChanged); 0090 connect(&dialogWidget().listPV().listPhysicalVolumes(), &QListWidget::itemChanged, 0091 this, [=] ( QListWidgetItem*) { 0092 updateSizeInfos(); 0093 }); 0094 } 0095 0096 void VolumeGroupDialog::setupConstraints() 0097 { 0098 updateSizeInfos(); 0099 updateOkButtonStatus(); 0100 } 0101 0102 void VolumeGroupDialog::updateOkButtonStatus() 0103 { 0104 bool enable = isValidSize(); 0105 0106 if (dialogWidget().vgName().text().isEmpty() || !isValidName()) { 0107 enable = false; 0108 } 0109 if (dialogWidget().spinPESize().value() <= 0) { 0110 enable = false; 0111 } 0112 0113 okButton->setEnabled(enable); 0114 } 0115 0116 void VolumeGroupDialog::updateSectorInfos() 0117 { 0118 qint32 totalSectors = 0; 0119 // we can't use LvmDevice method here because pv that is not in any VG will return 0 0120 m_ExtentSize = dialogWidget().spinPESize().value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); 0121 if (m_ExtentSize > 0) { 0122 totalSectors = m_TotalSize / m_ExtentSize; 0123 } 0124 dialogWidget().totalSectors().setText(QString::number(totalSectors)); 0125 } 0126 0127 void VolumeGroupDialog::updateSizeInfos() 0128 { 0129 const QVector<const Partition *> checkedPartitions = dialogWidget().listPV().checkedItems(); 0130 m_TotalSize = 0; 0131 for (const auto &p : checkedPartitions) 0132 m_TotalSize += p->capacity() - p->capacity() % (dialogWidget().spinPESize().value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB)); // subtract space which is too small to hold PE 0133 0134 dialogWidget().totalSize().setText(Capacity::formatByteSize(m_TotalSize)); 0135 0136 //Probably a bad design for updating state here; the state should be changed inside the update button function. 0137 m_IsValidSize = m_TotalSize >= m_TotalUsedSize; 0138 updateSectorInfos(); 0139 updateOkButtonStatus(); 0140 } 0141 0142 void VolumeGroupDialog::updatePartitionList() 0143 { 0144 } 0145 0146 void VolumeGroupDialog::onPartitionListChanged() 0147 { 0148 } 0149 0150 void VolumeGroupDialog::onVolumeTypeChanged(int index) 0151 { 0152 Q_UNUSED(index) 0153 updatePartitionList(); 0154 }