1 /* === This file is part of Calamares - <https://calamares.io> === 2 * 3 * SPDX-FileCopyrightText: 2017 Kyle Robbertze <kyle@aims.ac.za> 4 * SPDX-FileCopyrightText: 2017 2020, Adriaan de Groot <groot@kde.org> 5 * SPDX-License-Identifier: GPL-3.0-or-later 6 * 7 * Calamares is Free Software: see the License-Identifier above. 8 * 9 */ 10 11 #ifndef PACKAGETREEITEM_H 12 #define PACKAGETREEITEM_H 13 14 #include <QList> 15 #include <QStandardItem> 16 #include <QVariant> 17 18 class PackageTreeItem : public QStandardItem 19 { 20 public: 21 using List = QList< PackageTreeItem* >; 22 23 ///@brief A tag class to distinguish package-from-map from group-from-map 24 struct PackageTag 25 { 26 PackageTreeItem* parent; 27 }; 28 ///@brief A tag class to distinguish group-from-map from package-from-map 29 struct GroupTag 30 { 31 PackageTreeItem* parent; 32 }; 33 34 ///@brief A package (individual package) 35 explicit PackageTreeItem( const QString& packageName, PackageTreeItem* parent = nullptr ); 36 ///@brief A package (individual package with description) 37 explicit PackageTreeItem( const QVariantMap& packageData, PackageTag&& parent ); 38 ///@brief A group (sub-items and sub-groups are ignored) 39 explicit PackageTreeItem( const QVariantMap& groupData, GroupTag&& parent ); 40 ///@brief A root item, always selected, named "<root>" 41 explicit PackageTreeItem(); 42 ~PackageTreeItem() override; 43 44 void appendChild( PackageTreeItem* child ); 45 PackageTreeItem* child( int row ); 46 int childCount() const; 47 QVariant data( int column ) const override; 48 int row() const; 49 50 PackageTreeItem* parentItem(); 51 const PackageTreeItem* parentItem() const; 52 name()53 QString name() const { return m_name; } packageName()54 QString packageName() const { return m_packageName; } 55 description()56 QString description() const { return m_description; } preScript()57 QString preScript() const { return m_preScript; } postScript()58 QString postScript() const { return m_postScript; } 59 60 /** @brief Is this item a group-item? 61 * 62 * Groups have a (possibly empty) list of packages, and a 63 * (possibly empty) list of sub-groups, and can be marked 64 * critical, hidden, etc. Packages, on the other hand, only 65 * have a meaningful packageName() and selection status. 66 * 67 * Root is a group. 68 */ isGroup()69 bool isGroup() const { return m_isGroup; } 70 71 /// @brief Is this item a single package? isPackage()72 bool isPackage() const { return !isGroup(); } 73 74 /** @brief Is this item hidden? 75 * 76 * Hidden items (generally only groups) are maintained separately, 77 * not shown to the user, but do enter into the package-installation process. 78 */ isHidden()79 bool isHidden() const { return m_isHidden; } 80 81 /** @brief Is this hidden item, considered "selected"? 82 * 83 * This asserts when called on a non-hidden item. 84 * A hidden item has its own selected state, but really 85 * falls under the selectedness of the parent item. 86 */ 87 bool hiddenSelected() const; 88 89 /** @brief Is this group critical? 90 * 91 * A critical group must be successfully installed, for the Calamares 92 * installation to continue. 93 */ isCritical()94 bool isCritical() const { return m_isCritical; } 95 96 /** @brief Is this group expanded on start? 97 * 98 * This does not affect installation, only the UI. A group 99 * that expands on start is shown expanded (not collapsed) 100 * in the treeview when the page is loaded. 101 */ expandOnStart()102 bool expandOnStart() const { return m_startExpanded; } 103 104 /** @brief Is this an immutable item? 105 * 106 * Groups can be immutable: then you can't toggle the selected 107 * state of any of its items. 108 */ isImmutable()109 bool isImmutable() const { return m_showReadOnly; } 110 111 /** @brief is this item selected? 112 * 113 * Groups may be partially selected; packages are only on or off. 114 */ isSelected()115 Qt::CheckState isSelected() const { return m_selected; } 116 117 /** @brief Turns this item into a variant for PackageOperations use 118 * 119 * For "plain" items, this is just the package name; items with 120 * scripts return a map. See the package module for how it's interpreted. 121 */ 122 QVariant toOperation() const; 123 124 void setSelected( Qt::CheckState isSelected ); 125 void setChildrenSelected( Qt::CheckState isSelected ); 126 127 /** @brief Update selectedness based on the children's states 128 * 129 * This only makes sense for groups, which might have packages 130 * or subgroups; it checks only direct children. 131 */ 132 void updateSelected(); 133 134 // QStandardItem methods 135 int type() const override; 136 137 /** @brief Are two items equal 138 * 139 * This **disregards** parent-item and the child-items, and compares 140 * only the fields for the items-proper (name, .. expanded). Note 141 * also that *isSelected()* is a run-time state, and is **not** 142 * compared either. 143 */ 144 bool operator==( const PackageTreeItem& rhs ) const; 145 bool operator!=( const PackageTreeItem& rhs ) const { return !( *this == rhs ); } 146 147 private: 148 PackageTreeItem* m_parentItem; 149 List m_childItems; 150 151 // An entry can be a package, or a group. 152 QString m_name; 153 QString m_packageName; 154 Qt::CheckState m_selected = Qt::Unchecked; 155 156 // These are only useful for groups 157 QString m_description; 158 QString m_preScript; 159 QString m_postScript; 160 bool m_isGroup = false; 161 bool m_isCritical = false; 162 bool m_isHidden = false; 163 bool m_showReadOnly = false; 164 bool m_startExpanded = false; 165 }; 166 167 #endif // PACKAGETREEITEM_H 168