LeechCraft 0.6.70-17609-g3dde4097dd
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
itemsmodel.h
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#pragma once
10
11#include <util/sll/ctstring.h>
13
14namespace LC::Util
15{
16 template<CtString RoleArg, auto GetterArg>
18 {
19 static constexpr auto Getter = GetterArg;
20 static constexpr auto Role = RoleArg;
21 };
22
23 template<CtString RoleArg, auto GetterArg>
25
26 template<typename T>
28 {
29 public:
30 using FieldGetter_t = QVariant (*) (const T&);
31 using FieldsList_t = QVector<QPair<QByteArray, FieldGetter_t>>;
32 private:
33 const QVector<FieldGetter_t> Fields_;
34 const QHash<int, QByteArray> Roles_;
35 public:
36 template<typename... Fields>
37 explicit RoledItemsModel (QObject *parent, Fields...) noexcept
38 : FlatItemsModelTypedBase<T> { QStringList { {} }, parent }
39 , Fields_ { +[] (const T& t) -> QVariant { return t.*(Fields::Getter); }... }
40 , Roles_ { MakeRoles ({ ToByteArray<Fields::Role> ()... }) }
41 {
42 }
43
44 QHash<int, QByteArray> roleNames () const override
45 {
46 return Roles_;
47 }
48 protected:
49 QVariant GetData (int row, int, int role) const override
50 {
51 if (const auto getter = Fields_.value (role - this->DataRole - 1))
52 return getter (this->Items_.at (row));
53 return {};
54 }
55 private:
56 QHash<int, QByteArray> MakeRoles (QVector<QByteArray> fields) const
57 {
59 result.reserve (result.size () + fields.size ());
60 for (int i = 0; i < fields.size (); ++i)
61 result [this->DataRole + i + 1] = std::move (fields [i]);
62 return result;
63 }
64 };
65
66 template<auto Getter>
67 struct Field
68 {
69 QString Name_;
70 };
71
72 namespace detail
73 {
74 template<Qt::ItemDataRole Role>
75 using RoleTag = std::integral_constant<Qt::ItemDataRole, Role>;
76
77 struct Extension
78 {
79 explicit Extension (auto&&...) {}
80
81 static Qt::ItemFlags GetFlags (auto&&...) { return {}; }
82 static bool SetData (auto&&...) { return false; }
83 static void GetDataForRole () {}
84 };
85
86 template<typename P>
88 {
89 struct Param
90 {
92 };
93
95
96 template<typename... Params>
97 requires (std::is_same_v<Param, Params> || ...)
98 explicit ParameterizedExtension (const std::tuple<Params...>& args)
99 : Param_ { std::get<Param> (args).Param_ }
100 {
101 }
102 };
103 }
104
105 template<auto IconField>
107 {
108 using Extension::Extension;
109
110 static QVariant GetDataForRole (detail::RoleTag<Qt::DecorationRole>, const auto& item, int column)
111 {
112 if (column)
113 return {};
114 return item.*IconField;
115 }
116 };
117
119 {
120 using ParameterizedExtension::ParameterizedExtension;
121
122 Qt::ItemFlags GetFlags (int column) const
123 {
124 return Param_.contains (column) ? Qt::ItemIsEditable : Qt::ItemFlags {};
125 }
126 };
127
128 template<auto CheckField>
130 {
131 using Extension::Extension;
132
133 static Qt::ItemFlags GetFlags (int column)
134 {
135 return column ? Qt::ItemFlags {} : Qt::ItemIsUserCheckable;
136 }
137
138 static QVariant GetDataForRole (detail::RoleTag<Qt::CheckStateRole>, const auto& item, int, int column)
139 {
140 if (column)
141 return QVariant {};
142
143 if constexpr (std::is_same_v<std::decay_t<decltype (item.*CheckField)>, Qt::CheckState>)
144 return item.*CheckField;
145 else if constexpr (std::is_same_v<std::decay_t<decltype (item.*CheckField)>, bool>)
146 return item.*CheckField ? Qt::Checked : Qt::Unchecked;
147 else
148 static_assert (false, "expected Qt::CheckState or bool field");
149 }
150
151 template<typename Item>
152 static bool SetData (Item& item, int, int column, const QVariant& value, int role)
153 {
154 if (role != Qt::CheckStateRole || column)
155 return false;
156
157 const auto state = value.value<Qt::CheckState> ();
158 if constexpr (std::is_same_v<std::decay_t<decltype (item.*CheckField)>, Qt::CheckState>)
159 item.*CheckField = state;
160 else if constexpr (std::is_same_v<std::decay_t<decltype (item.*CheckField)>, bool>)
161 item.*CheckField = state == Qt::Checked;
162 else
163 static_assert (false, "expected Qt::CheckState or bool field");
164 return true;
165 }
166 };
167
168 struct NoField {};
169 inline constexpr auto NoField_v = NoField {};
170
171 template<>
173 {
174 QHash<int, Qt::CheckState> RowsStates_;
175
176 using ParameterizedExtension::ParameterizedExtension;
177
178 static Qt::ItemFlags GetFlags (int column)
179 {
180 return column ? Qt::ItemFlags {} : Qt::ItemIsUserCheckable;
181 }
182
183 bool IsChecked (int row) const
184 {
185 return RowsStates_.value (row, Param_) == Qt::Checked;
186 }
187
188 QVariant GetDataForRole (detail::RoleTag<Qt::CheckStateRole>, const auto&, int row, int column)
189 {
190 return column ? QVariant {} : RowsStates_.value (row, Param_);
191 }
192
193 template<typename Item>
194 bool SetData (Item&, int row, int column, const QVariant& value, int role)
195 {
196 if (role != Qt::CheckStateRole || column)
197 return false;
198
199 RowsStates_ [row] = value.value<Qt::CheckState> ();
200 return true;
201 }
202 };
203
204 template<typename T, typename... Extensions>
206 , public Extensions...
207 {
208 using FieldGetter_t = QVariant (*) (const T&);
209 const QVector<FieldGetter_t> Fields_;
210
211 using FieldSetter_t = void (*) (T&, const QVariant&);
212 const QVector<FieldSetter_t> Setters_;
213 public:
214 template<auto... Getter>
215 explicit ItemsModel (const Field<Getter>&... fields)
216 : ItemsModel { std::tuple {}, fields... }
217 {
218 }
219
220 template<auto... Member, typename... ExtParams>
221 explicit ItemsModel (const std::tuple<ExtParams...>& extParams, const Field<Member>&... fields)
222 : FlatItemsModelTypedBase<T> { { fields.Name_... } }
223 , Extensions { extParams }...
224 , Fields_ { +[] (const T& t) -> QVariant { return t.*Member; }... }
225 , Setters_ { +[] (T& t, const QVariant& v) { t.*Member = v.value<std::decay_t<decltype (t.*Member)>> (); }... }
226 {
227 }
228
229 Qt::ItemFlags flags (const QModelIndex& index) const override
230 {
232 flags |= (Extensions::GetFlags (index.column ()) | ...);
233 return flags;
234 }
235
236 bool setData (const QModelIndex& index, const QVariant& value, int role) override
237 {
238 auto& item = this->Items_ [index.row ()];
239 if ((Extensions::SetData (item, index.row (), index.column (), value, role) ||...))
240 {
241 emit this->dataChanged (index, index);
242 return true;
243 }
244
245 if (role != Qt::EditRole)
246 return false;
247
248 Setters_ [index.column ()] (item, value);
249 emit this->dataChanged (index, index);
250 return true;
251 }
252 protected:
253 QVariant GetData (int row, int column, int role) const override
254 {
255 const auto& item = this->Items_ [row];
256
257 switch (role)
258 {
259 case Qt::DisplayRole:
260 case Qt::EditRole:
261 if (const auto getter = Fields_.value (column))
262 return getter (item);
263 return {};
264 case Qt::CheckStateRole:
265 return this->GetDataForRole (detail::RoleTag<Qt::CheckStateRole> {}, item, row, column);
266 case Qt::DecorationRole:
267 return this->GetDataForRole (detail::RoleTag<Qt::DecorationRole> {}, item, row, column);
268 default:
269 return {};
270 }
271 }
272
273 using Extensions::GetDataForRole...;
274
275 static QVariant GetDataForRole (auto&&...)
276 {
277 return {};
278 }
279 };
280}
QModelIndex index(int row, int col, const QModelIndex &parent={}) const override
QModelIndex parent(const QModelIndex &) const override
static constexpr auto DataRole
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition itemsmodel.h:229
ItemsModel(const std::tuple< ExtParams... > &extParams, const Field< Member > &... fields)
Definition itemsmodel.h:221
ItemsModel(const Field< Getter > &... fields)
Definition itemsmodel.h:215
QVariant GetData(int row, int column, int role) const override
Definition itemsmodel.h:253
static QVariant GetDataForRole(auto &&...)
Definition itemsmodel.h:275
bool setData(const QModelIndex &index, const QVariant &value, int role) override
Definition itemsmodel.h:236
QVariant GetData(int row, int, int role) const override
Definition itemsmodel.h:49
QVariant(*)(const T &) FieldGetter_t
Definition itemsmodel.h:30
QHash< int, QByteArray > roleNames() const override
Definition itemsmodel.h:44
QVector< QPair< QByteArray, FieldGetter_t > > FieldsList_t
Definition itemsmodel.h:31
RoledItemsModel(QObject *parent, Fields...) noexcept
Definition itemsmodel.h:37
std::integral_constant< Qt::ItemDataRole, Role > RoleTag
Definition itemsmodel.h:75
QByteArray ToByteArray()
Definition ctstring.h:124
constexpr auto NoField_v
Definition itemsmodel.h:169
RoledMemberField< RoleArg, GetterArg > RoledMemberField_v
Definition itemsmodel.h:24
QVariant GetDataForRole(detail::RoleTag< Qt::CheckStateRole >, const auto &, int row, int column)
Definition itemsmodel.h:188
bool SetData(Item &, int row, int column, const QVariant &value, int role)
Definition itemsmodel.h:194
QHash< int, Qt::CheckState > RowsStates_
Definition itemsmodel.h:174
static Qt::ItemFlags GetFlags(int column)
Definition itemsmodel.h:178
static Qt::ItemFlags GetFlags(int column)
Definition itemsmodel.h:133
static bool SetData(Item &item, int, int column, const QVariant &value, int role)
Definition itemsmodel.h:152
static QVariant GetDataForRole(detail::RoleTag< Qt::CheckStateRole >, const auto &item, int, int column)
Definition itemsmodel.h:138
static QVariant GetDataForRole(detail::RoleTag< Qt::DecorationRole >, const auto &item, int column)
Definition itemsmodel.h:110
Qt::ItemFlags GetFlags(int column) const
Definition itemsmodel.h:122
static constexpr auto Getter
Definition itemsmodel.h:19
static constexpr auto Role
Definition itemsmodel.h:20
static bool SetData(auto &&...)
Definition itemsmodel.h:82
static void GetDataForRole()
Definition itemsmodel.h:83
static Qt::ItemFlags GetFlags(auto &&...)
Definition itemsmodel.h:81
ParameterizedExtension(const std::tuple< Params... > &args)
Definition itemsmodel.h:98