Split up ChoicePage loading, support preview and disk chooser.

main
Teo Mrnjavac 9 years ago
parent 9a67f6372c
commit fadfc67015

@ -35,17 +35,50 @@
#include <QBoxLayout>
#include <QButtonGroup>
#include <QComboBox>
#include <QDir>
#include <QLabel>
#include <QListView>
ChoicePage::ChoicePage( QWidget* parent )
#define drivesList qobject_cast< QListView* >( m_drivesView )
#define drivesCombo qobject_cast< QComboBox* >( m_drivesView )
ChoicePage::ChoicePage( bool compactMode, QWidget* parent )
: QWidget( parent )
, m_compactMode( compactMode )
, m_choice( NoChoice )
, m_nextEnabled( false )
, m_core( nullptr )
, m_alongsideButton( nullptr )
, m_eraseButton( nullptr )
, m_replaceButton( nullptr )
, m_somethingElseButton( nullptr )
{
setupUi( this );
if ( m_compactMode )
{
m_mainLayout->setDirection( QBoxLayout::TopToBottom );
m_drivesView = new QComboBox( this );
m_mainLayout->setStretchFactor( m_drivesLayout, 0 );
m_mainLayout->setStretchFactor( m_rightLayout, 1 );
}
else
{
m_drivesView = new QListView( this );
drivesList->setViewMode( QListView::ListMode );
drivesList->setWrapping( false );
drivesList->setFlow( QListView::TopToBottom );
drivesList->setSelectionRectVisible( false );
drivesList->setWordWrap( true );
drivesList->setUniformItemSizes( true );
drivesList->setSelectionMode( QAbstractItemView::SingleSelection );
drivesList->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
drivesList->setIconSize( CalamaresUtils::defaultIconSize() / 2 );
}
m_drivesLayout->addWidget( m_drivesView );
m_messageLabel->setWordWrap( true );
@ -54,21 +87,6 @@ ChoicePage::ChoicePage( QWidget* parent )
// Drive selector + preview
CALAMARES_RETRANSLATE( m_drivesLabel->setText( tr( "Select drive:" ) ); )
m_drivesView->setViewMode( QListView::ListMode );
m_drivesView->setWrapping( false );
m_drivesView->setFlow( QListView::TopToBottom );
m_drivesView->setSelectionRectVisible( false );
m_drivesView->setWordWrap( true );
m_drivesView->setUniformItemSizes( true );
m_drivesView->setSelectionMode( QAbstractItemView::SingleSelection );
m_drivesView->setIconSize( CalamaresUtils::defaultIconSize() / 2 );
// m_drivesView->setGridSize( QSize( CalamaresUtils::defaultFontHeight() * 8,
// m_drivesView->iconSize().height() +
// CalamaresUtils::defaultFontHeight() * 4 ) );
// m_drivesView->setMinimumHeight( m_drivesView->gridSize().height() +
// CalamaresUtils::defaultFontHeight() / 2 );
m_previewFrame->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding );
// end
}
@ -79,51 +97,35 @@ ChoicePage::~ChoicePage()
void
ChoicePage::updatePreviews()
ChoicePage::init( PartitionCoreModule* core,
const OsproberEntryList& osproberEntries )
{
QMutexLocker locker( &m_previewsMutex );
m_core = core;
m_osproberEntries = osproberEntries;
cDebug() << "Updating partitioning preview widgets.";
qDeleteAll( m_previewFrame->children() );
m_previewFrame->layout()->deleteLater();
setupChoices();
if ( m_drivesView->selectionModel()->currentIndex() == QModelIndex() )
if ( compact() )
{
cDebug() << "No disk selected, bailing out.";
return;
drivesCombo->setModel( core->deviceModel() );
connect( drivesCombo,
static_cast< void ( QComboBox::* )( int ) >( &QComboBox::currentIndexChanged ),
this, &ChoicePage::applyDeviceChoice );
}
Device* dev = m_core->deviceModel()->deviceForIndex( m_drivesView->selectionModel()->currentIndex() );
QVBoxLayout* layout = new QVBoxLayout;
m_previewFrame->setLayout( layout );
layout->setMargin( 0 );
PartitionPreview* preview = new PartitionPreview( m_previewFrame );
preview->setLabelsVisible( true );
PartitionModel* model = new PartitionModel( m_previewFrame );
model->init( dev );
preview->setModel( model );
layout->addWidget( preview );
else
{
drivesList->setModel( core->deviceModel() );
connect( drivesList->selectionModel(),
&QItemSelectionModel::currentChanged,
this, &ChoicePage::applyDeviceChoice );
}
ChoicePage::applyDeviceChoice();
}
void
ChoicePage::init( PartitionCoreModule* core, const OsproberEntryList& osproberEntries )
ChoicePage::setupChoices()
{
m_core = core;
// Drive selector + preview
m_drivesView->setModel( core->deviceModel() );
connect( m_drivesView->selectionModel(), &QItemSelectionModel::currentChanged,
this, [ this ]( const QModelIndex& index,
const QModelIndex& oldIndex )
{
updatePreviews();
} );
// end
// sample os-prober output:
// /dev/sda2:Windows 7 (loader):Windows:chain
// /dev/sda6::Arch:linux
@ -143,57 +145,159 @@ ChoicePage::init( PartitionCoreModule* core, const OsproberEntryList& osproberEn
CalamaresUtils::defaultIconSize().height() * 3 );
QButtonGroup* grp = new QButtonGroup( this );
PrettyRadioButton* alongsideButton = new PrettyRadioButton;
alongsideButton->setIconSize( iconSize );
alongsideButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionAlongside,
CalamaresUtils::Original,
iconSize ) );
grp->addButton( alongsideButton->buttonWidget() );
PrettyRadioButton* eraseButton = new PrettyRadioButton;
eraseButton->setIconSize( iconSize );
eraseButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionEraseAuto,
CalamaresUtils::Original,
iconSize ) );
grp->addButton( eraseButton->buttonWidget() );
PrettyRadioButton* replaceButton = new PrettyRadioButton;
replaceButton->setIconSize( iconSize );
replaceButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionReplaceOs,
m_alongsideButton = new PrettyRadioButton;
m_alongsideButton->setIconSize( iconSize );
m_alongsideButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionAlongside,
CalamaresUtils::Original,
iconSize ) );
grp->addButton( m_alongsideButton->buttonWidget() );
m_eraseButton = new PrettyRadioButton;
m_eraseButton->setIconSize( iconSize );
m_eraseButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionEraseAuto,
CalamaresUtils::Original,
iconSize ) );
grp->addButton( replaceButton->buttonWidget() );
grp->addButton( m_eraseButton->buttonWidget() );
m_itemsLayout->addWidget( alongsideButton );
m_itemsLayout->addWidget( replaceButton );
m_itemsLayout->addWidget( eraseButton );
m_replaceButton = new PrettyRadioButton;
m_replaceButton->setIconSize( iconSize );
m_replaceButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionReplaceOs,
CalamaresUtils::Original,
iconSize ) );
grp->addButton( m_replaceButton->buttonWidget() );
m_itemsLayout->addWidget( m_alongsideButton );
m_itemsLayout->addWidget( m_replaceButton );
m_itemsLayout->addWidget( m_eraseButton );
m_itemsLayout->setSpacing( CalamaresUtils::defaultFontHeight() / 2 );
if ( osproberEntries.count() == 0 )
QFrame* hLine = new QFrame;
hLine->setFrameStyle( QFrame::HLine );
m_itemsLayout->addWidget( hLine );
m_somethingElseButton = new PrettyRadioButton;
CALAMARES_RETRANSLATE(
m_somethingElseButton->setText( tr( "<strong>Manual partitioning</strong><br/>"
"You can create or resize partitions yourself, or choose "
"multiple partitions for %1." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
)
m_somethingElseButton->setIconSize( iconSize );
m_somethingElseButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionManual,
CalamaresUtils::Original,
iconSize ) );
m_itemsLayout->addWidget( m_somethingElseButton );
grp->addButton( m_somethingElseButton->buttonWidget() );
m_itemsLayout->addStretch();
connect( m_alongsideButton->buttonWidget(), &QRadioButton::toggled,
this, [ this ]( bool checked )
{
if ( checked )
m_choice = Alongside;
setNextEnabled( true );
} );
connect( m_eraseButton->buttonWidget(), &QRadioButton::toggled,
this, [ this ]( bool checked )
{
if ( checked )
m_choice = Erase;
setNextEnabled( true );
} );
connect( m_replaceButton->buttonWidget(), &QRadioButton::toggled,
this, [ this ]( bool checked )
{
if ( checked )
m_choice = Replace;
setNextEnabled( true );
} );
connect( m_somethingElseButton->buttonWidget(), &QRadioButton::toggled,
this, [ this ]( bool checked )
{
if ( checked )
m_choice = Manual;
setNextEnabled( true );
} );
m_rightLayout->setStretchFactor( m_itemsLayout, 1 );
m_rightLayout->setStretchFactor( m_previewFrame, 0 );
}
void
ChoicePage::applyDeviceChoice()
{
QMutexLocker locker( &m_previewsMutex );
cDebug() << "Updating partitioning preview widgets.";
qDeleteAll( m_previewFrame->children() );
m_previewFrame->layout()->deleteLater();
if ( !compact() &&
drivesList->selectionModel()->currentIndex() == QModelIndex() )
{
cDebug() << "No disk selected, bailing out.";
return;
}
Device* dev = nullptr;
if ( compact() )
{
dev = m_core->deviceModel()->deviceForIndex(
m_core->deviceModel()->index(
drivesCombo->currentIndex() ) );
}
else
{
dev = m_core->deviceModel()->deviceForIndex(
drivesList->selectionModel()->currentIndex() );
}
if ( !dev )
return;
QVBoxLayout* layout = new QVBoxLayout;
m_previewFrame->setLayout( layout );
layout->setMargin( 0 );
PartitionPreview* preview = new PartitionPreview( m_previewFrame );
preview->setLabelsVisible( true );
PartitionModel* model = new PartitionModel( m_previewFrame );
model->init( dev );
preview->setModel( model );
layout->addWidget( preview );
// Preview setup done. Now we show/hide choices as needed.
if ( m_osproberEntries.count() == 0 )
{
CALAMARES_RETRANSLATE(
m_messageLabel->setText( tr( "This computer currently does not seem to have an operating system on it. "
"What would you like to do?" ) );
if ( core->deviceModel()->rowCount() < 2 )
eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"<font color=\"red\">Warning: </font>This will delete all of your programs, "
"documents, photos, music, and any other files." )
if ( m_core->deviceModel()->rowCount() < 2 )
m_eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"<font color=\"red\">Warning: </font>This will delete all of your programs, "
"documents, photos, music, and any other files." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
else
eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"You will be offered a choice of which disk to erase." )
m_eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"You will be offered a choice of which disk to erase." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
)
replaceButton->hide();
alongsideButton->hide();
m_replaceButton->hide();
m_alongsideButton->hide();
}
else if ( osproberEntries.count() == 1 )
else if ( m_osproberEntries.count() == 1 )
{
QString osName = osproberEntries.first().prettyName;
QString osName = m_osproberEntries.first().prettyName;
if ( !osName.isEmpty() )
{
@ -202,30 +306,30 @@ ChoicePage::init( PartitionCoreModule* core, const OsproberEntryList& osproberEn
"What would you like to do?" )
.arg( osName ) );
alongsideButton->setText( tr( "<strong>Install %2 alongside %1</strong><br/>"
"The installer will shrink the %1 volume to make room for %2. "
"You can choose which operating system you want each time the "
"computer starts up." )
m_alongsideButton->setText( tr( "<strong>Install %2 alongside %1</strong><br/>"
"The installer will shrink the %1 volume to make room for %2. "
"You can choose which operating system you want each time the "
"computer starts up." )
.arg( osName )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
if ( core->deviceModel()->rowCount() < 2 )
eraseButton->setText( tr( "<strong>Erase entire disk with %1 and install %2</strong><br/>"
"<font color=\"red\">Warning: </font>This will erase the whole disk and "
"delete all of your %1 programs, "
"documents, photos, music, and any other files." )
if ( m_core->deviceModel()->rowCount() < 2 )
m_eraseButton->setText( tr( "<strong>Erase entire disk with %1 and install %2</strong><br/>"
"<font color=\"red\">Warning: </font>This will erase the whole disk and "
"delete all of your %1 programs, "
"documents, photos, music, and any other files." )
.arg( osName )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
else
eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"You will be offered a choice of which disk to erase." )
m_eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"You will be offered a choice of which disk to erase." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
replaceButton->setText( tr( "<strong>Replace a partition with %1</strong><br/>"
"You will be offered a choice of which partition to erase." )
m_replaceButton->setText( tr( "<strong>Replace a partition with %1</strong><br/>"
"You will be offered a choice of which partition to erase." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
)
@ -236,35 +340,35 @@ ChoicePage::init( PartitionCoreModule* core, const OsproberEntryList& osproberEn
m_messageLabel->setText( tr( "This computer already has an operating system on it. "
"What would you like to do?" ) );
alongsideButton->setText( tr( "<strong>Install %1 alongside your current operating system</strong><br/>"
"The installer will shrink an existing volume to make room for %2. "
"You can choose which operating system you want each time the "
"computer starts up." )
m_alongsideButton->setText( tr( "<strong>Install %1 alongside your current operating system</strong><br/>"
"The installer will shrink an existing volume to make room for %2. "
"You can choose which operating system you want each time the "
"computer starts up." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortProductName ) ) );
if ( core->deviceModel()->rowCount() < 2 )
eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"<font color=\"red\">Warning: </font>This will delete all of your programs, "
"documents, photos, music, and any other files." )
if ( m_core->deviceModel()->rowCount() < 2 )
m_eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"<font color=\"red\">Warning: </font>This will delete all of your programs, "
"documents, photos, music, and any other files." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
else
eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"You will be offered a choice of which disk to erase." )
m_eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"You will be offered a choice of which disk to erase." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
replaceButton->setText( tr( "<strong>Replace a partition with %1</strong><br/>"
"You will be offered a choice of which partition to erase." )
m_replaceButton->setText( tr( "<strong>Replace a partition with %1</strong><br/>"
"You will be offered a choice of which partition to erase." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
)
}
if ( !osproberEntries.first().canBeResized )
alongsideButton->hide();
if ( !m_osproberEntries.first().canBeResized )
m_alongsideButton->hide();
}
else
{
@ -272,7 +376,7 @@ ChoicePage::init( PartitionCoreModule* core, const OsproberEntryList& osproberEn
bool atLeastOneCanBeResized = false;
foreach ( const OsproberEntry& entry, osproberEntries )
foreach ( const OsproberEntry& entry, m_osproberEntries )
{
if ( entry.canBeResized )
{
@ -285,35 +389,35 @@ ChoicePage::init( PartitionCoreModule* core, const OsproberEntryList& osproberEn
m_messageLabel->setText( tr( "This computer currently has multiple operating systems on it. "
"What would you like to do?" ) );
alongsideButton->setText( tr( "<strong>Install %1 alongside your current operating systems</strong><br/>"
"The installer will shrink an existing volume to make room for %2. "
"You can choose which operating system you want each time the "
"computer starts up." )
m_alongsideButton->setText( tr( "<strong>Install %1 alongside your current operating systems</strong><br/>"
"The installer will shrink an existing volume to make room for %2. "
"You can choose which operating system you want each time the "
"computer starts up." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortProductName ) ) );
if ( core->deviceModel()->rowCount() < 2 )
eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"<font color=\"red\">Warning: </font>This will delete all of your programs, "
"documents, photos, music, and any other files." )
if ( m_core->deviceModel()->rowCount() < 2 )
m_eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"<font color=\"red\">Warning: </font>This will delete all of your programs, "
"documents, photos, music, and any other files." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
else
eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"You will be offered a choice of which disk to erase." )
m_eraseButton->setText( tr( "<strong>Erase disk and install %1</strong><br/>"
"You will be offered a choice of which disk to erase." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
replaceButton->setText( tr( "<strong>Replace a partition with %1</strong><br/>"
"You will be offered a choice of which partition to erase." )
m_replaceButton->setText( tr( "<strong>Replace a partition with %1</strong><br/>"
"You will be offered a choice of which partition to erase." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
)
if ( !atLeastOneCanBeResized )
alongsideButton->hide();
m_alongsideButton->hide();
}
bool isEfi = QDir( "/sys/firmware/efi/efivars" ).exists();
@ -321,62 +425,11 @@ ChoicePage::init( PartitionCoreModule* core, const OsproberEntryList& osproberEn
if ( isEfi && !efiSystemPartitionFound )
{
cDebug() << "WARNING: system is EFI but there's not EFI system partition, "
cDebug() << "WARNING: system is EFI but there's no EFI system partition, "
"DISABLING alongside and replace features.";
alongsideButton->hide();
replaceButton->hide();
m_alongsideButton->hide();
m_replaceButton->hide();
}
QFrame* hLine = new QFrame;
hLine->setFrameStyle( QFrame::HLine );
m_itemsLayout->addWidget( hLine );
PrettyRadioButton* somethingElseButton = new PrettyRadioButton;
CALAMARES_RETRANSLATE(
somethingElseButton->setText( tr( "<strong>Manual partitioning</strong><br/>"
"You can create or resize partitions yourself, or choose "
"multiple partitions for %1." )
.arg( Calamares::Branding::instance()->
string( Calamares::Branding::ShortVersionedName ) ) );
)
somethingElseButton->setIconSize( iconSize );
somethingElseButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionManual,
CalamaresUtils::Original,
iconSize ) );
m_itemsLayout->addWidget( somethingElseButton );
grp->addButton( somethingElseButton->buttonWidget() );
connect( alongsideButton->buttonWidget(), &QRadioButton::toggled,
this, [ this ]( bool checked )
{
if ( checked )
m_choice = Alongside;
setNextEnabled( true );
} );
connect( eraseButton->buttonWidget(), &QRadioButton::toggled,
this, [ this ]( bool checked )
{
if ( checked )
m_choice = Erase;
setNextEnabled( true );
} );
connect( replaceButton->buttonWidget(), &QRadioButton::toggled,
this, [ this ]( bool checked )
{
if ( checked )
m_choice = Replace;
setNextEnabled( true );
} );
connect( somethingElseButton->buttonWidget(), &QRadioButton::toggled,
this, [ this ]( bool checked )
{
if ( checked )
m_choice = Manual;
setNextEnabled( true );
} );
}
@ -394,6 +447,24 @@ ChoicePage::currentChoice() const
}
bool
ChoicePage::compact()
{
if ( m_compactMode )
{
Q_ASSERT( drivesCombo );
Q_ASSERT( !drivesList );
return true;
}
else
{
Q_ASSERT( drivesList );
Q_ASSERT( !drivesCombo );
return false;
}
}
void
ChoicePage::setNextEnabled( bool enabled )
{

@ -32,6 +32,7 @@ class QLabel;
class QListView;
class PartitionCoreModule;
class PrettyRadioButton;
class ChoicePage : public QWidget, private Ui::ChoicePage
{
@ -46,10 +47,11 @@ public:
Manual
};
explicit ChoicePage( QWidget* parent = nullptr );
explicit ChoicePage( bool compactMode = false, QWidget* parent = nullptr );
virtual ~ChoicePage();
void init( PartitionCoreModule* core, const OsproberEntryList& osproberEntries );
void init( PartitionCoreModule* core,
const OsproberEntryList& osproberEntries );
bool isNextEnabled() const;
@ -59,15 +61,26 @@ signals:
void nextStatusChanged( bool );
private:
bool compact();
void setNextEnabled( bool enabled );
void updatePreviews();
void setupChoices();
void applyDeviceChoice();
bool m_nextEnabled;
PartitionCoreModule* m_core;
OsproberEntryList m_osproberEntries;
QMutex m_previewsMutex;
Choice m_choice;
bool m_compactMode;
QWidget* m_drivesView;
PrettyRadioButton* m_alongsideButton;
PrettyRadioButton* m_eraseButton;
PrettyRadioButton* m_replaceButton;
PrettyRadioButton* m_somethingElseButton;
};
#endif // CHOICEPAGE_H

@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="m_mainLayout" stretch="1,2">
<item>
<layout class="QVBoxLayout" name="m_drivesLayout">
<item>
@ -26,13 +26,10 @@
</property>
</widget>
</item>
<item>
<widget class="QListView" name="m_drivesView"/>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="m_leftLayout">
<layout class="QVBoxLayout" name="m_rightLayout">
<item>
<widget class="QLabel" name="m_messageLabel">
<property name="toolTip">

Loading…
Cancel
Save