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

0001 /*
0002     SPDX-FileCopyrightText: 2008-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 
0006     SPDX-License-Identifier: GPL-3.0-or-later
0007 */
0008 
0009 #include "gui/resizedialog.h"
0010 #include "gui/sizedialogwidget.h"
0011 #include "gui/sizedetailswidget.h"
0012 
0013 #include <core/partition.h>
0014 #include <core/device.h>
0015 
0016 #include <fs/filesystem.h>
0017 #include <fs/luks2.h>
0018 
0019 #include <ops/resizeoperation.h>
0020 
0021 #include <util/capacity.h>
0022 
0023 #include <KConfigGroup>
0024 #include <KLocalizedString>
0025 #include <KPasswordDialog>
0026 #include <KSharedConfig>
0027 
0028 /** Creates a new ResizeDialog
0029     @param parent pointer to the parent widget
0030     @param d the Device the Partition to resize is on
0031     @param p the Partition to resize
0032     @param minFirst the first free sector before the Partition to resize
0033     @param maxLast the last free sector free after the Partition to resize
0034 */
0035 ResizeDialog::ResizeDialog(QWidget* parent, Device& d, Partition& p, qint64 minFirst, qint64 maxLast) :
0036     SizeDialogBase(parent, d, p, minFirst, maxLast),
0037     m_OriginalFirstSector(p.firstSector()),
0038     m_OriginalLastSector(p.lastSector()),
0039     m_ResizedFirstSector(p.firstSector()),
0040     m_ResizedLastSector(p.lastSector())
0041 {
0042     setWindowTitle(xi18nc("@title:window", "Resize/move partition: <filename>%1</filename>", partition().deviceNode()));
0043 
0044     dialogWidget().hideRole();
0045     dialogWidget().hideFileSystem();
0046     dialogWidget().hideLabel();
0047     dialogWidget().textLVName().hide();
0048     dialogWidget().lvName().hide();
0049 
0050     setupDialog();
0051     setupConstraints();
0052     setupConnections();
0053 
0054     KConfigGroup kcg(KSharedConfig::openConfig(), QStringLiteral("resizeDialog"));
0055     restoreGeometry(kcg.readEntry<QByteArray>("Geometry", QByteArray()));
0056 }
0057 
0058 /** Destroys a ResizeDialog */
0059 ResizeDialog::~ResizeDialog()
0060 {
0061     KConfigGroup kcg(KSharedConfig::openConfig(), QStringLiteral("resizeDialog"));
0062     kcg.writeEntry("Geometry", saveGeometry());
0063 }
0064 
0065 void ResizeDialog::rollback()
0066 {
0067     partition().setFirstSector(originalFirstSector());
0068     partition().fileSystem().setFirstSector(originalFirstSector());
0069 
0070     partition().setLastSector(originalLastSector());
0071     partition().fileSystem().setLastSector(originalLastSector());
0072 
0073     if (partition().roles().has(PartitionRole::Extended)) {
0074         device().partitionTable()->removeUnallocated(&partition());
0075         device().partitionTable()->insertUnallocated(device(), &partition(), partition().firstSector());
0076     }
0077 }
0078 
0079 void ResizeDialog::accept()
0080 {
0081     if (partition().roles().has(PartitionRole::Luks)) {
0082         FS::luks2* luksFs = dynamic_cast<FS::luks2*>(&partition().fileSystem());
0083         if (luksFs) {
0084             if (luksFs->keyLocation() == FS::luks::KeyLocation::keyring) {
0085                 bool validPassphrase = false;
0086                 QString errorMessage;
0087                 QString passphrase;
0088 
0089                 while  (!validPassphrase) {
0090                     KPasswordDialog dlg( this );
0091                     dlg.setPrompt(i18nc("%2 is either empty or says Invalid passphrase.", "%2Enter passphrase for %1:", partition().deviceNode(), errorMessage));
0092                     if (!dlg.exec()) {
0093                         reject();
0094                         return;
0095                     }
0096 
0097                     passphrase = dlg.password();
0098                     validPassphrase = luksFs->testPassphrase(partition().deviceNode(), passphrase);
0099                     if(!validPassphrase)
0100                         errorMessage = i18nc("Part of %2Enter passphrase for %1:", "Invalid passphrase. ");
0101                 }
0102                 luksFs->setPassphrase(passphrase);
0103             }
0104         }
0105     }
0106 
0107     setResizedFirstSector(partition().firstSector());
0108     setResizedLastSector(partition().lastSector());
0109 
0110     rollback();
0111     QDialog::accept();
0112 }
0113 
0114 void ResizeDialog::reject()
0115 {
0116     rollback();
0117     QDialog::reject();
0118 }
0119 
0120 void ResizeDialog::setupDialog()
0121 {
0122     SizeDialogBase::setupDialog();
0123     if (device().type() == Device::Type::LVM_Device) {
0124         dialogWidget().hideBeforeAndAfter();
0125         detailsWidget().checkAlign().setChecked(false);
0126         detailsWidget().checkAlign().setEnabled(false);
0127         detailsButton->hide();
0128     }
0129     okButton->setEnabled(false);
0130 }
0131 
0132 void ResizeDialog::setDirty()
0133 {
0134     okButton->setEnabled(isModified());
0135 }
0136 
0137 /** @return true if the user modified anything */
0138 bool ResizeDialog::isModified() const
0139 {
0140     return partition().firstSector() != originalFirstSector() || partition().lastSector() != originalLastSector();
0141 }
0142 
0143 bool ResizeDialog::canGrow() const
0144 {
0145     return ResizeOperation::canGrow(&partition());
0146 }
0147 
0148 bool ResizeDialog::canShrink() const
0149 {
0150     return ResizeOperation::canShrink(&partition());
0151 }
0152 
0153 bool ResizeDialog::canMove() const
0154 {
0155     return (device().type() == Device::Type::LVM_Device) ? false : ResizeOperation::canMove(&partition());
0156 }