From 960008b124476e5b8b73a630568efaf9f9939585 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 16 Apr 2020 22:33:59 +0200 Subject: [PATCH] [netinstall] Allow rich descriptions of packages - the *packages* list can now be package-names, or package-names-and-a-description. --- src/modules/netinstall/PackageModel.cpp | 17 +++++++-- src/modules/netinstall/PackageTreeItem.cpp | 19 ++++++++-- src/modules/netinstall/PackageTreeItem.h | 15 +++++++- src/modules/netinstall/Tests.cpp | 43 +++++++++++++++++++--- 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index dad2207b2..dd5047129 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -232,16 +232,27 @@ PackageModel::setupModelData( const QVariantList& groupList, PackageTreeItem* pa continue; } - PackageTreeItem* item = new PackageTreeItem( groupMap, parent ); + PackageTreeItem* item = new PackageTreeItem( groupMap, PackageTreeItem::GroupTag { parent } ); if ( groupMap.contains( "selected" ) ) { item->setSelected( CalamaresUtils::getBool( groupMap, "selected", false ) ? Qt::Checked : Qt::Unchecked ); } if ( groupMap.contains( "packages" ) ) { - for ( const auto& packageName : groupMap.value( "packages" ).toStringList() ) + for ( const auto& packageName : groupMap.value( "packages" ).toList() ) { - item->appendChild( new PackageTreeItem( packageName, item ) ); + if ( packageName.type() == QVariant::String ) + { + item->appendChild( new PackageTreeItem( packageName.toString(), item ) ); + } + else + { + QVariantMap m = packageName.toMap(); + if ( !m.isEmpty() ) + { + item->appendChild( new PackageTreeItem( m, PackageTreeItem::PackageTag { item } ) ); + } + } } } if ( groupMap.contains( "subgroups" ) ) diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index edc89c536..df9195cce 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -61,15 +61,26 @@ PackageTreeItem::PackageTreeItem( const QString& packageName, PackageTreeItem* p { } -PackageTreeItem::PackageTreeItem( const QVariantMap& groupData, PackageTreeItem* parent ) - : m_parentItem( parent ) +PackageTreeItem::PackageTreeItem( const QVariantMap& groupData, PackageTag&& parent ) + : m_parentItem( parent.parent ) + , m_packageName( CalamaresUtils::getString( groupData, "name" ) ) + , m_selected( parentCheckState( parent.parent ) ) + , m_description( CalamaresUtils::getString( groupData, "description" ) ) + , m_isGroup( false ) + , m_isCritical( parent.parent ? parent.parent->isCritical() : false ) + , m_showReadOnly( parent.parent ? parent.parent->isImmutable() : false ) +{ +} + +PackageTreeItem::PackageTreeItem( const QVariantMap& groupData, GroupTag&& parent ) + : m_parentItem( parent.parent ) , m_name( CalamaresUtils::getString( groupData, "name" ) ) - , m_selected( parentCheckState( parent ) ) + , m_selected( parentCheckState( parent.parent ) ) , m_description( CalamaresUtils::getString( groupData, "description" ) ) , m_preScript( CalamaresUtils::getString( groupData, "pre-install" ) ) , m_postScript( CalamaresUtils::getString( groupData, "post-install" ) ) , m_isGroup( true ) - , m_isCritical( parentCriticality( groupData, parent ) ) + , m_isCritical( parentCriticality( groupData, parent.parent ) ) , m_isHidden( CalamaresUtils::getBool( groupData, "hidden", false ) ) , m_showReadOnly( CalamaresUtils::getBool( groupData, "immutable", false ) ) , m_startExpanded( CalamaresUtils::getBool( groupData, "expanded", false ) ) diff --git a/src/modules/netinstall/PackageTreeItem.h b/src/modules/netinstall/PackageTreeItem.h index d443bcdc6..0b2d506d7 100644 --- a/src/modules/netinstall/PackageTreeItem.h +++ b/src/modules/netinstall/PackageTreeItem.h @@ -29,10 +29,23 @@ class PackageTreeItem : public QStandardItem public: using List = QList< PackageTreeItem* >; + ///@brief A tag class to distinguish package-from-map from group-from-map + struct PackageTag + { + PackageTreeItem* parent; + }; + ///@brief A tag class to distinguish group-from-map from package-from-map + struct GroupTag + { + PackageTreeItem* parent; + }; + ///@brief A package (individual package) explicit PackageTreeItem( const QString& packageName, PackageTreeItem* parent = nullptr ); + ///@brief A package (individual package with description) + explicit PackageTreeItem( const QVariantMap& packageData, PackageTag&& parent ); ///@brief A group (sub-items and sub-groups are ignored) - explicit PackageTreeItem( const QVariantMap& groupData, PackageTreeItem* parent = nullptr ); + explicit PackageTreeItem( const QVariantMap& groupData, GroupTag&& parent ); ///@brief A root item, always selected, named "" explicit PackageTreeItem(); ~PackageTreeItem() override; diff --git a/src/modules/netinstall/Tests.cpp b/src/modules/netinstall/Tests.cpp index cfaf20efa..c74e6aafe 100644 --- a/src/modules/netinstall/Tests.cpp +++ b/src/modules/netinstall/Tests.cpp @@ -41,7 +41,10 @@ private Q_SLOTS: void initTestCase(); void testRoot(); + void testPackage(); + void testExtendedPackage(); + void testGroup(); void testCompare(); void testModel(); @@ -77,6 +80,7 @@ ItemTests::testPackage() QCOMPARE( p.isSelected(), Qt::Unchecked ); QCOMPARE( p.packageName(), QStringLiteral( "bash" ) ); QVERIFY( p.name().isEmpty() ); // not a group + QVERIFY( p.description().isEmpty() ); QCOMPARE( p.parentItem(), nullptr ); QCOMPARE( p.childCount(), 0 ); QVERIFY( !p.isHidden() ); @@ -126,6 +130,33 @@ static const char doc_with_expanded[] = // *INDENT-ON* // clang-format on +void +ItemTests::testExtendedPackage() +{ + YAML::Node yamldoc = YAML::Load( doc ); + QVariantList yamlContents = CalamaresUtils::yamlSequenceToVariant( yamldoc ); + + QCOMPARE( yamlContents.length(), 1 ); + + // Kind of derpy, but we can treat a group as if it is a package + // because the keys name and description are the same + PackageTreeItem p( yamlContents[ 0 ].toMap(), PackageTreeItem::PackageTag { nullptr } ); + + QCOMPARE( p.isSelected(), Qt::Unchecked ); + QCOMPARE( p.packageName(), QStringLiteral( "CCR" ) ); + QVERIFY( p.name().isEmpty() ); // not a group + QVERIFY( !p.description().isEmpty() ); // because it is set + QVERIFY( p.description().startsWith( QStringLiteral( "Tools for the Chakra" ) ) ); + QCOMPARE( p.parentItem(), nullptr ); + QCOMPARE( p.childCount(), 0 ); + QVERIFY( !p.isHidden() ); + QVERIFY( !p.isCritical() ); + QVERIFY( !p.isGroup() ); + QVERIFY( p.isPackage() ); + QVERIFY( p == p ); +} + + void ItemTests::testGroup() { @@ -134,7 +165,7 @@ ItemTests::testGroup() QCOMPARE( yamlContents.length(), 1 ); - PackageTreeItem p( yamlContents[ 0 ].toMap(), nullptr ); + PackageTreeItem p( yamlContents[ 0 ].toMap(), PackageTreeItem::GroupTag { nullptr } ); QCOMPARE( p.name(), QStringLiteral( "CCR" ) ); QVERIFY( p.packageName().isEmpty() ); QVERIFY( p.description().startsWith( QStringLiteral( "Tools " ) ) ); @@ -147,7 +178,7 @@ ItemTests::testGroup() QVERIFY( !p.isPackage() ); QVERIFY( p == p ); - PackageTreeItem c( "zsh", nullptr ); + PackageTreeItem c( "zsh", nullptr ); // Single string, package QVERIFY( p != c ); } @@ -184,15 +215,17 @@ ItemTests::testCompare() QVariantList yamlContents = CalamaresUtils::yamlSequenceToVariant( yamldoc ); QCOMPARE( yamlContents.length(), 1 ); - PackageTreeItem p3( yamlContents[ 0 ].toMap(), nullptr ); + PackageTreeItem p3( yamlContents[ 0 ].toMap(), PackageTreeItem::GroupTag { nullptr } ); QVERIFY( p3 == p3 ); QVERIFY( p3 != p1 ); QVERIFY( p1 != p3 ); QCOMPARE( p3.childCount(), 0 ); // Doesn't load the packages: list - PackageTreeItem p4( CalamaresUtils::yamlSequenceToVariant( YAML::Load( doc ) )[ 0 ].toMap(), nullptr ); + PackageTreeItem p4( CalamaresUtils::yamlSequenceToVariant( YAML::Load( doc ) )[ 0 ].toMap(), + PackageTreeItem::GroupTag { nullptr } ); QVERIFY( p3 == p4 ); - PackageTreeItem p5( CalamaresUtils::yamlSequenceToVariant( YAML::Load( doc_no_packages ) )[ 0 ].toMap(), nullptr ); + PackageTreeItem p5( CalamaresUtils::yamlSequenceToVariant( YAML::Load( doc_no_packages ) )[ 0 ].toMap(), + PackageTreeItem::GroupTag { nullptr } ); QVERIFY( p3 == p5 ); }