File indexing completed on 2024-06-23 04:36:25
0001 /* 0002 SPDX-FileCopyrightText: 2014 Sergey Kalinichev <kalinichev.so.0@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "compilersmodel.h" 0008 0009 #include <KLocalizedString> 0010 #include <QVariant> 0011 0012 //Represents a single row in the table 0013 class TreeItem 0014 { 0015 public: 0016 explicit TreeItem(const QList<QVariant> &data, TreeItem *parent = nullptr) 0017 :m_itemData(data) 0018 ,m_parentItem(parent) 0019 {} 0020 0021 virtual ~TreeItem() 0022 { 0023 removeChilds(); 0024 } 0025 0026 void appendChild(TreeItem *item) 0027 { 0028 m_childItems.append(item); 0029 } 0030 0031 void removeChild(int row) 0032 { 0033 m_childItems.removeAt(row); 0034 } 0035 0036 TreeItem *child(int row) 0037 { 0038 return m_childItems.value(row); 0039 } 0040 0041 int childCount() const 0042 { 0043 return m_childItems.count(); 0044 } 0045 0046 int columnCount() const 0047 { 0048 return m_itemData.count(); 0049 } 0050 0051 virtual QVariant data(int column) const 0052 { 0053 return m_itemData.value(column); 0054 } 0055 0056 TreeItem *parent() 0057 { 0058 return m_parentItem; 0059 } 0060 0061 int row() const 0062 { 0063 if (m_parentItem) { 0064 return m_parentItem->m_childItems.indexOf(const_cast<TreeItem*>(this)); 0065 } 0066 0067 return 0; 0068 } 0069 0070 void removeChilds() 0071 { 0072 qDeleteAll(m_childItems); 0073 m_childItems.clear(); 0074 } 0075 0076 private: 0077 QList<TreeItem*> m_childItems; 0078 QList<QVariant> m_itemData; 0079 TreeItem *m_parentItem; 0080 }; 0081 0082 class CompilerItem : public TreeItem { 0083 public: 0084 CompilerItem(const CompilerPointer& compiler, TreeItem* parent) 0085 : TreeItem(QList<QVariant>{compiler->name(), compiler->factoryName()}, parent) 0086 , m_compiler(compiler) 0087 {} 0088 0089 CompilerPointer compiler() 0090 { 0091 return m_compiler; 0092 } 0093 0094 QVariant data(int column) const override 0095 { 0096 return !column ? m_compiler->name() : m_compiler->factoryName(); 0097 } 0098 0099 private: 0100 CompilerPointer m_compiler; 0101 }; 0102 0103 namespace { 0104 TreeItem* autoDetectedRootItem(TreeItem* root) 0105 { 0106 return root->child(0); 0107 } 0108 0109 TreeItem* manualRootItem(TreeItem* root) 0110 { 0111 return root->child(1); 0112 } 0113 } 0114 0115 CompilersModel::CompilersModel(QObject* parent) 0116 : QAbstractItemModel(parent) 0117 , m_rootItem(new TreeItem({i18nc("@title:column", "Name"), i18nc("@title:column", "Type")})) 0118 { 0119 m_rootItem->appendChild(new TreeItem( QList<QVariant>{i18nc("@item", "Auto-detected"), QString()}, m_rootItem)); 0120 m_rootItem->appendChild(new TreeItem( QList<QVariant>{i18nc("@item", "Manual"), QString()}, m_rootItem)); 0121 } 0122 0123 CompilersModel::~CompilersModel() 0124 { 0125 delete m_rootItem; 0126 } 0127 0128 QVariant CompilersModel::data(const QModelIndex& index, int role) const 0129 { 0130 if (!index.isValid() || (role != Qt::DisplayRole && role != CompilerDataRole)) { 0131 return QVariant(); 0132 } 0133 0134 auto *item = static_cast<TreeItem*>(index.internalPointer()); 0135 0136 if (role == CompilerDataRole) { 0137 QVariant v; 0138 if (auto c = dynamic_cast<CompilerItem*>(item)) { 0139 if (item->parent() == manualRootItem(m_rootItem)) { 0140 v.setValue<CompilerPointer>(c->compiler()); 0141 } 0142 } 0143 return v; 0144 } 0145 0146 return item->data(index.column()); 0147 } 0148 0149 int CompilersModel::rowCount(const QModelIndex& parent) const 0150 { 0151 TreeItem *parentItem; 0152 if (parent.column() > 0) { 0153 return 0; 0154 } 0155 0156 if (!parent.isValid()) { 0157 parentItem = m_rootItem; 0158 } else { 0159 parentItem = static_cast<TreeItem*>(parent.internalPointer()); 0160 } 0161 0162 return parentItem->childCount(); 0163 } 0164 0165 int CompilersModel::columnCount(const QModelIndex& parent) const 0166 { 0167 if (parent.isValid()) { 0168 return static_cast<TreeItem*>(parent.internalPointer())->columnCount(); 0169 } else { 0170 return m_rootItem->columnCount(); 0171 } 0172 } 0173 0174 QVariant CompilersModel::headerData(int section, Qt::Orientation orientation, int role) const 0175 { 0176 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { 0177 return m_rootItem->data(section); 0178 } 0179 return QVariant(); 0180 } 0181 0182 Qt::ItemFlags CompilersModel::flags(const QModelIndex& index) const 0183 { 0184 if (!index.isValid()) { 0185 return Qt::NoItemFlags; 0186 } 0187 0188 return Qt::ItemIsEnabled | Qt::ItemIsSelectable; 0189 } 0190 0191 QModelIndex CompilersModel::index(int row, int column, const QModelIndex& parent) const 0192 { 0193 if (!hasIndex(row, column, parent)) { 0194 return QModelIndex(); 0195 } 0196 0197 TreeItem *parentItem; 0198 0199 if (!parent.isValid()) { 0200 parentItem = m_rootItem; 0201 } else { 0202 parentItem = static_cast<TreeItem*>(parent.internalPointer()); 0203 } 0204 0205 TreeItem* childItem = parentItem->child(row); 0206 if (childItem) { 0207 return createIndex(row, column, childItem); 0208 } else { 0209 return QModelIndex(); 0210 } 0211 } 0212 0213 QModelIndex CompilersModel::parent(const QModelIndex& index) const 0214 { 0215 if (!index.isValid()) { 0216 return QModelIndex(); 0217 } 0218 0219 auto *childItem = static_cast<TreeItem*>(index.internalPointer()); 0220 TreeItem *parentItem = childItem->parent(); 0221 0222 if (parentItem == m_rootItem) { 0223 return QModelIndex(); 0224 } 0225 0226 return createIndex(parentItem->row(), 0, parentItem); 0227 } 0228 0229 QVector< CompilerPointer > CompilersModel::compilers() const 0230 { 0231 QVector<CompilerPointer> compilers; 0232 for (int idx = 0; idx < 2; idx++) { 0233 for (int i = 0; i< m_rootItem->child(idx)->childCount(); i++) { 0234 auto compiler = static_cast<CompilerItem*>(m_rootItem->child(idx)->child(i))->compiler(); 0235 if (!compiler->name().isEmpty() && !compiler->path().isEmpty()) { 0236 compilers.append(compiler); 0237 } 0238 } 0239 } 0240 0241 return compilers; 0242 } 0243 0244 void CompilersModel::setCompilers(const QVector< CompilerPointer >& compilers) 0245 { 0246 beginResetModel(); 0247 autoDetectedRootItem(m_rootItem)->removeChilds(); 0248 manualRootItem(m_rootItem)->removeChilds(); 0249 0250 for (auto& compiler: compilers) { 0251 if (compiler->factoryName().isEmpty()) { 0252 continue; 0253 } 0254 TreeItem* parent = autoDetectedRootItem(m_rootItem); 0255 if (compiler->editable()) { 0256 parent = manualRootItem(m_rootItem); 0257 } 0258 parent->appendChild(new CompilerItem(compiler, parent)); 0259 } 0260 0261 endResetModel(); 0262 } 0263 0264 QModelIndex CompilersModel::addCompiler(const CompilerPointer& compiler) 0265 { 0266 beginInsertRows(index(1, 0), manualRootItem(m_rootItem)->childCount(), manualRootItem(m_rootItem)->childCount()); 0267 Q_ASSERT(!compiler->factoryName().isEmpty()); 0268 manualRootItem(m_rootItem)->appendChild(new CompilerItem(compiler, manualRootItem(m_rootItem))); 0269 endInsertRows(); 0270 0271 emit compilerChanged(); 0272 return index(manualRootItem(m_rootItem)->childCount()-1, 0, index(1, 0)); 0273 } 0274 0275 bool CompilersModel::removeRows(int row, int count, const QModelIndex& parent) 0276 { 0277 if (row >= 0 && count > 0 && parent.isValid() && static_cast<TreeItem*>(parent.internalPointer()) == manualRootItem(m_rootItem)) { 0278 beginRemoveRows(parent, row, row + count - 1); 0279 for (int i = 0; i < count; ++i) { 0280 manualRootItem(m_rootItem)->removeChild(row); 0281 } 0282 endRemoveRows(); 0283 0284 emit compilerChanged(); 0285 return true; 0286 } 0287 return false; 0288 } 0289 0290 void CompilersModel::updateCompiler(const QItemSelection& compiler) 0291 { 0292 const auto& indexes = compiler.indexes(); 0293 for (const auto& idx : indexes) { 0294 emit dataChanged(idx, idx); 0295 } 0296 emit compilerChanged(); 0297 } 0298 0299 #include "moc_compilersmodel.cpp"