diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index 84c071db9..956b49fc9 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -1,6 +1,7 @@ /* * Copyright 2016, Luca Giambonini * Copyright 2016, Lisa Vitolo + * Copyright 2017, Kyle Robbertze * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +25,7 @@ #include "GlobalStorage.h" #include "JobQueue.h" #include "utils/Logger.h" +#include "utils/Retranslator.h" #include "utils/YamlUtils.h" #include @@ -64,9 +66,10 @@ void NetInstallPage::readGroups( const QByteArray& yamlData ) { YAML::Node groups = YAML::Load( yamlData.constData() ); Q_ASSERT( groups.IsSequence() ); - QVariantList columnHeadings; - columnHeadings << tr( "Name" ) << tr( "Description" ); - m_groups = new PackageModel( groups, columnHeadings ); + m_groups = new PackageModel( groups ); + CALAMARES_RETRANSLATE( + m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); + m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Description" ) ); ) } void @@ -89,9 +92,9 @@ NetInstallPage::dataIsHere( QNetworkReply* reply ) emit checkReady( isReady() ); } -QList NetInstallPage::selectedPackages( bool isCritical ) const +QList NetInstallPage::selectedPackages() const { - return m_groups->getPackages( isCritical ); + return m_groups->getPackages(); } void NetInstallPage::loadGroupList() diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index 0f4866770..7ecc74f89 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -1,6 +1,7 @@ /* * Copyright 2016, Luca Giambonini * Copyright 2016, Lisa Vitolo + * Copyright 2017, Kyle Robbertze * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +21,9 @@ #define NETINSTALLPAGE_H #include "PackageModel.h" +#include "PackageTreeItem.h" #include "Typedefs.h" + #include #include #include @@ -28,8 +31,6 @@ // required forward declarations class QByteArray; class QNetworkReply; -class GroupSelectionWidget; -class PackageModel; namespace Ui { @@ -54,7 +55,7 @@ public: // Returns the list of packages belonging to groups that are // selected in the view in this given moment. No data is cached here, so // this function does not have constant time. - QList selectedPackages( bool isCritical ) const; + QList selectedPackages() const; public slots: void dataIsHere( QNetworkReply* ); @@ -74,9 +75,6 @@ private: QNetworkAccessManager m_networkManager; PackageModel* m_groups; - // For each group name, store the selection widget to retrieve UI - // properties. - QHash m_groupWidgets; }; #endif // NETINSTALLPAGE_H diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index a653a0c0e..348a46e52 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -1,6 +1,7 @@ /* * Copyright 2016, Luca Giambonini * Copyright 2016, Lisa Vitolo + * Copyright 2017, Kyle Robbertze * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -126,13 +127,27 @@ NetInstallViewStep::onLeave() << "to global storage"; QMap packagesWithOperation; - QList installPackages = m_widget->selectedPackages( true ); - QList tryInstallPackages = m_widget->selectedPackages( false ); + QList packages = m_widget->selectedPackages(); + QVariantList installPackages; + QVariantList tryInstallPackages; + cDebug() << "Processing"; + + for ( auto package : packages ) + { + QMap details; + details.insert( "pre-script", package.preScript ); + details.insert( "package", package.packageName ); + details.insert( "post-script", package.postScript ); + if ( package.isCritical ) + installPackages.append( details ); + else + tryInstallPackages.append( details ); + } if ( !installPackages.empty() ) - packagesWithOperation.insert( "install", installPackages ); + packagesWithOperation.insert( "install", QVariant( installPackages ) ); if ( !tryInstallPackages.empty() ) - packagesWithOperation.insert( "try-install", tryInstallPackages ); + packagesWithOperation.insert( "try-install", QVariant( tryInstallPackages ) ); if ( !packagesWithOperation.isEmpty() ) { diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index e35f21d9d..2c07a55d0 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -18,18 +18,13 @@ #include "PackageModel.h" -#include "utils/Logger.h" #include "utils/YamlUtils.h" -#include - -PackageModel::PackageModel( const YAML::Node& data, const QVariantList& columnHeadings, - QObject* parent ) : +PackageModel::PackageModel( const YAML::Node& data, QObject* parent ) : QAbstractItemModel( parent ), - m_columnHeadings( columnHeadings ) + m_columnHeadings() { - QVariantList rootData; - m_rootItem = new PackageTreeItem( ); + m_rootItem = new PackageTreeItem(); setupModelData( data, m_rootItem ); } @@ -100,37 +95,17 @@ PackageModel::data( const QModelIndex& index, int role ) const { if ( !index.isValid() ) return QVariant(); + PackageTreeItem* item = static_cast( index.internalPointer() ); if ( index.column() == 0 && role == Qt::CheckStateRole ) return item->isSelected(); - if ( !item->childCount() ) // package - { - if ( !item->parentItem()->isHidden() && role == Qt::DisplayRole && - index.column() == 0 ) - return QVariant( item->packageName() ); - else if ( role == PackageTreeItem::PackageNameRole ) - return QVariant( item->packageName() ); - else - return QVariant(); - } - if ( item->isHidden() && role == Qt::DisplayRole ) // Hidden group return QVariant(); - switch ( role ) - { - case Qt::DisplayRole: + if ( role == Qt::DisplayRole ) return item->data( index.column() ); - case PackageTreeItem::PreScriptRole: - return QVariant( item->preScript() ); - case PackageTreeItem::PackageNameRole: - return QVariant( item->packageName() ); - case PackageTreeItem::PostScriptRole: - return QVariant( item->postScript() ); - default: - return QVariant(); - } + return QVariant(); } bool @@ -147,6 +122,21 @@ PackageModel::setData( const QModelIndex& index, const QVariant& value, int role return true; } +bool +PackageModel::setHeaderData( int section, Qt::Orientation orientation, + const QVariant& value, int role ) +{ + if ( orientation == Qt::Horizontal ) + { + if ( m_columnHeadings.value( section ) != QVariant() ) + m_columnHeadings.replace( section, value ); + else + m_columnHeadings.insert( section, value ); + emit headerDataChanged( orientation, section, section ); + } + return true; +} + Qt::ItemFlags PackageModel::flags( const QModelIndex& index ) const { @@ -165,38 +155,38 @@ PackageModel::headerData( int section, Qt::Orientation orientation, int role ) c return QVariant(); } -QList -PackageModel::getPackages( bool isCritical ) const +QList +PackageModel::getPackages() const { - QList items = getItemPackages( m_rootItem, isCritical ); + QList items = getItemPackages( m_rootItem ); for ( auto package : m_hiddenItems ) - items.append( getItemPackages( package, isCritical ) ); - QList packages; + items.append( getItemPackages( package ) ); + QList packages; for ( auto item : items ) { - QMap itemMap; - itemMap.insert( "pre-script", item->parentItem()->preScript() ); // Only groups have hooks - itemMap.insert( "package", item->packageName() ); - itemMap.insert( "post-script", item->parentItem()->postScript() ); - packages.append( QVariant( itemMap ) ); + PackageTreeItem::ItemData itemData; + itemData.preScript = item->parentItem()->preScript(); // Only groups have hooks + itemData.packageName = item->packageName(); // this seg faults + itemData.postScript = item->parentItem()->postScript(); // Only groups have hooks + itemData.isCritical = item->parentItem()->isCritical(); // Only groups are critical + packages.append( itemData ); } return packages; } QList -PackageModel::getItemPackages( PackageTreeItem* item, bool isCritical ) const +PackageModel::getItemPackages( PackageTreeItem* item ) const { QList selectedPackages; for ( int i = 0; i < item->childCount(); i++ ) { - if ( item->child( i )->isSelected() == Qt::Unchecked || - item->child( i )->isCritical() != isCritical ) + if ( item->child( i )->isSelected() == Qt::Unchecked ) continue; if ( !item->child( i )->childCount() ) // package selectedPackages.append( item->child( i ) ); else - selectedPackages.append( getItemPackages( item->child( i ), isCritical ) ); + selectedPackages.append( getItemPackages( item->child( i ) ) ); } return selectedPackages; diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index 174a3ae80..d49dd88c2 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -35,23 +35,24 @@ class PackageModel : public QAbstractItemModel Q_OBJECT public: - explicit PackageModel( const YAML::Node& data, const QVariantList& columnHeadings, - QObject* parent = 0 ); + explicit PackageModel( const YAML::Node& data, QObject* parent = 0 ); ~PackageModel(); - QVariant data( const QModelIndex& index, int role ) const Q_DECL_OVERRIDE; + QVariant data( const QModelIndex& index, int role ) const override; bool setData( const QModelIndex& index, const QVariant& value, - int role = Qt::EditRole ) Q_DECL_OVERRIDE; - Qt::ItemFlags flags( const QModelIndex& index ) const Q_DECL_OVERRIDE; + int role = Qt::EditRole ) override; + bool setHeaderData( int section, Qt::Orientation orientation, + const QVariant& value, int role = Qt::EditRole ); + Qt::ItemFlags flags( const QModelIndex& index ) const override; QVariant headerData( int section, Qt::Orientation orientation, - int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; + int role = Qt::DisplayRole ) const override; QModelIndex index( int row, int column, - const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE; - QModelIndex parent( const QModelIndex& index ) const Q_DECL_OVERRIDE; - int rowCount( const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE; - int columnCount( const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE; - QList getPackages( bool isCritical ) const; - QList getItemPackages( PackageTreeItem* item, bool isCritical ) const; + const QModelIndex& parent = QModelIndex() ) const override; + QModelIndex parent( const QModelIndex& index ) const override; + int rowCount( const QModelIndex& parent = QModelIndex() ) const override; + int columnCount( const QModelIndex& parent = QModelIndex() ) const override; + QList getPackages() const; + QList getItemPackages( PackageTreeItem* item ) const; private: void setupModelData( const YAML::Node& data, PackageTreeItem* parent ); diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index 93e1d317c..0cbc52223 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -18,18 +18,20 @@ #include "PackageTreeItem.h" -#include "utils/Logger.h" // TODO:Remove - PackageTreeItem::PackageTreeItem( const ItemData& data, PackageTreeItem* parent ) : m_data( data ), m_parentItem( parent ) { } PackageTreeItem::PackageTreeItem( const QString packageName, PackageTreeItem* parent ) : - m_packageName( packageName ), - m_parentItem( parent ), - m_selected( parent->isSelected() ) -{ } + m_parentItem( parent ) +{ + m_data.packageName = packageName; + if ( parent != nullptr ) + m_data.selected = parent->isSelected(); + else + m_data.selected = Qt::Unchecked; +} PackageTreeItem::PackageTreeItem( PackageTreeItem* parent ) : m_parentItem( parent ) @@ -75,9 +77,9 @@ PackageTreeItem::columnCount() const QVariant PackageTreeItem::data( int column ) const { - if ( m_packageName != nullptr ) // package + if ( packageName() != nullptr ) // package { - if ( column == 1 ) + if ( !column ) return QVariant( packageName() ); return QVariant(); } @@ -119,7 +121,7 @@ PackageTreeItem::preScript() const QString PackageTreeItem::packageName() const { - return m_packageName; + return m_data.packageName; } QString @@ -131,37 +133,37 @@ PackageTreeItem::postScript() const bool PackageTreeItem::isHidden() const { - return m_hidden; + return m_data.isHidden; } void PackageTreeItem::setHidden( bool isHidden ) { - m_hidden = isHidden; + m_data.isHidden = isHidden; } bool PackageTreeItem::isCritical() const { - return m_critical; + return m_data.isCritical; } void PackageTreeItem::setCritical( bool isCritical ) { - m_critical = isCritical; + m_data.isCritical = isCritical; } Qt::CheckState PackageTreeItem::isSelected() const { - return m_selected; + return m_data.selected; } void PackageTreeItem::setSelected( Qt::CheckState isSelected ) { - m_selected = isSelected; + m_data.selected = isSelected; setChildrenSelected( isSelected ); PackageTreeItem* currentItem = parentItem(); while ( currentItem != nullptr ) @@ -176,11 +178,11 @@ PackageTreeItem::setSelected( Qt::CheckState isSelected ) isChildPartiallySelected = true; } if ( !childrenSelected && !isChildPartiallySelected ) - currentItem->m_selected = Qt::Unchecked; + currentItem->m_data.selected = Qt::Unchecked; else if ( childrenSelected == currentItem->childCount() ) - currentItem->m_selected = Qt::Checked; + currentItem->m_data.selected = Qt::Checked; else - currentItem->m_selected = Qt::PartiallyChecked; + currentItem->m_data.selected = Qt::PartiallyChecked; currentItem = currentItem->parentItem(); } } @@ -191,7 +193,7 @@ PackageTreeItem::setChildrenSelected( Qt::CheckState isSelected ) if ( isSelected != Qt::PartiallyChecked ) for ( auto child : m_childItems ) { - child->m_selected = isSelected; + child->m_data.selected = isSelected; child->setChildrenSelected( isSelected ); } } diff --git a/src/modules/netinstall/PackageTreeItem.h b/src/modules/netinstall/PackageTreeItem.h index d4480ec20..291def37d 100644 --- a/src/modules/netinstall/PackageTreeItem.h +++ b/src/modules/netinstall/PackageTreeItem.h @@ -19,8 +19,6 @@ #ifndef PACKAGETREEITEM_H #define PACKAGETREEITEM_H -#include "NetInstallPage.h" - #include #include #include @@ -33,7 +31,11 @@ public: QString name; QString description; QString preScript; + QString packageName; QString postScript; + bool isCritical = false; + bool isHidden = false; + Qt::CheckState selected = Qt::Unchecked; }; explicit PackageTreeItem( const ItemData& data, PackageTreeItem* parent = 0 ); explicit PackageTreeItem( const QString packageName, PackageTreeItem* parent = 0 ); @@ -44,7 +46,7 @@ public: PackageTreeItem* child( int row ); int childCount() const; int columnCount() const; - QVariant data( int column ) const Q_DECL_OVERRIDE; + QVariant data( int column ) const override; int row() const; PackageTreeItem* parentItem(); QString prettyName() const; @@ -59,22 +61,12 @@ public: Qt::CheckState isSelected() const; void setSelected( Qt::CheckState isSelected ); void setChildrenSelected( Qt::CheckState isSelected ); - int type() const Q_DECL_OVERRIDE; - - static const int PreScriptRole = Qt::UserRole; - static const int PackageNameRole = Qt::UserRole + 1; - static const int PostScriptRole = Qt::UserRole + 2; + int type() const override; private: + PackageTreeItem* m_parentItem; QList m_childItems; ItemData m_data; - QString m_packageName; - - // See README.md for a description of these two fields. - Qt::CheckState m_selected = Qt::Unchecked; - bool m_hidden = false; - bool m_critical = false; const int m_columns = 2; // Name, description - PackageTreeItem* m_parentItem; }; #endif // PACKAGETREEITEM_H diff --git a/src/modules/netinstall/README.md b/src/modules/netinstall/README.md index 931ef37ff..f3860254e 100644 --- a/src/modules/netinstall/README.md +++ b/src/modules/netinstall/README.md @@ -27,13 +27,16 @@ The URL must point to a YAML file. Here is a short example of how the YAML file The file is composed of a list of entry, each describing one group. The keys *name*, *description* and *packages* are required. -Three more keys are supported: +More keys are supported: - hidden: if true, do not show the group on the page. Defaults to false. - selected: if true, display the group as selected. Defaults to false. - critical: if true, make the installation process fail if installing any of the packages in the group fails. Otherwise, just log a warning. Defaults to false. + - subgroups: if present this follows the same structure as the top level + of the YAML file, allowing there to be sub-groups of packages to an + arbitary depth If you set both *hidden* and *selected* for a group, you are basically creating a "default" group of packages which will always be installed in the user's system. diff --git a/src/modules/netinstall/page_netinst.ui b/src/modules/netinstall/page_netinst.ui index 033f30889..15d27cfb4 100644 --- a/src/modules/netinstall/page_netinst.ui +++ b/src/modules/netinstall/page_netinst.ui @@ -34,6 +34,11 @@ 434 + + + 11 + +