diff --git a/src/modules/officechooser/PackageChooserPage.cpp b/src/modules/officechooser/PackageChooserPage.cpp index 98b569bce..2b8449592 100644 --- a/src/modules/officechooser/PackageChooserPage.cpp +++ b/src/modules/officechooser/PackageChooserPage.cpp @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2019, Adriaan de Groot - * Copyright 2019, Philip Müller + * Copyright 2019, Philip MÜller * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,11 +31,10 @@ PackageChooserPage::PackageChooserPage( PackageChooserMode mode, QWidget* parent , ui( new Ui::PackageChooserPage ) , m_introduction( QString(), QString(), - tr( "Office Selection" ), + tr( "Office Suite" ), tr( "Please pick a office suite from the list. The selected product will be installed." ) ) { m_introduction.screenshot = QPixmap( QStringLiteral( ":/images/choose-office.jpg" ) ); - cDebug() << m_introduction.screenshot; ui->setupUi( this ); CALAMARES_RETRANSLATE( updateLabels(); ) @@ -43,9 +42,9 @@ PackageChooserPage::PackageChooserPage( PackageChooserMode mode, QWidget* parent switch ( mode ) { case PackageChooserMode::Optional: - case PackageChooserMode::Exclusive: + case PackageChooserMode::Required: ui->products->setSelectionMode( QAbstractItemView::SingleSelection ); - case PackageChooserMode::Multiple: + case PackageChooserMode::OptionalMultiple: case PackageChooserMode::RequiredMultiple: ui->products->setSelectionMode( QAbstractItemView::ExtendedSelection ); } @@ -88,6 +87,26 @@ void PackageChooserPage::setModel( QAbstractItemModel* model ) { ui->products->setModel( model ); + + // Check if any of the items in the model is the "none" option. + // If so, copy its values into the introduction / none item. + for ( int r = 0; r < model->rowCount(); ++r ) + { + auto index = model->index( r, 0 ); + if ( index.isValid() ) + { + QVariant v = model->data( index, PackageListModel::IdRole ); + if ( v.isValid() && v.toString().isEmpty() ) + { + m_introduction.name = model->data( index, PackageListModel::NameRole ).toString(); + m_introduction.description = model->data( index, PackageListModel::DescriptionRole ).toString(); + m_introduction.screenshot = model->data( index, PackageListModel::ScreenshotRole ).value< QPixmap >(); + currentChanged( QModelIndex() ); + break; + } + } + } + connect( ui->products->selectionModel(), &QItemSelectionModel::selectionChanged, this, @@ -99,3 +118,24 @@ PackageChooserPage::hasSelection() const { return ui && ui->products && ui->products->selectionModel() && ui->products->selectionModel()->hasSelection(); } + +QStringList +PackageChooserPage::selectedPackageIds() const +{ + if ( !( ui && ui->products && ui->products->selectionModel() ) ) + { + return QStringList(); + } + + const auto* model = ui->products->model(); + QStringList ids; + for ( const auto& index : ui->products->selectionModel()->selectedIndexes() ) + { + QString pid = model->data( index, PackageListModel::IdRole ).toString(); + if ( !pid.isEmpty() ) + { + ids.append( pid ); + } + } + return ids; +} diff --git a/src/modules/officechooser/PackageChooserPage.h b/src/modules/officechooser/PackageChooserPage.h index 8f9fde11f..401de903b 100644 --- a/src/modules/officechooser/PackageChooserPage.h +++ b/src/modules/officechooser/PackageChooserPage.h @@ -37,7 +37,13 @@ public: void setModel( QAbstractItemModel* model ); + /// @brief Is anything selected? bool hasSelection() const; + /** @brief Get the list of selected ids + * + * This list may be empty (if none is selected). + */ + QStringList selectedPackageIds() const; public slots: void currentChanged( const QModelIndex& index ); diff --git a/src/modules/officechooser/PackageChooserViewStep.cpp b/src/modules/officechooser/PackageChooserViewStep.cpp index 41576b320..925d57f4c 100644 --- a/src/modules/officechooser/PackageChooserViewStep.cpp +++ b/src/modules/officechooser/PackageChooserViewStep.cpp @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2019, Adriaan de Groot - * Copyright 2019, Philip Müller + * Copyright 2019, Philip MÜller * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,7 +38,7 @@ PackageChooserViewStep::PackageChooserViewStep( QObject* parent ) : Calamares::ViewStep( parent ) , m_widget( nullptr ) , m_model( nullptr ) - , m_mode( PackageChooserMode::Exclusive ) + , m_mode( PackageChooserMode::Required ) { emit nextStatusChanged( false ); } @@ -77,7 +77,7 @@ PackageChooserViewStep::widget() } else { - cWarning() << "PackageChooser Widget created before model."; + cWarning() << "OfficeChooser Widget created before model."; } } return m_widget; @@ -101,10 +101,10 @@ PackageChooserViewStep::isNextEnabled() const switch ( m_mode ) { case PackageChooserMode::Optional: - case PackageChooserMode::Multiple: + case PackageChooserMode::OptionalMultiple: // zero or one OR zero or more return true; - case PackageChooserMode::Exclusive: + case PackageChooserMode::Required: case PackageChooserMode::RequiredMultiple: // exactly one OR one or more return m_widget->hasSelection(); @@ -138,6 +138,15 @@ PackageChooserViewStep::isAtEnd() const void PackageChooserViewStep::onLeave() { + QString key = QStringLiteral( "packagechooser_%1" ).arg( m_id ); + QString value; + if ( m_widget->hasSelection() ) + { + value = m_widget->selectedPackageIds().join( ',' ); + } + Calamares::JobQueue::instance()->globalStorage()->insert( key, value ); + + cDebug() << "OfficeChooser" << key << "selected" << value; } Calamares::JobList @@ -150,16 +159,50 @@ PackageChooserViewStep::jobs() const void PackageChooserViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { - // TODO: use the configurationMap + QString mode = CalamaresUtils::getString( configurationMap, "mode" ); + bool ok = false; + if ( !mode.isEmpty() ) + { + m_mode = roleNames().find( mode, ok ); + } + if ( !ok ) + { + m_mode = PackageChooserMode::Required; + } + m_id = CalamaresUtils::getString( configurationMap, "id" ); + if ( m_id.isEmpty() ) + { + // Not set, so use the instance id + // TODO: use a stronger type than QString for structured IDs + m_id = moduleInstanceKey().split( '@' ).last(); + } + + // TODO: replace this hard-coded model if ( !m_model ) { - m_model = new PackageListModel( nullptr ); - m_model->addPackage( PackageItem { "libreoffice-still", "libreoffice-still", "LibreOffice", "LibreOffice is a powerful and free office suite, used by millions of people around the world. ts clean interface and feature-rich tools help you unleash your creativity and enhance your productivity.", ":/images/LibreOffice.jpg" } ); - m_model->addPackage( - PackageItem { "freeoffice", "freeoffice", "FreeOffice", "FreeOffice 2018 is a full-featured Office suite with word processing, spreadsheet and presentation software. It is seamlessly compatible with Microsoft Office. (Note: You need to register the product for free longterm usage)", ":/images/FreeOffice.jpg" } ); + m_model->addPackage( PackageItem { QString(), + QString(), + "No Office Suite", + "Please pick a Office Suite from the list. " + "If you don't want to install a Office Suite, that's fine, " + "you can install one later as needed.", + ":/images/choose-office.jpg" } ); + m_model->addPackage( PackageItem { "libreoffice-still", + "libreoffice-still", + "LibreOffice", + "LibreOffice is a powerful and free office suite, used by millions of people around the world. " + "Its clean interface and feature-rich tools help you unleash your creativity and enhance your productivity.", + ":/images/LibreOffice.jpg" } ); + m_model->addPackage( PackageItem { "freeoffice", + "freeoffice", + "FreeOffice", + "FreeOffice 2018 is a full-featured Office suite with word processing, " + "spreadsheet and presentation software. It is seamlessly compatible with Microsoft Office. " + "(Note: You need to register the product for free longterm usage)", + ":/images/FreeOffice.jpg" } ); if ( m_widget ) { diff --git a/src/modules/officechooser/PackageChooserViewStep.h b/src/modules/officechooser/PackageChooserViewStep.h index ed33c3e46..55ed2d4d5 100644 --- a/src/modules/officechooser/PackageChooserViewStep.h +++ b/src/modules/officechooser/PackageChooserViewStep.h @@ -30,7 +30,6 @@ #include class PackageChooserPage; -class PackageListModel; class PLUGINDLLEXPORT PackageChooserViewStep : public Calamares::ViewStep { @@ -61,7 +60,10 @@ private: PackageChooserPage* m_widget; PackageListModel* m_model; + + // Configuration PackageChooserMode m_mode; + QString m_id; }; CALAMARES_PLUGIN_FACTORY_DECLARATION( PackageChooserViewStepFactory ) diff --git a/src/modules/officechooser/PackageModel.cpp b/src/modules/officechooser/PackageModel.cpp index 7798b33bd..aa8dd39fc 100644 --- a/src/modules/officechooser/PackageModel.cpp +++ b/src/modules/officechooser/PackageModel.cpp @@ -20,6 +20,26 @@ #include "utils/Logger.h" +const NamedEnumTable< PackageChooserMode >& +roleNames() +{ + static const NamedEnumTable< PackageChooserMode > names { + { "optional", PackageChooserMode::Optional }, + { "required", PackageChooserMode::Required }, + { "optionalmultiple", PackageChooserMode::OptionalMultiple }, + { "requiredmultiple", PackageChooserMode::RequiredMultiple }, + // and a bunch of aliases + { "zero-or-one", PackageChooserMode::Optional }, + { "radio", PackageChooserMode::Required }, + { "one", PackageChooserMode::Required }, + { "set", PackageChooserMode::OptionalMultiple }, + { "zero-or-more", PackageChooserMode::OptionalMultiple }, + { "multiple", PackageChooserMode::RequiredMultiple }, + { "one-or-more", PackageChooserMode::RequiredMultiple } + }; + return names; +} + PackageItem PackageItem::fromAppStream( const QString& filename ) { @@ -108,6 +128,10 @@ PackageListModel::data( const QModelIndex& index, int role ) const { return m_packages[ row ].screenshot; } + else if ( role == IdRole ) + { + return m_packages[ row ].id; + } return QVariant(); } diff --git a/src/modules/officechooser/PackageModel.h b/src/modules/officechooser/PackageModel.h index 7db668df4..7f8fff8ec 100644 --- a/src/modules/officechooser/PackageModel.h +++ b/src/modules/officechooser/PackageModel.h @@ -19,6 +19,8 @@ #ifndef PACKAGEMODEL_H #define PACKAGEMODEL_H +#include "utils/NamedEnum.h" + #include #include #include @@ -27,11 +29,13 @@ enum class PackageChooserMode { Optional, // zero or one - Exclusive, // exactly one - Multiple, // zero or more + Required, // exactly one + OptionalMultiple, // zero or more RequiredMultiple // one or more }; +const NamedEnumTable< PackageChooserMode >& roleNames(); + struct PackageItem { QString id; @@ -69,7 +73,7 @@ class PackageListModel : public QAbstractListModel public: PackageListModel( PackageList&& items, QObject* parent ); PackageListModel( QObject* parent ); - virtual ~PackageListModel(); + virtual ~PackageListModel() override; void addPackage( PackageItem&& p ); @@ -80,7 +84,8 @@ public: { NameRole = Qt::DisplayRole, DescriptionRole = Qt::UserRole, - ScreenshotRole + ScreenshotRole, + IdRole }; private: diff --git a/src/modules/officechooser/page_package.ui b/src/modules/officechooser/page_package.ui index e54f778b5..ea85acff3 100644 --- a/src/modules/officechooser/page_package.ui +++ b/src/modules/officechooser/page_package.ui @@ -36,23 +36,12 @@ - - - 14 - - TextLabel - - Qt::AutoText - Qt::AlignCenter - - true - @@ -76,6 +65,9 @@ true + + true +