2014-08-06 18:31:46 +02:00
|
|
|
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
|
|
|
*
|
|
|
|
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
|
2016-06-24 16:05:33 +02:00
|
|
|
* Copyright 2016, Teo Mrnjavac <teo@kde.org>
|
2014-08-06 18:31:46 +02:00
|
|
|
*
|
|
|
|
* Calamares is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Calamares is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2015-07-02 13:49:21 +02:00
|
|
|
#include "gui/PartitionSizeController.h"
|
2014-08-06 18:31:46 +02:00
|
|
|
|
2015-07-02 13:49:21 +02:00
|
|
|
#include "core/ColorUtils.h"
|
2015-09-18 15:41:07 +02:00
|
|
|
#include "core/KPMHelpers.h"
|
2014-08-07 17:26:26 +02:00
|
|
|
|
2014-08-06 18:31:46 +02:00
|
|
|
// Qt
|
|
|
|
#include <QSpinBox>
|
|
|
|
|
2015-07-02 13:49:21 +02:00
|
|
|
// KPMcore
|
|
|
|
#include <kpmcore/core/device.h>
|
|
|
|
#include <kpmcore/gui/partresizerwidget.h>
|
2014-08-06 18:31:46 +02:00
|
|
|
|
|
|
|
// stdc++
|
|
|
|
#include <limits>
|
|
|
|
|
|
|
|
PartitionSizeController::PartitionSizeController( QObject* parent )
|
|
|
|
: QObject( parent )
|
|
|
|
{}
|
|
|
|
|
|
|
|
void
|
2014-08-09 11:31:00 +02:00
|
|
|
PartitionSizeController::init( Device* device, Partition* partition, const QColor& color )
|
|
|
|
{
|
|
|
|
m_device = device;
|
|
|
|
m_originalPartition = partition;
|
|
|
|
// PartResizerWidget stores its changes directly in the partition it is
|
|
|
|
// initialized with. We don't want the changes to be committed that way,
|
|
|
|
// because it means we would have to revert them if the user cancel the
|
|
|
|
// dialog the widget is in. Therefore we init PartResizerWidget with a clone
|
|
|
|
// of the original partition.
|
2015-09-18 15:41:07 +02:00
|
|
|
m_partition.reset( KPMHelpers::clonePartition( m_device, partition ) );
|
2014-08-09 11:31:00 +02:00
|
|
|
m_partitionColor = color;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PartitionSizeController::setPartResizerWidget( PartResizerWidget* widget, bool format )
|
2014-08-06 18:31:46 +02:00
|
|
|
{
|
2014-08-09 11:31:00 +02:00
|
|
|
Q_ASSERT( m_device );
|
|
|
|
|
2014-08-06 18:31:46 +02:00
|
|
|
if ( m_partResizerWidget )
|
|
|
|
disconnect( m_partResizerWidget, 0, this, 0 );
|
2014-08-09 11:31:00 +02:00
|
|
|
|
2016-06-24 16:04:48 +02:00
|
|
|
m_dirty = false;
|
|
|
|
|
2014-08-09 11:31:00 +02:00
|
|
|
// Update partition filesystem. This must be done *before* the call to
|
|
|
|
// PartResizerWidget::init() otherwise it will be ignored by the widget.
|
|
|
|
// This is why this method accept a `format` boolean.
|
|
|
|
qint64 used = format ? 0 : m_originalPartition->fileSystem().sectorsUsed();
|
|
|
|
m_partition->fileSystem().setSectorsUsed( used );
|
|
|
|
|
|
|
|
// Init PartResizerWidget
|
2014-08-06 18:31:46 +02:00
|
|
|
m_partResizerWidget = widget;
|
2014-08-09 11:31:00 +02:00
|
|
|
PartitionTable* table = m_device->partitionTable();
|
|
|
|
qint64 minFirstSector = m_originalPartition->firstSector() - table->freeSectorsBefore( *m_originalPartition );
|
|
|
|
qint64 maxLastSector = m_originalPartition->lastSector() + table->freeSectorsAfter( *m_originalPartition );
|
|
|
|
m_partResizerWidget->init( *m_device, *m_partition.data(), minFirstSector, maxLastSector );
|
|
|
|
|
2014-08-06 18:31:46 +02:00
|
|
|
// FIXME: Should be set by PartResizerWidget itself
|
|
|
|
m_partResizerWidget->setFixedHeight( PartResizerWidget::handleHeight() );
|
2014-08-07 17:26:26 +02:00
|
|
|
|
|
|
|
QPalette pal = widget->palette();
|
|
|
|
pal.setColor( QPalette::Base, ColorUtils::freeSpaceColor() );
|
|
|
|
pal.setColor( QPalette::Button, m_partitionColor );
|
|
|
|
m_partResizerWidget->setPalette( pal );
|
2014-08-09 11:31:00 +02:00
|
|
|
connectWidgets();
|
|
|
|
|
|
|
|
if ( !format )
|
|
|
|
{
|
|
|
|
// If we are not formatting, update the widget to make sure the space
|
|
|
|
// between the first and last sectors is big enough to fit the existing
|
|
|
|
// content.
|
2016-06-24 16:04:48 +02:00
|
|
|
m_updating = true;
|
|
|
|
|
|
|
|
qint64 firstSector = m_partition->firstSector();
|
|
|
|
qint64 lastSector = m_partition->lastSector();
|
|
|
|
|
|
|
|
// This first time we call doAAUPRW with real first/last sector,
|
|
|
|
// all further calls will come from updatePartResizerWidget, and
|
|
|
|
// will therefore use values calculated from the SpinBox.
|
|
|
|
doAlignAndUpdatePartResizerWidget( firstSector, lastSector );
|
|
|
|
|
|
|
|
m_updating = false;
|
2014-08-09 11:31:00 +02:00
|
|
|
}
|
2014-08-06 18:31:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PartitionSizeController::setSpinBox( QSpinBox* spinBox )
|
|
|
|
{
|
|
|
|
if ( m_spinBox )
|
|
|
|
disconnect( m_spinBox, 0, this, 0 );
|
|
|
|
m_spinBox = spinBox;
|
|
|
|
m_spinBox->setMaximum( std::numeric_limits< int >::max() );
|
2014-08-09 11:31:00 +02:00
|
|
|
connectWidgets();
|
2014-08-06 18:31:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-08-09 11:31:00 +02:00
|
|
|
PartitionSizeController::connectWidgets()
|
2014-08-06 18:31:46 +02:00
|
|
|
{
|
|
|
|
if ( !m_spinBox || !m_partResizerWidget )
|
|
|
|
return;
|
|
|
|
|
|
|
|
connect( m_spinBox, SIGNAL( editingFinished() ), SLOT( updatePartResizerWidget() ) );
|
|
|
|
connect( m_partResizerWidget, SIGNAL( firstSectorChanged( qint64 ) ), SLOT( updateSpinBox() ) );
|
|
|
|
connect( m_partResizerWidget, SIGNAL( lastSectorChanged( qint64 ) ), SLOT( updateSpinBox() ) );
|
2014-08-09 11:31:00 +02:00
|
|
|
|
|
|
|
// Init m_spinBox from m_partResizerWidget
|
2014-08-06 18:31:46 +02:00
|
|
|
updateSpinBox();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PartitionSizeController::updatePartResizerWidget()
|
|
|
|
{
|
|
|
|
if ( m_updating )
|
|
|
|
return;
|
|
|
|
m_updating = true;
|
|
|
|
qint64 sectorSize = qint64( m_spinBox->value() ) * 1024 * 1024 / m_device->logicalSectorSize();
|
|
|
|
|
|
|
|
qint64 firstSector = m_partition->firstSector();
|
|
|
|
qint64 lastSector = firstSector + sectorSize - 1;
|
2016-06-24 16:04:48 +02:00
|
|
|
|
|
|
|
doAlignAndUpdatePartResizerWidget( firstSector, lastSector );
|
|
|
|
|
|
|
|
m_updating = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PartitionSizeController::doAlignAndUpdatePartResizerWidget( qint64 firstSector,
|
|
|
|
qint64 lastSector )
|
|
|
|
{
|
2014-08-06 18:31:46 +02:00
|
|
|
if ( lastSector > m_partResizerWidget->maximumLastSector() )
|
|
|
|
{
|
|
|
|
qint64 delta = lastSector - m_partResizerWidget->maximumLastSector();
|
|
|
|
firstSector -= delta;
|
|
|
|
lastSector -= delta;
|
|
|
|
}
|
2016-06-24 16:04:48 +02:00
|
|
|
if ( lastSector != m_partition->lastSector() )
|
|
|
|
{
|
|
|
|
m_partResizerWidget->updateLastSector( lastSector );
|
|
|
|
m_dirty = true;
|
|
|
|
}
|
|
|
|
if ( firstSector != m_partition->firstSector() )
|
|
|
|
{
|
|
|
|
m_partResizerWidget->updateFirstSector( firstSector );
|
|
|
|
m_dirty = true;
|
|
|
|
}
|
2014-08-06 18:31:46 +02:00
|
|
|
|
|
|
|
// Update spinbox value in case it was an impossible value
|
|
|
|
doUpdateSpinBox();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PartitionSizeController::updateSpinBox()
|
|
|
|
{
|
|
|
|
if ( m_updating )
|
|
|
|
return;
|
|
|
|
m_updating = true;
|
|
|
|
doUpdateSpinBox();
|
|
|
|
m_updating = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PartitionSizeController::doUpdateSpinBox()
|
|
|
|
{
|
2014-08-09 11:31:00 +02:00
|
|
|
if ( !m_spinBox )
|
|
|
|
return;
|
2016-06-24 15:10:20 +02:00
|
|
|
qint64 mbSize = m_partition->length() * m_device->logicalSectorSize() / 1024 / 1024;
|
2014-08-06 18:31:46 +02:00
|
|
|
m_spinBox->setValue( mbSize );
|
|
|
|
}
|
2014-08-09 11:31:00 +02:00
|
|
|
|
|
|
|
qint64
|
|
|
|
PartitionSizeController::firstSector() const
|
|
|
|
{
|
|
|
|
return m_partition->firstSector();
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64
|
|
|
|
PartitionSizeController::lastSector() const
|
|
|
|
{
|
|
|
|
return m_partition->lastSector();
|
|
|
|
}
|
2016-06-24 16:04:48 +02:00
|
|
|
|
|
|
|
bool
|
|
|
|
PartitionSizeController::isDirty() const
|
|
|
|
{
|
|
|
|
return m_dirty;
|
|
|
|
}
|