2015-07-08 17:16:57 +01:00
/*************************************************************************
* Copyright ( C ) 2008 , 2010 by Volker Lanz < vl @ fidra . de > *
* *
* This program 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 . *
* *
* This program 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 this program . If not , see < http : //www.gnu.org/licenses/>.*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "gui/partresizerwidget.h"
# include "gui/partwidget.h"
# include "core/partition.h"
# include "core/device.h"
# include "core/partitiontable.h"
# include "core/partitionalignment.h"
# include "fs/filesystem.h"
2017-09-11 13:41:03 +01:00
# include <algorithm>
2015-07-08 17:16:57 +01:00
# include <QDebug>
# include <QPainter>
# include <QMouseEvent>
# include <QPaintEvent>
# include <QResizeEvent>
# include <QStyleOptionToolBar>
2016-07-06 20:44:32 +01:00
# include <QStyleOptionFrame>
2015-07-08 17:16:57 +01:00
# include <QStyleOptionButton>
const qint32 PartResizerWidget : : m_HandleHeight = 59 ;
/** Creates a new PartResizerWidget
2015-07-13 15:16:36 +01:00
Initializing is mostly done in init ( ) .
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
@ param parent pointer to the parent widget
2015-07-08 17:16:57 +01:00
*/
PartResizerWidget : : PartResizerWidget ( QWidget * parent ) :
2015-07-13 15:16:36 +01:00
QWidget ( parent ) ,
2015-07-22 14:48:03 +01:00
m_Device ( nullptr ) ,
m_Partition ( nullptr ) ,
m_PartWidget ( nullptr ) ,
2015-07-13 15:16:36 +01:00
m_MinimumFirstSector ( 0 ) ,
m_MaximumFirstSector ( - 1 ) ,
m_MinimumLastSector ( - 1 ) ,
m_MaximumLastSector ( 0 ) ,
m_MinimumLength ( - 1 ) ,
m_MaximumLength ( - 1 ) ,
m_LeftHandle ( this ) ,
m_RightHandle ( this ) ,
2015-07-22 14:48:03 +01:00
m_DraggedWidget ( nullptr ) ,
2015-07-13 15:16:36 +01:00
m_Hotspot ( 0 ) ,
m_MoveAllowed ( true ) ,
m_ReadOnly ( false ) ,
m_Align ( true )
2015-07-08 17:16:57 +01:00
{
}
/** Intializes the PartResizerWidget
2015-07-13 15:16:36 +01:00
@ param d the Device the Partition is on
@ param p the Partition to show and / or resize
@ param minFirst the minimum value for the first sector
@ param maxLast the maximum value for the last sector
2015-07-08 17:16:57 +01:00
*/
void PartResizerWidget : : init ( Device & d , Partition & p , qint64 minFirst , qint64 maxLast , bool read_only , bool move_allowed )
{
2015-07-13 15:16:36 +01:00
setDevice ( d ) ;
setPartition ( p ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
setMinimumFirstSector ( minFirst ) ;
setMaximumLastSector ( maxLast ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
setReadOnly ( read_only ) ;
setMoveAllowed ( move_allowed ) ;
2015-07-08 17:16:57 +01:00
2017-09-11 13:41:03 +01:00
setMinimumLength ( std : : max ( partition ( ) . sectorsUsed ( ) , partition ( ) . minimumSectors ( ) ) ) ;
setMaximumLength ( std : : min ( totalSectors ( ) , partition ( ) . maximumSectors ( ) ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
// set margins to accommodate to top/bottom button asymmetric layouts
QStyleOptionButton bOpt ;
bOpt . initFrom ( this ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
QRect buttonRect ( style ( ) - > subElementRect ( QStyle : : SE_PushButtonContents , & bOpt ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
int asym = ( rect ( ) . bottom ( ) - buttonRect . bottom ( ) ) - ( buttonRect . top ( ) - rect ( ) . top ( ) ) ;
if ( asym > 0 )
setContentsMargins ( 0 , asym , 0 , 0 ) ;
else
setContentsMargins ( 0 , 0 , 0 , asym ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( ! readOnly ( ) ) {
QPixmap pixmap ( handleWidth ( ) , handleHeight ( ) ) ;
pixmap . fill ( Qt : : transparent ) ;
2017-09-11 12:01:39 +01:00
QPainter painter ( & pixmap ) ;
2015-07-13 15:16:36 +01:00
QStyleOption opt ;
opt . state | = QStyle : : State_Horizontal ;
opt . rect = pixmap . rect ( ) . adjusted ( 0 , 2 , 0 , - 2 ) ;
2017-09-11 12:01:39 +01:00
style ( ) - > drawControl ( QStyle : : CE_Splitter , & opt , & painter , this ) ;
2015-07-08 17:16:57 +01:00
2016-12-31 10:34:38 +00:00
if ( moveAllowed ( ) )
leftHandle ( ) . setPixmap ( pixmap ) ;
2015-07-13 15:16:36 +01:00
rightHandle ( ) . setPixmap ( pixmap ) ;
2015-07-08 17:16:57 +01:00
2016-12-31 10:34:38 +00:00
if ( moveAllowed ( ) )
leftHandle ( ) . setFixedSize ( handleWidth ( ) , handleHeight ( ) ) ;
2015-07-13 15:16:36 +01:00
rightHandle ( ) . setFixedSize ( handleWidth ( ) , handleHeight ( ) ) ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
delete m_PartWidget ;
m_PartWidget = new PartWidget ( this , & partition ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( ! readOnly ( ) ) {
2016-05-18 12:30:44 +01:00
if ( moveAllowed ( ) )
leftHandle ( ) . setCursor ( Qt : : SizeHorCursor ) ;
2015-07-13 15:16:36 +01:00
rightHandle ( ) . setCursor ( Qt : : SizeHorCursor ) ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( moveAllowed ( ) )
partWidget ( ) . setCursor ( Qt : : SizeAllCursor ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
partWidget ( ) . setToolTip ( QString ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
updatePositions ( ) ;
2015-07-08 17:16:57 +01:00
}
qint32 PartResizerWidget : : handleWidth ( ) const
{
2015-07-13 15:16:36 +01:00
return style ( ) - > pixelMetric ( QStyle : : PM_SplitterWidth ) ;
2015-07-08 17:16:57 +01:00
}
2016-07-18 15:08:42 +01:00
long double PartResizerWidget : : sectorsPerPixel ( ) const
2015-07-08 17:16:57 +01:00
{
2016-07-18 15:08:42 +01:00
return totalSectors ( ) / ( width ( ) - 2.0 L * handleWidth ( ) ) ;
2015-07-08 17:16:57 +01:00
}
int PartResizerWidget : : partWidgetStart ( ) const
{
2017-09-11 13:41:03 +01:00
return static_cast < int > ( handleWidth ( ) + ( partition ( ) . firstSector ( ) - minimumFirstSector ( ) ) / sectorsPerPixel ( ) ) ;
2015-07-08 17:16:57 +01:00
}
int PartResizerWidget : : partWidgetWidth ( ) const
{
2017-09-11 13:41:03 +01:00
return static_cast < int > ( partition ( ) . length ( ) / sectorsPerPixel ( ) ) ;
2015-07-08 17:16:57 +01:00
}
void PartResizerWidget : : updatePositions ( )
{
2015-07-13 15:16:36 +01:00
QMargins margins ( contentsMargins ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
partWidget ( ) . move ( partWidgetStart ( ) + margins . left ( ) , margins . top ( ) ) ;
partWidget ( ) . resize ( partWidgetWidth ( ) - margins . left ( ) - margins . right ( ) , height ( ) - margins . top ( ) - margins . bottom ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
leftHandle ( ) . move ( partWidgetStart ( ) - leftHandle ( ) . width ( ) , 0 ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
rightHandle ( ) . move ( partWidgetStart ( ) + partWidgetWidth ( ) , 0 ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
partWidget ( ) . update ( ) ;
2015-07-08 17:16:57 +01:00
}
void PartResizerWidget : : resizeEvent ( QResizeEvent * event )
{
2015-07-13 15:16:36 +01:00
updatePositions ( ) ;
QWidget : : resizeEvent ( event ) ;
2015-07-08 17:16:57 +01:00
}
void PartResizerWidget : : paintEvent ( QPaintEvent * )
{
2015-07-13 15:16:36 +01:00
// draw sunken frame
QPainter painter ( this ) ;
2016-07-06 20:44:32 +01:00
QStyleOptionFrame opt ;
2015-07-13 15:16:36 +01:00
opt . initFrom ( this ) ;
opt . frameShape = QFrame : : StyledPanel ;
opt . rect = contentsRect ( ) ;
opt . lineWidth = style ( ) - > pixelMetric ( QStyle : : PM_DefaultFrameWidth , & opt , this ) ;
opt . midLineWidth = 0 ;
opt . state | = QStyle : : State_Sunken ;
style ( ) - > drawPrimitive ( QStyle : : PE_PanelLineEdit , & opt , & painter , this ) ;
2015-07-08 17:16:57 +01:00
}
void PartResizerWidget : : mousePressEvent ( QMouseEvent * event )
{
2015-07-13 15:16:36 +01:00
if ( event - > button ( ) = = Qt : : LeftButton ) {
m_DraggedWidget = static_cast < QWidget * > ( childAt ( event - > pos ( ) ) ) ;
2015-07-22 14:48:03 +01:00
if ( m_DraggedWidget ! = nullptr ) {
2015-07-13 15:16:36 +01:00
if ( partWidget ( ) . isAncestorOf ( m_DraggedWidget ) )
m_DraggedWidget = & partWidget ( ) ;
m_Hotspot = m_DraggedWidget - > mapFromParent ( event - > pos ( ) ) . x ( ) ;
}
}
2015-07-08 17:16:57 +01:00
}
bool PartResizerWidget : : checkConstraints ( qint64 first , qint64 last ) const
{
2015-07-13 15:16:36 +01:00
return ( maximumFirstSector ( ) = = - 1 | | first < = maximumFirstSector ( ) ) & &
( minimumFirstSector ( ) = = 0 | | first > = minimumFirstSector ( ) ) & &
( minimumLastSector ( ) = = - 1 | | last > = minimumLastSector ( ) ) & &
( maximumLastSector ( ) = = 0 | | last < = maximumLastSector ( ) ) ;
2015-07-08 17:16:57 +01:00
}
bool PartResizerWidget : : movePartition ( qint64 newFirstSector )
{
2015-07-13 15:16:36 +01:00
const qint64 originalLength = partition ( ) . length ( ) ;
const bool isLengthAligned = PartitionAlignment : : isLengthAligned ( device ( ) , partition ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( maximumFirstSector ( align ( ) ) > - 1 & & newFirstSector > maximumFirstSector ( align ( ) ) )
newFirstSector = maximumFirstSector ( align ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( minimumFirstSector ( align ( ) ) > 0 & & newFirstSector < minimumFirstSector ( align ( ) ) )
newFirstSector = minimumFirstSector ( align ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( align ( ) )
newFirstSector = PartitionAlignment : : alignedFirstSector ( device ( ) , partition ( ) , newFirstSector , minimumFirstSector ( align ( ) ) , maximumFirstSector ( align ( ) ) , - 1 , - 1 ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
qint64 delta = newFirstSector - partition ( ) . firstSector ( ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( delta = = 0 )
return false ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
qint64 newLastSector = partition ( ) . lastSector ( ) + delta ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( minimumLastSector ( align ( ) ) > - 1 & & newLastSector < minimumLastSector ( align ( ) ) ) {
const qint64 deltaLast = minimumLastSector ( align ( ) ) - newLastSector ;
newFirstSector + = deltaLast ;
newLastSector + = deltaLast ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( maximumLastSector ( align ( ) ) > 0 & & newLastSector > maximumLastSector ( align ( ) ) ) {
const qint64 deltaLast = newLastSector - maximumLastSector ( align ( ) ) ;
newFirstSector - = deltaLast ;
newLastSector - = deltaLast ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( align ( ) )
newLastSector = PartitionAlignment : : alignedLastSector ( device ( ) , partition ( ) , newLastSector , minimumLastSector ( align ( ) ) , maximumLastSector ( align ( ) ) , - 1 , - 1 , originalLength , isLengthAligned ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( newLastSector = = partition ( ) . lastSector ( ) )
return false ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( isLengthAligned & & newLastSector - newFirstSector + 1 ! = partition ( ) . length ( ) ) {
qDebug ( ) < < " length changes while trying to move partition " < < partition ( ) . deviceNode ( ) < < " . new first: " < < newFirstSector < < " , new last: " < < newLastSector < < " , old length: " < < partition ( ) . length ( ) < < " , new length: " < < newLastSector - newFirstSector + 1 ;
return false ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( ! checkConstraints ( newFirstSector , newLastSector ) ) {
qDebug ( ) < < " constraints not satisfied while trying to move partition " < < partition ( ) . deviceNode ( ) < < " . new first: " < < newFirstSector < < " , new last: " < < newLastSector ;
return false ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( align ( ) & & ! PartitionAlignment : : isAligned ( device ( ) , partition ( ) , newFirstSector , newLastSector , true ) ) {
qDebug ( ) < < " partition " < < partition ( ) . deviceNode ( ) < < " not aligned but supposed to be. new first: " < < newFirstSector < < " delta: " < < PartitionAlignment : : firstDelta ( device ( ) , partition ( ) , newFirstSector ) < < " , new last: " < < newLastSector < < " , delta: " < < PartitionAlignment : : lastDelta ( device ( ) , partition ( ) , newLastSector ) ;
return false ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( partition ( ) . children ( ) . size ( ) > 0 & &
( ! checkAlignment ( * partition ( ) . children ( ) . first ( ) , partition ( ) . firstSector ( ) - newFirstSector ) | |
! checkAlignment ( * partition ( ) . children ( ) . last ( ) , partition ( ) . lastSector ( ) - newLastSector ) ) ) {
qDebug ( ) < < " cannot align children while trying to move partition " < < partition ( ) . deviceNode ( ) ;
return false ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
partition ( ) . setFirstSector ( newFirstSector ) ;
partition ( ) . fileSystem ( ) . setFirstSector ( newFirstSector ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
partition ( ) . setLastSector ( newLastSector ) ;
partition ( ) . fileSystem ( ) . setLastSector ( newLastSector ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
updatePositions ( ) ;
2015-07-08 17:16:57 +01:00
2020-09-15 02:36:46 +01:00
Q_EMIT firstSectorChanged ( partition ( ) . firstSector ( ) ) ;
Q_EMIT lastSectorChanged ( partition ( ) . lastSector ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
return true ;
2015-07-08 17:16:57 +01:00
}
void PartResizerWidget : : mouseMoveEvent ( QMouseEvent * event )
{
2015-07-13 15:16:36 +01:00
int x = event - > pos ( ) . x ( ) - m_Hotspot ;
if ( draggedWidget ( ) = = & leftHandle ( ) ) {
2017-09-11 13:41:03 +01:00
const qint64 newFirstSector = static_cast < qint64 > ( std : : max ( minimumFirstSector ( ) + x * sectorsPerPixel ( ) , 0.0 L ) ) ;
2015-07-13 15:16:36 +01:00
updateFirstSector ( newFirstSector ) ;
} else if ( draggedWidget ( ) = = & rightHandle ( ) ) {
2017-09-11 13:41:03 +01:00
const qint64 newLastSector = static_cast < qint64 > ( std : : min ( static_cast < qint64 > ( minimumFirstSector ( ) + ( x - rightHandle ( ) . width ( ) ) * sectorsPerPixel ( ) ) , maximumLastSector ( ) ) ) ;
2015-07-13 15:16:36 +01:00
updateLastSector ( newLastSector ) ;
} else if ( draggedWidget ( ) = = & partWidget ( ) & & moveAllowed ( ) ) {
2017-09-11 13:41:03 +01:00
const qint64 newFirstSector = static_cast < qint64 > ( std : : max ( minimumFirstSector ( ) + ( x - handleWidth ( ) ) * sectorsPerPixel ( ) , 0.0 L ) ) ;
2015-07-13 15:16:36 +01:00
movePartition ( newFirstSector ) ;
}
2015-07-08 17:16:57 +01:00
}
void PartResizerWidget : : mouseReleaseEvent ( QMouseEvent * event )
{
2015-07-13 15:16:36 +01:00
if ( event - > button ( ) = = Qt : : LeftButton )
2015-07-22 14:48:03 +01:00
m_DraggedWidget = nullptr ;
2015-07-08 17:16:57 +01:00
}
bool PartResizerWidget : : updateFirstSector ( qint64 newFirstSector )
{
2015-07-13 15:16:36 +01:00
if ( maximumFirstSector ( align ( ) ) > - 1 & & newFirstSector > maximumFirstSector ( align ( ) ) )
newFirstSector = maximumFirstSector ( align ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( minimumFirstSector ( align ( ) ) > 0 & & newFirstSector < minimumFirstSector ( align ( ) ) )
newFirstSector = minimumFirstSector ( align ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
const qint64 newLength = partition ( ) . lastSector ( ) - newFirstSector + 1 ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( newLength < minimumLength ( ) )
newFirstSector - = minimumLength ( ) - newLength ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( newLength > maximumLength ( ) )
newFirstSector - = newLength - maximumLength ( ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( align ( ) )
newFirstSector = PartitionAlignment : : alignedFirstSector ( device ( ) , partition ( ) , newFirstSector , minimumFirstSector ( align ( ) ) , maximumFirstSector ( align ( ) ) , minimumLength ( ) , maximumLength ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( newFirstSector ! = partition ( ) . firstSector ( ) & & ( partition ( ) . children ( ) . size ( ) = = 0 | | checkAlignment ( * partition ( ) . children ( ) . first ( ) , partition ( ) . firstSector ( ) - newFirstSector ) ) ) {
const qint64 deltaFirst = partition ( ) . firstSector ( ) - newFirstSector ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
partition ( ) . setFirstSector ( newFirstSector ) ;
partition ( ) . fileSystem ( ) . setFirstSector ( newFirstSector ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
resizeLogicals ( deltaFirst , 0 ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
updatePositions ( ) ;
2015-07-08 17:16:57 +01:00
2020-09-15 02:36:46 +01:00
Q_EMIT firstSectorChanged ( partition ( ) . firstSector ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
return true ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
return false ;
2015-07-08 17:16:57 +01:00
}
bool PartResizerWidget : : checkAlignment ( const Partition & child , qint64 delta ) const
{
2015-07-13 15:16:36 +01:00
// TODO: what is this exactly good for? and is it correct in non-cylinder-aligned
// situations?
if ( ! partition ( ) . roles ( ) . has ( PartitionRole : : Extended ) )
return true ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( child . roles ( ) . has ( PartitionRole : : Unallocated ) )
return true ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
return qAbs ( delta ) > = PartitionAlignment : : sectorAlignment ( device ( ) ) ;
2015-07-08 17:16:57 +01:00
}
void PartResizerWidget : : resizeLogicals ( qint64 deltaFirst , qint64 deltaLast , bool force )
{
2015-07-13 15:16:36 +01:00
if ( deltaFirst ! = 0 & & partition ( ) . children ( ) . size ( ) > 0 & & partition ( ) . children ( ) . first ( ) - > roles ( ) . has ( PartitionRole : : Unallocated ) ) {
qint64 start = partition ( ) . children ( ) . first ( ) - > firstSector ( ) - deltaFirst ;
qint64 end = partition ( ) . children ( ) . first ( ) - > lastSector ( ) + deltaLast ;
if ( PartitionTable : : getUnallocatedRange ( device ( ) , partition ( ) , start , end ) ) {
partition ( ) . children ( ) . first ( ) - > setFirstSector ( start ) ;
deltaFirst = 0 ;
}
}
if ( deltaLast ! = 0 & & partition ( ) . children ( ) . size ( ) > 0 & & partition ( ) . children ( ) . last ( ) - > roles ( ) . has ( PartitionRole : : Unallocated ) ) {
qint64 start = partition ( ) . children ( ) . last ( ) - > firstSector ( ) - deltaFirst ;
qint64 end = partition ( ) . children ( ) . last ( ) - > lastSector ( ) + deltaLast ;
if ( PartitionTable : : getUnallocatedRange ( device ( ) , partition ( ) , start , end ) ) {
partition ( ) . children ( ) . last ( ) - > setLastSector ( end ) ;
deltaLast = 0 ;
}
}
if ( force | | deltaFirst ! = 0 | | deltaLast ! = 0 ) {
Q_ASSERT ( device ( ) . partitionTable ( ) ) ;
device ( ) . partitionTable ( ) - > removeUnallocated ( & partition ( ) ) ;
if ( partition ( ) . roles ( ) . has ( PartitionRole : : Extended ) )
device ( ) . partitionTable ( ) - > insertUnallocated ( device ( ) , & partition ( ) , partition ( ) . firstSector ( ) ) ;
}
partWidget ( ) . updateChildren ( ) ;
2015-07-08 17:16:57 +01:00
}
bool PartResizerWidget : : updateLastSector ( qint64 newLastSector )
{
2015-07-13 15:16:36 +01:00
if ( minimumLastSector ( align ( ) ) > - 1 & & newLastSector < minimumLastSector ( align ( ) ) )
newLastSector = minimumLastSector ( align ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( maximumLastSector ( align ( ) ) > 0 & & newLastSector > maximumLastSector ( align ( ) ) )
newLastSector = maximumLastSector ( align ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
const qint64 newLength = newLastSector - partition ( ) . firstSector ( ) + 1 ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( newLength < minimumLength ( ) )
newLastSector + = minimumLength ( ) - newLength ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( newLength > maximumLength ( ) )
newLastSector - = newLength - maximumLength ( ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( align ( ) )
newLastSector = PartitionAlignment : : alignedLastSector ( device ( ) , partition ( ) , newLastSector , minimumLastSector ( align ( ) ) , maximumLastSector ( align ( ) ) , minimumLength ( ) , maximumLength ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
if ( newLastSector ! = partition ( ) . lastSector ( ) & & ( partition ( ) . children ( ) . size ( ) = = 0 | | checkAlignment ( * partition ( ) . children ( ) . last ( ) , partition ( ) . lastSector ( ) - newLastSector ) ) ) {
const qint64 deltaLast = newLastSector - partition ( ) . lastSector ( ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
partition ( ) . setLastSector ( newLastSector ) ;
partition ( ) . fileSystem ( ) . setLastSector ( newLastSector ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
resizeLogicals ( 0 , deltaLast ) ;
updatePositions ( ) ;
2015-07-08 17:16:57 +01:00
2020-09-15 02:36:46 +01:00
Q_EMIT lastSectorChanged ( partition ( ) . lastSector ( ) ) ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
return true ;
}
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
return false ;
2015-07-08 17:16:57 +01:00
}
/** Sets the minimum sectors the Partition can be long.
2015-07-13 15:16:36 +01:00
@ note This value can never be less than 0 and never be higher than totalSectors ( )
@ param s the new minimum length
2015-07-08 17:16:57 +01:00
*/
void PartResizerWidget : : setMinimumLength ( qint64 s )
{
2015-07-13 15:16:36 +01:00
m_MinimumLength = qBound ( 0LL , s , totalSectors ( ) ) ;
2015-07-08 17:16:57 +01:00
}
/** Sets the maximum sectors the Partition can be long.
2015-07-13 15:16:36 +01:00
@ note This value can never be less than 0 and never by higher than totalSectors ( )
@ param s the new maximum length
2015-07-08 17:16:57 +01:00
*/
void PartResizerWidget : : setMaximumLength ( qint64 s )
{
2015-07-13 15:16:36 +01:00
m_MaximumLength = qBound ( 0LL , s , totalSectors ( ) ) ;
2015-07-08 17:16:57 +01:00
}
/** Sets if moving the Partition is allowed.
2015-07-13 15:16:36 +01:00
@ param b true if moving is allowed
2015-07-08 17:16:57 +01:00
*/
void PartResizerWidget : : setMoveAllowed ( bool b )
{
2015-07-13 15:16:36 +01:00
m_MoveAllowed = b ;
2015-07-08 17:16:57 +01:00
2015-07-22 14:48:03 +01:00
if ( m_PartWidget ! = nullptr )
2015-07-13 15:16:36 +01:00
partWidget ( ) . setCursor ( b ? Qt : : SizeAllCursor : Qt : : ArrowCursor ) ;
2015-07-08 17:16:57 +01:00
}
qint64 PartResizerWidget : : minimumFirstSector ( bool aligned ) const
{
2015-07-13 15:16:36 +01:00
if ( ! aligned | | PartitionAlignment : : firstDelta ( device ( ) , partition ( ) , m_MinimumFirstSector ) = = 0 )
return m_MinimumFirstSector ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
return m_MinimumFirstSector - PartitionAlignment : : firstDelta ( device ( ) , partition ( ) , m_MinimumFirstSector ) + PartitionAlignment : : sectorAlignment ( device ( ) ) ;
2015-07-08 17:16:57 +01:00
}
qint64 PartResizerWidget : : maximumFirstSector ( bool aligned ) const
{
2015-07-13 15:16:36 +01:00
return ( m_MaximumFirstSector ! = - 1 & & aligned )
? m_MaximumFirstSector - PartitionAlignment : : firstDelta ( device ( ) , partition ( ) , m_MaximumFirstSector )
: m_MaximumFirstSector ;
2015-07-08 17:16:57 +01:00
}
qint64 PartResizerWidget : : minimumLastSector ( bool aligned ) const
{
2015-07-13 15:16:36 +01:00
if ( ! aligned | | PartitionAlignment : : lastDelta ( device ( ) , partition ( ) , m_MinimumLastSector ) = = 1 )
return m_MinimumLastSector ;
2015-07-08 17:16:57 +01:00
2015-07-13 15:16:36 +01:00
return m_MinimumLastSector - PartitionAlignment : : lastDelta ( device ( ) , partition ( ) , m_MinimumLastSector ) + 1 + PartitionAlignment : : sectorAlignment ( device ( ) ) ;
2015-07-08 17:16:57 +01:00
}
qint64 PartResizerWidget : : maximumLastSector ( bool aligned ) const
{
2015-07-13 15:16:36 +01:00
return ( m_MaximumLastSector ! = 0 & & aligned )
? m_MaximumLastSector - PartitionAlignment : : lastDelta ( device ( ) , partition ( ) , m_MaximumLastSector )
: m_MaximumLastSector ;
2015-07-08 17:16:57 +01:00
}