|
|
|
|
@ -20,31 +20,33 @@
|
|
|
|
|
#include "ChoicePage.h"
|
|
|
|
|
|
|
|
|
|
#include "core/BootLoaderModel.h"
|
|
|
|
|
#include "core/PartitionActions.h"
|
|
|
|
|
#include "core/PartitionCoreModule.h"
|
|
|
|
|
#include "core/DeviceModel.h"
|
|
|
|
|
#include "core/PartitionModel.h"
|
|
|
|
|
#include "core/KPMHelpers.h"
|
|
|
|
|
#include "core/OsproberEntry.h"
|
|
|
|
|
#include "core/PartUtils.h"
|
|
|
|
|
#include "core/PartitionActions.h"
|
|
|
|
|
#include "core/PartitionCoreModule.h"
|
|
|
|
|
#include "core/PartitionInfo.h"
|
|
|
|
|
#include "core/PartitionIterator.h"
|
|
|
|
|
#include "core/PartitionModel.h"
|
|
|
|
|
|
|
|
|
|
#include "ReplaceWidget.h"
|
|
|
|
|
#include "PrettyRadioButton.h"
|
|
|
|
|
#include "BootInfoWidget.h"
|
|
|
|
|
#include "DeviceInfoWidget.h"
|
|
|
|
|
#include "PartitionBarsView.h"
|
|
|
|
|
#include "PartitionLabelsView.h"
|
|
|
|
|
#include "PartitionSplitterWidget.h"
|
|
|
|
|
#include "BootInfoWidget.h"
|
|
|
|
|
#include "DeviceInfoWidget.h"
|
|
|
|
|
#include "PrettyRadioButton.h"
|
|
|
|
|
#include "ReplaceWidget.h"
|
|
|
|
|
#include "ScanningDialog.h"
|
|
|
|
|
|
|
|
|
|
#include "utils/CalamaresUtilsGui.h"
|
|
|
|
|
#include "utils/Logger.h"
|
|
|
|
|
#include "utils/Retranslator.h"
|
|
|
|
|
#include "utils/Units.h"
|
|
|
|
|
|
|
|
|
|
#include "Branding.h"
|
|
|
|
|
#include "core/KPMHelpers.h"
|
|
|
|
|
#include "JobQueue.h"
|
|
|
|
|
#include "GlobalStorage.h"
|
|
|
|
|
#include "core/PartitionInfo.h"
|
|
|
|
|
#include "JobQueue.h"
|
|
|
|
|
|
|
|
|
|
#include <kpmcore/core/device.h>
|
|
|
|
|
#include <kpmcore/core/partition.h>
|
|
|
|
|
@ -61,7 +63,7 @@
|
|
|
|
|
#include <QFutureWatcher>
|
|
|
|
|
#include <QtConcurrent/QtConcurrent>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using PartitionActions::Choices::SwapChoice;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief ChoicePage::ChoicePage is the default constructor. Called on startup as part of
|
|
|
|
|
@ -81,6 +83,9 @@ ChoicePage::ChoicePage( QWidget* parent )
|
|
|
|
|
, m_eraseButton( nullptr )
|
|
|
|
|
, m_replaceButton( nullptr )
|
|
|
|
|
, m_somethingElseButton( nullptr )
|
|
|
|
|
, m_eraseSwapChoices( nullptr )
|
|
|
|
|
, m_replaceSwapChoices( nullptr )
|
|
|
|
|
, m_alongsideSwapChoices( nullptr )
|
|
|
|
|
, m_deviceInfoWidget( nullptr )
|
|
|
|
|
, m_beforePartitionBarsView( nullptr )
|
|
|
|
|
, m_beforePartitionLabelsView( nullptr )
|
|
|
|
|
@ -176,6 +181,19 @@ ChoicePage::init( PartitionCoreModule* core )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @brief Creates a combobox with the given choices in it.
|
|
|
|
|
*
|
|
|
|
|
* No texts are set -- that happens later by the translator functions.
|
|
|
|
|
*/
|
|
|
|
|
static inline QComboBox*
|
|
|
|
|
createCombo( std::initializer_list< SwapChoice > l )
|
|
|
|
|
{
|
|
|
|
|
QComboBox* box = new QComboBox;
|
|
|
|
|
for ( SwapChoice c : l )
|
|
|
|
|
box->addItem( QString(), c );
|
|
|
|
|
return box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief ChoicePage::setupChoices creates PrettyRadioButton objects for the action
|
|
|
|
|
* choices.
|
|
|
|
|
@ -229,6 +247,19 @@ ChoicePage::setupChoices()
|
|
|
|
|
iconSize ) );
|
|
|
|
|
m_grp->addButton( m_replaceButton->buttonWidget(), Replace );
|
|
|
|
|
|
|
|
|
|
// Fill up swap options
|
|
|
|
|
// .. TODO: only if enabled in the config
|
|
|
|
|
m_eraseSwapChoices = createCombo( { SwapChoice::NoSwap, SwapChoice::SmallSwap, SwapChoice::FullSwap } );
|
|
|
|
|
m_eraseButton->addOptionsComboBox( m_eraseSwapChoices );
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
m_replaceSwapChoices = createCombo( { SwapChoice::NoSwap, SwapChoice::ReuseSwap, SwapChoice::SmallSwap, SwapChoice::FullSwap } );
|
|
|
|
|
m_replaceButton->addOptionsComboBox( m_replaceSwapChoices );
|
|
|
|
|
|
|
|
|
|
m_alongsideSwapChoices = createCombo( { SwapChoice::NoSwap, SwapChoice::ReuseSwap, SwapChoice::SmallSwap, SwapChoice::FullSwap } );
|
|
|
|
|
m_alongsideButton->addOptionsComboBox( m_alongsideSwapChoices );
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
m_itemsLayout->addWidget( m_alongsideButton );
|
|
|
|
|
m_itemsLayout->addWidget( m_replaceButton );
|
|
|
|
|
m_itemsLayout->addWidget( m_eraseButton );
|
|
|
|
|
@ -252,7 +283,7 @@ ChoicePage::setupChoices()
|
|
|
|
|
{
|
|
|
|
|
if ( checked ) // An action was picked.
|
|
|
|
|
{
|
|
|
|
|
m_choice = static_cast< Choice >( id );
|
|
|
|
|
m_choice = static_cast< InstallChoice >( id );
|
|
|
|
|
updateNextEnabled();
|
|
|
|
|
|
|
|
|
|
emit actionChosen();
|
|
|
|
|
@ -282,6 +313,12 @@ ChoicePage::setupChoices()
|
|
|
|
|
applyActionChoice( currentChoice() );
|
|
|
|
|
}
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
CALAMARES_RETRANSLATE(
|
|
|
|
|
updateSwapChoicesTr( m_eraseSwapChoices );
|
|
|
|
|
updateSwapChoicesTr( m_alongsideSwapChoices );
|
|
|
|
|
updateSwapChoicesTr( m_replaceSwapChoices );
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -376,7 +413,7 @@ ChoicePage::continueApplyDeviceChoice()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ChoicePage::applyActionChoice( ChoicePage::Choice choice )
|
|
|
|
|
ChoicePage::applyActionChoice( ChoicePage::InstallChoice choice )
|
|
|
|
|
{
|
|
|
|
|
m_beforePartitionBarsView->selectionModel()->
|
|
|
|
|
disconnect( SIGNAL( currentRowChanged( QModelIndex, QModelIndex ) ) );
|
|
|
|
|
@ -386,30 +423,37 @@ ChoicePage::applyActionChoice( ChoicePage::Choice choice )
|
|
|
|
|
switch ( choice )
|
|
|
|
|
{
|
|
|
|
|
case Erase:
|
|
|
|
|
if ( m_core->isDirty() )
|
|
|
|
|
{
|
|
|
|
|
ScanningDialog::run( QtConcurrent::run( [ = ]
|
|
|
|
|
auto gs = Calamares::JobQueue::instance()->globalStorage();
|
|
|
|
|
|
|
|
|
|
PartitionActions::Choices::AutoPartitionOptions options {
|
|
|
|
|
gs->value( "defaultFileSystemType" ).toString(),
|
|
|
|
|
m_encryptWidget->passphrase(),
|
|
|
|
|
gs->value( "efiSystemPartition" ).toString(),
|
|
|
|
|
CalamaresUtils::GiBtoBytes( gs->value( "requiredStorageGB" ).toDouble() ),
|
|
|
|
|
static_cast<PartitionActions::Choices::SwapChoice>( m_eraseSwapChoices->currentData().toInt() )
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if ( m_core->isDirty() )
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker( &m_coreMutex );
|
|
|
|
|
m_core->revertDevice( selectedDevice() );
|
|
|
|
|
} ),
|
|
|
|
|
[ = ]
|
|
|
|
|
ScanningDialog::run( QtConcurrent::run( [ = ]
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker( &m_coreMutex );
|
|
|
|
|
m_core->revertDevice( selectedDevice() );
|
|
|
|
|
} ),
|
|
|
|
|
[ = ]
|
|
|
|
|
{
|
|
|
|
|
PartitionActions::doAutopartition( m_core, selectedDevice(), options );
|
|
|
|
|
emit deviceChosen();
|
|
|
|
|
},
|
|
|
|
|
this );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PartitionActions::doAutopartition( m_core,
|
|
|
|
|
selectedDevice(),
|
|
|
|
|
m_encryptWidget->passphrase() );
|
|
|
|
|
PartitionActions::doAutopartition( m_core, selectedDevice(), options );
|
|
|
|
|
emit deviceChosen();
|
|
|
|
|
},
|
|
|
|
|
this );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PartitionActions::doAutopartition( m_core,
|
|
|
|
|
selectedDevice(),
|
|
|
|
|
m_encryptWidget->passphrase() );
|
|
|
|
|
emit deviceChosen();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case Replace:
|
|
|
|
|
if ( m_core->isDirty() )
|
|
|
|
|
@ -487,6 +531,7 @@ ChoicePage::doAlongsideSetupSplitter( const QModelIndex& current,
|
|
|
|
|
->value( "requiredStorageGB" )
|
|
|
|
|
.toDouble();
|
|
|
|
|
|
|
|
|
|
// TODO: make this consistent
|
|
|
|
|
qint64 requiredStorageB = qRound64( requiredStorageGB + 0.1 + 2.0 ) * 1024 * 1024 * 1024;
|
|
|
|
|
|
|
|
|
|
m_afterPartitionSplitterWidget->setSplitPartition(
|
|
|
|
|
@ -777,14 +822,19 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current )
|
|
|
|
|
if ( homePartitionPath->isEmpty() )
|
|
|
|
|
doReuseHomePartition = false;
|
|
|
|
|
|
|
|
|
|
PartitionActions::doReplacePartition( m_core,
|
|
|
|
|
selectedDevice(),
|
|
|
|
|
selectedPartition,
|
|
|
|
|
m_encryptWidget->passphrase() );
|
|
|
|
|
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
|
|
|
|
|
|
|
|
|
PartitionActions::doReplacePartition(
|
|
|
|
|
m_core,
|
|
|
|
|
selectedDevice(),
|
|
|
|
|
selectedPartition,
|
|
|
|
|
{
|
|
|
|
|
gs->value( "defaultFileSystemType" ).toString(),
|
|
|
|
|
m_encryptWidget->passphrase()
|
|
|
|
|
} );
|
|
|
|
|
Partition* homePartition = KPMHelpers::findPartitionByPath( { selectedDevice() },
|
|
|
|
|
*homePartitionPath );
|
|
|
|
|
|
|
|
|
|
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
|
|
|
|
if ( homePartition && doReuseHomePartition )
|
|
|
|
|
{
|
|
|
|
|
PartitionInfo::setMountPoint( homePartition, "/home" );
|
|
|
|
|
@ -897,7 +947,7 @@ ChoicePage::updateDeviceStatePreview()
|
|
|
|
|
* @param choice the chosen partitioning action.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
ChoicePage::updateActionChoicePreview( ChoicePage::Choice choice )
|
|
|
|
|
ChoicePage::updateActionChoicePreview( ChoicePage::InstallChoice choice )
|
|
|
|
|
{
|
|
|
|
|
Device* currentDevice = selectedDevice();
|
|
|
|
|
Q_ASSERT( currentDevice );
|
|
|
|
|
@ -1386,7 +1436,7 @@ ChoicePage::isNextEnabled() const
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ChoicePage::Choice
|
|
|
|
|
ChoicePage::InstallChoice
|
|
|
|
|
ChoicePage::currentChoice() const
|
|
|
|
|
{
|
|
|
|
|
return m_choice;
|
|
|
|
|
@ -1434,3 +1484,42 @@ ChoicePage::updateNextEnabled()
|
|
|
|
|
emit nextStatusChanged( enabled );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ChoicePage::updateSwapChoicesTr(QComboBox* box)
|
|
|
|
|
{
|
|
|
|
|
if ( !box )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
static_assert(SwapChoice::NoSwap == 0, "Enum values out-of-sync");
|
|
|
|
|
for ( int index = 0; index < box->count(); ++index )
|
|
|
|
|
{
|
|
|
|
|
bool ok = false;
|
|
|
|
|
int value = 0;
|
|
|
|
|
|
|
|
|
|
switch ( value = box->itemData( index ).toInt( &ok ) )
|
|
|
|
|
{
|
|
|
|
|
// case 0:
|
|
|
|
|
case SwapChoice::NoSwap:
|
|
|
|
|
// toInt() returns 0 on failure, so check for ok
|
|
|
|
|
if ( ok ) // It was explicitly set to 0
|
|
|
|
|
box->setItemText( index, tr( "No Swap" ) );
|
|
|
|
|
else
|
|
|
|
|
cWarning() << "Box item" << index << box->itemText( index ) << "has non-integer role.";
|
|
|
|
|
break;
|
|
|
|
|
case SwapChoice::ReuseSwap:
|
|
|
|
|
box->setItemText( index, tr( "Reuse Swap" ) );
|
|
|
|
|
break;
|
|
|
|
|
case SwapChoice::SmallSwap:
|
|
|
|
|
box->setItemText( index, tr( "Swap (no Hibernate)" ) );
|
|
|
|
|
break;
|
|
|
|
|
case SwapChoice::FullSwap:
|
|
|
|
|
box->setItemText( index, tr( "Swap (with Hibernate)" ) );
|
|
|
|
|
break;
|
|
|
|
|
case SwapChoice::SwapFile:
|
|
|
|
|
box->setItemText( index, tr( "Swap to file" ) );
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cWarning() << "Box item" << index << box->itemText( index ) << "has role" << value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|