File indexing completed on 2024-04-14 03:55:01
0001 /* 0002 SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "kateargumenthintmodel.h" 0008 #include "katecompletionmodel.h" 0009 #include "katepartdebug.h" 0010 #include <ktexteditor/codecompletionmodel.h> 0011 0012 #include <QTextFormat> 0013 0014 using namespace KTextEditor; 0015 0016 void KateArgumentHintModel::clear() 0017 { 0018 m_rows.clear(); 0019 } 0020 0021 QModelIndex KateArgumentHintModel::mapToSource(const QModelIndex &index) const 0022 { 0023 if (size_t(index.row()) >= m_rows.size()) { 0024 return QModelIndex(); 0025 } 0026 0027 if (m_rows[index.row()] < 0 || m_rows[index.row()] >= (int)group()->filtered.size()) { 0028 return QModelIndex(); 0029 } 0030 0031 KateCompletionModel::ModelRow source = group()->filtered[m_rows[index.row()]].sourceRow(); 0032 if (!source.first) { 0033 qCDebug(LOG_KTE) << "KateArgumentHintModel::data: Row does not exist in source"; 0034 return QModelIndex(); 0035 } 0036 0037 QModelIndex sourceIndex = source.second.sibling(source.second.row(), index.column()); 0038 0039 return sourceIndex; 0040 } 0041 0042 void KateArgumentHintModel::parentModelReset() 0043 { 0044 clear(); 0045 buildRows(); 0046 } 0047 0048 void KateArgumentHintModel::buildRows() 0049 { 0050 beginResetModel(); 0051 0052 m_rows.clear(); 0053 std::map<int, std::vector<int>> m_depths; // Map each hint-depth to a list of functions of that depth 0054 for (int a = 0; a < (int)group()->filtered.size(); a++) { 0055 KateCompletionModel::ModelRow source = group()->filtered[a].sourceRow(); 0056 QModelIndex sourceIndex = source.second.sibling(source.second.row(), 0); 0057 QVariant v = sourceIndex.data(CodeCompletionModel::ArgumentHintDepth); 0058 if (v.userType() == QMetaType::Int) { 0059 std::vector<int> &lst(m_depths[v.toInt()]); 0060 lst.push_back(a); 0061 } 0062 } 0063 0064 for (const auto &[key, value] : m_depths) { 0065 for (int row : value) { 0066 m_rows.insert(m_rows.begin(), row); // Insert filtered in reversed order 0067 } 0068 } 0069 0070 endResetModel(); 0071 0072 Q_EMIT contentStateChanged(!m_rows.empty()); 0073 } 0074 0075 KateArgumentHintModel::KateArgumentHintModel(KateCompletionModel *parent) 0076 : QAbstractListModel(parent) 0077 , m_parent(parent) 0078 { 0079 connect(parent, &KateCompletionModel::modelReset, this, &KateArgumentHintModel::parentModelReset); 0080 connect(parent, &KateCompletionModel::argumentHintsChanged, this, &KateArgumentHintModel::parentModelReset); 0081 } 0082 0083 QVariant KateArgumentHintModel::data(const QModelIndex &index, int role) const 0084 { 0085 if (size_t(index.row()) >= m_rows.size()) { 0086 // qCDebug(LOG_KTE) << "KateArgumentHintModel::data: index out of bound: " << index.row() << " total filtered: " << m_rows.count(); 0087 return QVariant(); 0088 } 0089 0090 if (m_rows[index.row()] < 0 || m_rows[index.row()] >= (int)group()->filtered.size()) { 0091 qCDebug(LOG_KTE) << "KateArgumentHintModel::data: index out of bound: " << m_rows[index.row()] << " total filtered: " << (int)group()->filtered.size(); 0092 return QVariant(); 0093 } 0094 0095 KateCompletionModel::ModelRow source = group()->filtered[m_rows[index.row()]].sourceRow(); 0096 if (!source.first) { 0097 qCDebug(LOG_KTE) << "KateArgumentHintModel::data: Row does not exist in source"; 0098 return QVariant(); 0099 } 0100 0101 QModelIndex sourceIndex = source.second.sibling(source.second.row(), index.column()); 0102 0103 if (!sourceIndex.isValid()) { 0104 qCDebug(LOG_KTE) << "KateArgumentHintModel::data: Source-index is not valid"; 0105 return QVariant(); 0106 } 0107 0108 switch (role) { 0109 case Qt::DisplayRole: { 0110 // Construct the text 0111 QString totalText; 0112 for (int a = CodeCompletionModel::Prefix; a <= CodeCompletionModel::Postfix; a++) { 0113 if (a != CodeCompletionModel::Scope) { // Skip the scope 0114 totalText += source.second.sibling(source.second.row(), a).data(Qt::DisplayRole).toString() + QLatin1Char(' '); 0115 } 0116 } 0117 0118 return QVariant(totalText); 0119 } 0120 case CodeCompletionModel::HighlightingMethod: { 0121 // Return that we are doing custom-highlighting of one of the sub-strings does it 0122 for (int a = CodeCompletionModel::Prefix; a <= CodeCompletionModel::Postfix; a++) { 0123 QVariant method = source.second.sibling(source.second.row(), a).data(CodeCompletionModel::HighlightingMethod); 0124 if (method.userType() == QMetaType::Int && method.toInt() == CodeCompletionModel::CustomHighlighting) { 0125 return QVariant(CodeCompletionModel::CustomHighlighting); 0126 } 0127 } 0128 0129 return QVariant(); 0130 } 0131 case CodeCompletionModel::CustomHighlight: { 0132 QStringList strings; 0133 0134 // Collect strings 0135 for (int a = CodeCompletionModel::Prefix; a <= CodeCompletionModel::Postfix; a++) { 0136 strings << source.second.sibling(source.second.row(), a).data(Qt::DisplayRole).toString(); 0137 } 0138 0139 QList<QVariantList> highlights; 0140 0141 // Collect custom-highlightings 0142 for (int a = CodeCompletionModel::Prefix; a <= CodeCompletionModel::Postfix; a++) { 0143 highlights << source.second.sibling(source.second.row(), a).data(CodeCompletionModel::CustomHighlight).toList(); 0144 } 0145 0146 return mergeCustomHighlighting(strings, highlights, 1); 0147 } 0148 } 0149 0150 return {}; 0151 } 0152 0153 int KateArgumentHintModel::rowCount(const QModelIndex &) const 0154 { 0155 return m_rows.size(); 0156 } 0157 0158 KateCompletionModel::Group *KateArgumentHintModel::group() const 0159 { 0160 return m_parent->m_argumentHints; 0161 } 0162 0163 void KateArgumentHintModel::emitDataChanged(const QModelIndex &start, const QModelIndex &end) 0164 { 0165 Q_EMIT dataChanged(start, end); 0166 } 0167 0168 #include "moc_kateargumenthintmodel.cpp"