File indexing completed on 2024-03-24 04:37:01
0001 /* 0002 * This file is part of KDevelop Krazy2 Plugin. 0003 * 0004 * Copyright 2012 Daniel Calviño Sánchez <danxuliu@gmail.com> 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU General Public License 0008 * as published by the Free Software Foundation; either version 2 0009 * of the License, or (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0018 */ 0019 0020 #include "checkermodel.h" 0021 0022 #include <KLocalizedString> 0023 0024 #include "checker.h" 0025 0026 class Item { 0027 public: 0028 0029 enum ItemType { 0030 FileTypeItem, 0031 CheckerItem, 0032 ExtraHeaderItem 0033 }; 0034 0035 Item(): 0036 m_parent(nullptr), 0037 m_checker(nullptr) { 0038 } 0039 0040 ~Item() { 0041 qDeleteAll(m_children); 0042 } 0043 0044 ItemType type() const { 0045 return m_type; 0046 } 0047 0048 void setType(ItemType type) { 0049 m_type = type; 0050 } 0051 0052 const QList<Item*>& children() const { 0053 return m_children; 0054 } 0055 0056 void addChild(Item* item) { 0057 item->setParent(this); 0058 m_children.append(item); 0059 } 0060 0061 Item* parent() const { 0062 return m_parent; 0063 } 0064 0065 void setParent(Item* parent) { 0066 m_parent = parent; 0067 } 0068 0069 const QString& fileType() const { 0070 return m_fileType; 0071 } 0072 0073 void setFileType(const QString& fileType) { 0074 m_fileType = fileType; 0075 } 0076 0077 const Checker* checker() const { 0078 return m_checker; 0079 } 0080 0081 void setChecker(const Checker* checker) { 0082 m_checker = checker; 0083 } 0084 0085 private: 0086 0087 ItemType m_type; 0088 QList<Item*> m_children; 0089 Item* m_parent; 0090 0091 QString m_fileType; 0092 const Checker* m_checker; 0093 0094 }; 0095 0096 //public: 0097 0098 CheckerModel::CheckerModel(QObject* parent /*= 0*/): 0099 QAbstractItemModel(parent) { 0100 } 0101 0102 CheckerModel::~CheckerModel() { 0103 qDeleteAll(m_fileTypeItems); 0104 } 0105 0106 QModelIndex CheckerModel::index(int row, int column, const QModelIndex& parent /* = QModelIndex()*/) const { 0107 if (!hasIndex(row, column, parent)) { 0108 return QModelIndex(); 0109 } 0110 0111 Item* item; 0112 if (!parent.isValid()) { 0113 item = m_fileTypeItems.at(row); 0114 } else { 0115 item = static_cast<Item*>(parent.internalPointer())->children().at(row); 0116 } 0117 0118 return createIndex(row, column, item); 0119 } 0120 0121 QModelIndex CheckerModel::parent(const QModelIndex& index) const { 0122 if (!index.isValid()) { 0123 return QModelIndex(); 0124 } 0125 0126 Item* childItem = static_cast<Item*>(index.internalPointer()); 0127 Item* parentItem = childItem->parent(); 0128 0129 if (!parentItem) { 0130 return QModelIndex(); 0131 } 0132 0133 int row; 0134 if (parentItem->type() == Item::FileTypeItem) { 0135 row = m_fileTypeItems.indexOf(parentItem); 0136 } else { 0137 row = parentItem->parent()->children().indexOf(parentItem); 0138 } 0139 0140 return createIndex(row, 0, parentItem); 0141 } 0142 0143 int CheckerModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const { 0144 if (parent.column() > 0) { 0145 return 0; 0146 } 0147 0148 if (!parent.isValid()) { 0149 return m_fileTypeItems.count(); 0150 } 0151 0152 return static_cast<Item*>(parent.internalPointer())->children().count(); 0153 } 0154 0155 int CheckerModel::columnCount(const QModelIndex& parent /*= QModelIndex()*/) const { 0156 Q_UNUSED(parent); 0157 0158 return 1; 0159 } 0160 0161 QVariant CheckerModel::data(const QModelIndex& index, int role /*= Qt::DisplayRole*/) const { 0162 if (!index.isValid()) { 0163 return QVariant(); 0164 } 0165 0166 if (role != Qt::DisplayRole && role != Qt::ToolTipRole) { 0167 return QVariant(); 0168 } 0169 0170 Item* item = static_cast<Item*>(index.internalPointer()); 0171 if (role == Qt::ToolTipRole) { 0172 if (item->type() != Item::CheckerItem) { 0173 return QVariant(); 0174 } 0175 0176 if (item->checker()->description().isEmpty()) { 0177 return i18nc("@info:tooltip The underlying command did not provide a text output", 0178 "Sorry, no description given"); 0179 } 0180 0181 return "<p>" + item->checker()->description() + "</p>"; 0182 } 0183 0184 if (item->type() == Item::FileTypeItem) { 0185 return item->fileType(); 0186 } 0187 0188 if (item->type() == Item::ExtraHeaderItem) { 0189 return i18nc("@item Extra Krazy2 checkers", "[EXTRA]"); 0190 } 0191 0192 return item->checker()->name(); 0193 } 0194 0195 const Checker* CheckerModel::checkerForIndex(const QModelIndex& index) const { 0196 if (!index.isValid()) { 0197 return nullptr; 0198 } 0199 0200 Item* item = static_cast<Item*>(index.internalPointer()); 0201 if (item->type() == Item::FileTypeItem || item->type() == Item::ExtraHeaderItem) { 0202 return nullptr; 0203 } 0204 0205 return item->checker(); 0206 } 0207 0208 void CheckerModel::setCheckers(const QList< const Checker* >& checkers) { 0209 beginResetModel(); 0210 0211 QMultiMap<QString, const Checker*> checkersByFileType; 0212 foreach (const Checker* checker, checkers) { 0213 checkersByFileType.insert(checker->fileType(), checker); 0214 } 0215 0216 qDeleteAll(m_fileTypeItems); 0217 m_fileTypeItems.clear(); 0218 0219 //Keys are returned in ascending order 0220 foreach (const QString& fileType, checkersByFileType.uniqueKeys()) { 0221 auto fileTypeItem = new Item(); 0222 fileTypeItem->setType(Item::FileTypeItem); 0223 fileTypeItem->setFileType(fileType); 0224 m_fileTypeItems.append(fileTypeItem); 0225 0226 QMap<QString, Item*> checkerItems; 0227 QMap<QString, Item*> extraCheckerItems; 0228 foreach (const Checker* checker, checkersByFileType.values(fileType)) { 0229 auto checkerItem = new Item(); 0230 checkerItem->setType(Item::CheckerItem); 0231 checkerItem->setChecker(checker); 0232 0233 if (!checker->isExtra()) { 0234 checkerItems.insert(checker->name(), checkerItem); 0235 } else { 0236 extraCheckerItems.insert(checker->name(), checkerItem); 0237 } 0238 } 0239 0240 //Values are returned in ascending order of their keys 0241 foreach (Item* checkerItem, checkerItems.values()) { 0242 fileTypeItem->addChild(checkerItem); 0243 } 0244 0245 if (!extraCheckerItems.values().isEmpty()) { 0246 auto extraHeaderItem = new Item(); 0247 extraHeaderItem->setType(Item::ExtraHeaderItem); 0248 extraHeaderItem->setFileType(fileTypeItem->fileType()); 0249 fileTypeItem->addChild(extraHeaderItem); 0250 0251 //Values are returned in ascending order of their keys 0252 foreach (Item* checkerItem, extraCheckerItems.values()) { 0253 extraHeaderItem->addChild(checkerItem); 0254 } 0255 } 0256 } 0257 0258 endResetModel(); 0259 }