source: calamares/trunk/fuentes/src/modules/partition/gui/EditExistingPartitionDialog.cpp @ 7538

Last change on this file since 7538 was 7538, checked in by kbut, 13 months ago

sync with github

File size: 10.1 KB
Line 
1/* === This file is part of Calamares - <https://github.com/calamares> ===
2 *
3 *   Copyright 2014, Aurélien Gâteau <agateau@kde.org>
4 *   Copyright 2016, Teo Mrnjavac <teo@kde.org>
5 *
6 *   Flags handling originally from KDE Partition Manager,
7 *   Copyright 2008-2009, Volker Lanz <vl@fidra.de>
8 *   Copyright 2016,      Andrius Štikonas <andrius@stikonas.eu>
9 *
10 *   Calamares is free software: you can redistribute it and/or modify
11 *   it under the terms of the GNU General Public License as published by
12 *   the Free Software Foundation, either version 3 of the License, or
13 *   (at your option) any later version.
14 *
15 *   Calamares is distributed in the hope that it will be useful,
16 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *   GNU General Public License for more details.
19 *
20 *   You should have received a copy of the GNU General Public License
21 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <gui/EditExistingPartitionDialog.h>
25
26#include <core/ColorUtils.h>
27#include <core/PartitionCoreModule.h>
28#include <core/PartitionInfo.h>
29#include "core/PartUtils.h"
30#include <core/KPMHelpers.h>
31#include "gui/PartitionDialogHelpers.h"
32#include <gui/PartitionSizeController.h>
33
34#include <ui_EditExistingPartitionDialog.h>
35
36#include <utils/Logger.h>
37#include "GlobalStorage.h"
38#include "JobQueue.h"
39
40// KPMcore
41#include <kpmcore/core/device.h>
42#include <kpmcore/core/partition.h>
43#include <kpmcore/fs/filesystemfactory.h>
44
45// Qt
46#include <QComboBox>
47#include <QDir>
48#include <QPushButton>
49
50EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, Partition* partition, const QStringList& usedMountPoints, QWidget* parentWidget )
51    : QDialog( parentWidget )
52    , m_ui( new Ui_EditExistingPartitionDialog )
53    , m_device( device )
54    , m_partition( partition )
55    , m_partitionSizeController( new PartitionSizeController( this ) )
56    , m_usedMountPoints( usedMountPoints )
57{
58    m_ui->setupUi( this );
59    standardMountPoints( *(m_ui->mountPointComboBox), PartitionInfo::mountPoint( partition ) );
60
61    QColor color = ColorUtils::colorForPartition( m_partition );
62    m_partitionSizeController->init( m_device, m_partition, color );
63    m_partitionSizeController->setSpinBox( m_ui->sizeSpinBox );
64
65    connect( m_ui->mountPointComboBox, &QComboBox::currentTextChanged,
66             this, &EditExistingPartitionDialog::checkMountPointSelection );
67
68    replacePartResizerWidget();
69
70    connect( m_ui->formatRadioButton, &QAbstractButton::toggled,
71             [ this ]( bool doFormat )
72    {
73        replacePartResizerWidget();
74
75        m_ui->fileSystemLabel->setEnabled( doFormat );
76        m_ui->fileSystemComboBox->setEnabled( doFormat );
77
78        if ( !doFormat )
79            m_ui->fileSystemComboBox->setCurrentText( m_partition->fileSystem().name() );
80
81        updateMountPointPicker();
82    } );
83
84    connect( m_ui->fileSystemComboBox, &QComboBox::currentTextChanged,
85             [ this ]( QString )
86    {
87        updateMountPointPicker();
88    } );
89
90    // File system
91    QStringList fsNames;
92    for ( auto fs : FileSystemFactory::map() )
93    {
94        if ( fs->supportCreate() != FileSystem::cmdSupportNone && fs->type() != FileSystem::Extended )
95            fsNames << fs->name();
96    }
97    m_ui->fileSystemComboBox->addItems( fsNames );
98
99    if ( fsNames.contains( m_partition->fileSystem().name() ) )
100        m_ui->fileSystemComboBox->setCurrentText( m_partition->fileSystem().name() );
101    else
102        m_ui->fileSystemComboBox->setCurrentText( Calamares::JobQueue::instance()->
103                                                      globalStorage()->
104                                                      value( "defaultFileSystemType" ).toString() );
105
106    m_ui->fileSystemLabel->setEnabled( m_ui->formatRadioButton->isChecked() );
107    m_ui->fileSystemComboBox->setEnabled( m_ui->formatRadioButton->isChecked() );
108
109    setFlagList( *(m_ui->m_listFlags), m_partition->availableFlags(), PartitionInfo::flags( m_partition ) );
110}
111
112
113EditExistingPartitionDialog::~EditExistingPartitionDialog()
114{}
115
116
117PartitionTable::Flags
118EditExistingPartitionDialog::newFlags() const
119{
120    return flagsFromList( *(m_ui->m_listFlags) );
121}
122
123void
124EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
125{
126    PartitionInfo::setMountPoint( m_partition, selectedMountPoint(m_ui->mountPointComboBox) );
127
128    qint64 newFirstSector = m_partitionSizeController->firstSector();
129    qint64 newLastSector  = m_partitionSizeController->lastSector();
130    bool partResizedMoved = newFirstSector != m_partition->firstSector() ||
131                            newLastSector  != m_partition->lastSector();
132
133    cDebug() << "old boundaries:" << m_partition->firstSector()
134             << m_partition->lastSector() << m_partition->length();
135    cDebug() << "new boundaries:" << newFirstSector << newLastSector;
136    cDebug() << "dirty status:" << m_partitionSizeController->isDirty();
137
138    FileSystem::Type fsType = FileSystem::Unknown;
139    if ( m_ui->formatRadioButton->isChecked() )
140    {
141        fsType = m_partition->roles().has( PartitionRole::Extended )
142                ? FileSystem::Extended
143                : FileSystem::typeForName( m_ui->fileSystemComboBox->currentText() );
144    }
145
146    if ( partResizedMoved )
147    {
148        if ( m_ui->formatRadioButton->isChecked() )
149        {
150            Partition* newPartition = KPMHelpers::createNewPartition(
151                                          m_partition->parent(),
152                                          *m_device,
153                                          m_partition->roles(),
154                                          fsType,
155                                          newFirstSector,
156                                          newLastSector,
157                                          newFlags() );
158            PartitionInfo::setMountPoint( newPartition, PartitionInfo::mountPoint( m_partition ) );
159            PartitionInfo::setFormat( newPartition, true );
160
161            core->deletePartition( m_device, m_partition );
162            core->createPartition( m_device, newPartition );
163            core->setPartitionFlags( m_device, newPartition, newFlags() );
164        }
165        else
166        {
167            core->resizePartition( m_device,
168                                   m_partition,
169                                   newFirstSector,
170                                   newLastSector );
171            if ( m_partition->activeFlags() != newFlags() )
172                core->setPartitionFlags( m_device, m_partition, newFlags() );
173        }
174    }
175    else
176    {
177        // No size changes
178        if ( m_ui->formatRadioButton->isChecked() )
179        {
180            // if the FS type is unchanged, we just format
181            if ( m_partition->fileSystem().type() == fsType )
182            {
183                core->formatPartition( m_device, m_partition );
184                if ( m_partition->activeFlags() != newFlags() )
185                    core->setPartitionFlags( m_device, m_partition, newFlags() );
186            }
187            else // otherwise, we delete and recreate the partition with new fs type
188            {
189                Partition* newPartition = KPMHelpers::createNewPartition(
190                                              m_partition->parent(),
191                                              *m_device,
192                                              m_partition->roles(),
193                                              fsType,
194                                              m_partition->firstSector(),
195                                              m_partition->lastSector(),
196                                              newFlags() );
197                PartitionInfo::setMountPoint( newPartition, PartitionInfo::mountPoint( m_partition ) );
198                PartitionInfo::setFormat( newPartition, true );
199
200                core->deletePartition( m_device, m_partition );
201                core->createPartition( m_device, newPartition );
202                core->setPartitionFlags( m_device, newPartition, newFlags() );
203            }
204        }
205        else
206        {
207            core->refreshPartition( m_device, m_partition );
208            if ( m_partition->activeFlags() != newFlags() )
209                core->setPartitionFlags( m_device, m_partition, newFlags() );
210        }
211    }
212}
213
214
215void
216EditExistingPartitionDialog::replacePartResizerWidget()
217{
218    /*
219     * There is no way to reliably update the partition used by
220     * PartResizerWidget, which is necessary when we switch between "format" and
221     * "keep". This is a hack which replaces the existing PartResizerWidget
222     * with a new one.
223     */
224    PartResizerWidget* widget = new PartResizerWidget( this );
225
226    layout()->replaceWidget( m_ui->partResizerWidget, widget );
227    delete m_ui->partResizerWidget;
228    m_ui->partResizerWidget = widget;
229
230    m_partitionSizeController->setPartResizerWidget( widget, m_ui->formatRadioButton->isChecked() );
231}
232
233
234void
235EditExistingPartitionDialog::updateMountPointPicker()
236{
237    bool doFormat = m_ui->formatRadioButton->isChecked();
238    FileSystem::Type fsType = FileSystem::Unknown;
239    if ( doFormat )
240    {
241        fsType = FileSystem::typeForName( m_ui->fileSystemComboBox->currentText() );
242    }
243    else
244    {
245        fsType = m_partition->fileSystem().type();
246    }
247    bool canMount = true;
248    if ( fsType == FileSystem::Extended ||
249         fsType == FileSystem::LinuxSwap ||
250         fsType == FileSystem::Unformatted ||
251         fsType == FileSystem::Unknown ||
252         fsType == FileSystem::Lvm2_PV )
253    {
254        canMount = false;
255    }
256
257    m_ui->mountPointLabel->setEnabled( canMount );
258    m_ui->mountPointComboBox->setEnabled( canMount );
259    if ( !canMount )
260        setSelectedMountPoint( m_ui->mountPointComboBox, QString() );
261}
262
263void
264EditExistingPartitionDialog::checkMountPointSelection()
265{
266    if ( m_usedMountPoints.contains( selectedMountPoint( m_ui->mountPointComboBox ) ) )
267    {
268        m_ui->labelMountPoint->setText( tr( "Mountpoint already in use. Please select another one." ) );
269        m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
270    }
271    else
272    {
273        m_ui->labelMountPoint->setText( QString() );
274        m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true );
275    }
276}
Note: See TracBrowser for help on using the repository browser.