File indexing completed on 2024-05-05 04:38:47
0001 /* 0002 SPDX-FileCopyrightText: 2013 Kevin Funk <kfunk@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "placeholderitemproxymodel.h" 0008 0009 #include <KColorScheme> 0010 0011 using namespace KDevelop; 0012 0013 class KDevelop::PlaceholderItemProxyModelPrivate 0014 { 0015 public: 0016 explicit PlaceholderItemProxyModelPrivate(PlaceholderItemProxyModel* qq) 0017 : q(qq) 0018 {} 0019 0020 inline int sourceRowCount() 0021 { 0022 return q->sourceModel() ? q->sourceModel()->rowCount() : 0; 0023 } 0024 0025 inline bool isPlaceholderRow(const QModelIndex& index) const 0026 { 0027 if (!q->sourceModel()) { 0028 return false; 0029 } 0030 return index.row() == q->sourceModel()->rowCount(); 0031 } 0032 0033 PlaceholderItemProxyModel* const q; 0034 0035 /// column -> hint mapping 0036 QMap<int, QVariant> m_columnHints; 0037 }; 0038 0039 PlaceholderItemProxyModel::PlaceholderItemProxyModel(QObject* parent) 0040 : QIdentityProxyModel(parent) 0041 , d_ptr(new PlaceholderItemProxyModelPrivate(this)) 0042 {} 0043 0044 PlaceholderItemProxyModel::~PlaceholderItemProxyModel() 0045 { 0046 } 0047 0048 QVariant PlaceholderItemProxyModel::columnHint(int column) const 0049 { 0050 Q_D(const PlaceholderItemProxyModel); 0051 0052 return d->m_columnHints.value(column); 0053 } 0054 0055 void PlaceholderItemProxyModel::setColumnHint(int column, const QVariant& hint) 0056 { 0057 Q_D(PlaceholderItemProxyModel); 0058 0059 if (column < 0) { 0060 return; 0061 } 0062 0063 d->m_columnHints[column] = hint; 0064 0065 const int row = d->sourceRowCount(); 0066 emit dataChanged(index(row, 0), index(row, columnCount())); 0067 } 0068 0069 Qt::ItemFlags PlaceholderItemProxyModel::flags(const QModelIndex& index) const 0070 { 0071 Q_D(const PlaceholderItemProxyModel); 0072 0073 if (d->isPlaceholderRow(index)) { 0074 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; 0075 const int column = index.column(); 0076 // if the column doesn't provide a hint we assume that we can't edit this field 0077 if (d->m_columnHints.contains(column)) { 0078 flags |= Qt::ItemIsEditable; 0079 } 0080 return flags; 0081 } 0082 0083 return QIdentityProxyModel::flags(index); 0084 } 0085 0086 void PlaceholderItemProxyModel::setSourceModel(QAbstractItemModel* sourceModel) 0087 { 0088 QIdentityProxyModel::setSourceModel(sourceModel); 0089 // TODO: Listen to layoutDataChanged signals? 0090 } 0091 0092 int PlaceholderItemProxyModel::rowCount(const QModelIndex& parent) const 0093 { 0094 if (!sourceModel()) 0095 return 0; 0096 0097 // only flat models supported for now, assert early in case that's not true 0098 Q_ASSERT(!parent.isValid()); 0099 Q_UNUSED(parent); 0100 return sourceModel()->rowCount() + 1; 0101 } 0102 0103 bool KDevelop::PlaceholderItemProxyModel::hasChildren(const QModelIndex& parent) const 0104 { 0105 if (!parent.isValid()) { 0106 return true; 0107 } 0108 return QIdentityProxyModel::hasChildren(parent); 0109 } 0110 0111 QVariant PlaceholderItemProxyModel::data(const QModelIndex& proxyIndex, int role) const 0112 { 0113 Q_D(const PlaceholderItemProxyModel); 0114 0115 const int column = proxyIndex.column(); 0116 if (d->isPlaceholderRow(proxyIndex)) { 0117 switch (role) { 0118 case Qt::DisplayRole: 0119 return columnHint(column); 0120 case Qt::ForegroundRole: { 0121 const KColorScheme scheme(QPalette::Normal); 0122 return scheme.foreground(KColorScheme::InactiveText); 0123 } 0124 default: 0125 return QVariant(); 0126 } 0127 } 0128 return QIdentityProxyModel::data(proxyIndex, role); 0129 } 0130 0131 QModelIndex PlaceholderItemProxyModel::parent(const QModelIndex& child) const 0132 { 0133 Q_D(const PlaceholderItemProxyModel); 0134 0135 if (d->isPlaceholderRow(child)) { 0136 return QModelIndex(); 0137 } 0138 0139 return QIdentityProxyModel::parent(child); 0140 } 0141 0142 QModelIndex PlaceholderItemProxyModel::buddy(const QModelIndex& index) const 0143 { 0144 Q_D(const PlaceholderItemProxyModel); 0145 0146 if (d->isPlaceholderRow(index)) { 0147 return index; 0148 } 0149 return QIdentityProxyModel::buddy(index); 0150 } 0151 0152 QModelIndex PlaceholderItemProxyModel::sibling(int row, int column, const QModelIndex& idx) const 0153 { 0154 const bool isPlaceHolderRow = (sourceModel() ? row == sourceModel()->rowCount() : false); 0155 if (isPlaceHolderRow) { 0156 return index(row, column, QModelIndex()); 0157 } 0158 return QIdentityProxyModel::sibling(row, column, idx); 0159 } 0160 0161 QModelIndex PlaceholderItemProxyModel::mapToSource(const QModelIndex& proxyIndex) const 0162 { 0163 Q_D(const PlaceholderItemProxyModel); 0164 0165 if (d->isPlaceholderRow(proxyIndex)) { 0166 return QModelIndex(); 0167 } 0168 return QIdentityProxyModel::mapToSource(proxyIndex); 0169 } 0170 0171 bool PlaceholderItemProxyModel::setData(const QModelIndex& index, const QVariant& value, int role) 0172 { 0173 Q_D(PlaceholderItemProxyModel); 0174 0175 const int column = index.column(); 0176 if (d->isPlaceholderRow(index) && role == Qt::EditRole && d->m_columnHints.contains(column)) { 0177 const bool accept = validateRow(index, value); 0178 // if validation fails, clear the complete line 0179 if (!accept) { 0180 emit dataChanged(index, index); 0181 return false; 0182 } 0183 0184 // update view 0185 emit dataChanged(index, index); 0186 0187 // notify observers 0188 emit dataInserted(column, value); 0189 return true; 0190 } 0191 return QIdentityProxyModel::setData(index, value, role); 0192 } 0193 0194 QModelIndex PlaceholderItemProxyModel::index(int row, int column, const QModelIndex& parent) const 0195 { 0196 Q_ASSERT(!parent.isValid()); 0197 Q_UNUSED(parent); 0198 0199 const bool isPlaceHolderRow = (sourceModel() ? row == sourceModel()->rowCount() : false); 0200 if (isPlaceHolderRow) { 0201 return createIndex(row, column); 0202 } 0203 return QIdentityProxyModel::index(row, column, parent); 0204 } 0205 0206 bool PlaceholderItemProxyModel::validateRow(const QModelIndex& index, const QVariant& value) const 0207 { 0208 Q_UNUSED(index); 0209 return !value.toString().isEmpty(); 0210 } 0211 0212 #include "moc_placeholderitemproxymodel.cpp"