17 template<
typename T,
int RoleV>
20 constexpr static auto Role = RoleV;
34 template<
typename U = T>
36 :
Value_ (std::forward<U> (value))
40 template<
typename U = T>
43 Value_ = std::forward<U> (value);
47 template<
typename U = T>
48 requires requires (T t, U u) { t == u; }
75 requires (!std::is_same_v<T, QVariant>)
80 operator QVariant ()
const
90 auto&& [...elems] = val;
91 return std::integral_constant<size_t,
sizeof... (elems)> {};
97 auto&& [...elems] = val;
101 template<
typename T,
size_t I>
110 template<
typename T,
size_t Ix>
117 +[] (
const T& t) {
return QVariant::fromValue (*
GetFieldAt<Ix> (t)); }
120 return { -1,
nullptr };
126 return []<
size_t... Ixs> (std::index_sequence<Ixs...>)
129 } (std::make_index_sequence<FieldsCount_v<T>> {});
134 constexpr auto FromField = +[] (
const ArgType_t<
decltype (F), 0>& t) {
return QVariant::fromValue (std::invoke (F, t)); };
142 const QHash<int, FieldGetter_t> Role2Getter_;
152 , Role2Getter_ { getters }
156 template<auto F,
typename V>
159 auto& item = this->
ItemAt (idx);
160 if (item.*F == value)
163 item.*F = std::forward<V> (value);
164 emit this->dataChanged (this->
index (idx, 0), this->
index (idx, 0),
165 { std::decay_t<
decltype (T {}.*F)>::Role });
168 template<
auto... Fs,
typename... Vs>
171 auto& item = this->
ItemAt (idx);
173 changedRoles.reserve (
sizeof... (values));
176 if (item.*Fs != std::forward<Vs> (values))
178 item.*Fs = std::forward<Vs> (values);
179 changedRoles << std::decay_t<
decltype (T {}.*Fs)>::Role;
183 if (!changedRoles.isEmpty ())
184 emit this->dataChanged (this->
index (idx, 0), this->
index (idx, 0), changedRoles);
187 QVariant
GetData (
int row,
int,
int role)
const override
189 if (
const auto getter = Role2Getter_.value (role))
190 return getter (this->
ItemAt (row));
196 template<CtString RoleArg, auto GetterArg>
199 static constexpr auto Getter = GetterArg;
200 static constexpr auto Role = RoleArg;
203 template<CtString RoleArg, auto GetterArg>
213 const QVector<FieldGetter_t> Fields_;
214 const QHash<int, QByteArray> Roles_;
216 template<
typename... Fields>
219 , Fields_ { +[] (
const T& t) -> QVariant {
return t.*Fields::Getter; }... }
229 QVariant
GetData (
int row,
int,
int role)
const override
231 if (
const auto getter = Fields_.value (role - this->DataRole - 1))
232 return getter (this->
ItemAt (row));
236 QHash<int, QByteArray> MakeRoles (QVector<QByteArray> fields)
const
239 result.reserve (result.size () + fields.size ());
240 for (
int i = 0; i < fields.size (); ++i)
241 result [this->
DataRole + i + 1] = std::move (fields [i]);
246 template<auto Getter>
254 template<Qt::ItemDataRole Role>
255 using RoleTag = std::integral_constant<Qt::ItemDataRole, Role>;
261 static Qt::ItemFlags
GetFlags (
auto&&...) {
return {}; }
262 static bool SetData (
auto&&...) {
return false; }
276 template<
typename... Params>
277 requires (std::is_same_v<Param, Params> || ...)
285 template<auto IconField>
288 using Extension::Extension;
294 return item.*IconField;
300 using ParameterizedExtension::ParameterizedExtension;
304 return Param_.contains (column) ? Qt::ItemIsEditable : Qt::ItemFlags {};
308 template<auto CheckField>
311 using Extension::Extension;
315 return column ? Qt::ItemFlags {} : Qt::ItemIsUserCheckable;
323 if constexpr (std::is_same_v<std::decay_t<
decltype (item.*CheckField)>, Qt::CheckState>)
324 return item.*CheckField;
325 else if constexpr (std::is_same_v<std::decay_t<
decltype (item.*CheckField)>,
bool>)
326 return item.*CheckField ? Qt::Checked : Qt::Unchecked;
328 static_assert (
false,
"expected Qt::CheckState or bool field");
331 template<
typename Item>
332 static bool SetData (Item& item,
int,
int column,
const QVariant& value,
int role)
334 if (role != Qt::CheckStateRole || column)
337 const auto state = value.value<Qt::CheckState> ();
338 if constexpr (std::is_same_v<std::decay_t<
decltype (item.*CheckField)>, Qt::CheckState>)
339 item.*CheckField = state;
340 else if constexpr (std::is_same_v<std::decay_t<
decltype (item.*CheckField)>,
bool>)
341 item.*CheckField = state == Qt::Checked;
343 static_assert (
false,
"expected Qt::CheckState or bool field");
356 using ParameterizedExtension::ParameterizedExtension;
360 return column ? Qt::ItemFlags {} : Qt::ItemIsUserCheckable;
373 template<
typename Item>
374 bool SetData (Item&,
int row,
int column,
const QVariant& value,
int role)
376 if (role != Qt::CheckStateRole || column)
379 RowsStates_ [row] = value.value<Qt::CheckState> ();
384 template<
typename T,
typename... Extensions>
386 ,
public Extensions...
388 using FieldGetter_t = QVariant (*) (
const T&);
389 const QVector<FieldGetter_t> Fields_;
391 using FieldSetter_t = void (*) (T&,
const QVariant&);
392 const QVector<FieldSetter_t> Setters_;
394 template<
auto... Getter>
400 template<
auto... Member,
typename... ExtParams>
403 , Extensions { extParams }...
404 , Fields_ { +[] (
const T& t) -> QVariant {
return t.*Member; }... }
405 , Setters_ { +[] (T& t,
const QVariant& v) { t.*Member = v.value<std::decay_t<
decltype (t.*Member)>> (); }... }
409 Qt::ItemFlags
flags (
const QModelIndex&
index)
const override
412 if (
index.isValid ())
413 flags |= (Extensions::GetFlags (
index.column ()) | ...);
417 bool setData (
const QModelIndex&
index,
const QVariant& value,
int role)
override
419 if (!
index.isValid ())
423 if ((Extensions::SetData (item,
index.row (),
index.column (), value, role) ||...))
429 if (role != Qt::EditRole)
432 Setters_ [
index.column ()] (item, value);
437 QVariant
GetData (
int row,
int column,
int role)
const override
439 const auto& item = this->
ItemAt (row);
443 case Qt::DisplayRole:
445 if (
const auto getter = Fields_.value (column))
446 return getter (item);
448 case Qt::CheckStateRole:
450 case Qt::DecorationRole:
457 using Extensions::GetDataForRole...;
QModelIndex index(int row, int col, const QModelIndex &parent={}) const override
QModelIndex parent(const QModelIndex &) const override
static constexpr auto DataRole
auto & ItemAt(this auto &&self, int row, const std::source_location &loc=std::source_location::current())
FlatItemsModelTypedBase(QStringList headers, QObject *parent=nullptr)
Qt::ItemFlags flags(const QModelIndex &index) const override
ItemsModel(const std::tuple< ExtParams... > &extParams, const Field< Member > &... fields)
ItemsModel(const Field< Getter > &... fields)
QVariant GetData(int row, int column, int role) const override
static QVariant GetDataForRole(auto &&...)
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QHash< int, QByteArray > roleNames() const override
QVector< QPair< QByteArray, FieldGetter_t > > FieldsList_t
detail::FieldGetter_t< T > FieldGetter_t
NamedItemsModel(QObject *parent, Fields...) noexcept
QVariant GetData(int row, int, int role) const override
RoledItemsModel(QObject *parent=nullptr)
QVariant GetData(int row, int, int role) const override
void SetField(int idx, V &&value)
detail::FieldGetter_t< T > FieldGetter_t
RoledItemsModel(const QHash< int, FieldGetter_t > &getters, QObject *parent=nullptr)
void SetFields(int idx, Vs &&... values)
std::integral_constant< Qt::ItemDataRole, Role > RoleTag
constexpr size_t FieldsCount_v
std::pair< int, FieldGetter_t< T > > Role2GetterPair()
decltype(GetFieldAt< I >(std::declval< T >())) FieldType_t
QHash< int, FieldGetter_t< T > > MkGetters()
QVariant(*)(const T &) FieldGetter_t
constexpr auto GetFieldAt(auto &&val)
constexpr auto GetFieldsCount(auto &&val)
QByteArray ToByteArray() noexcept
NamedMemberField< RoleArg, GetterArg > NamedMemberField_v
std::tuple_element_t< Idx+1, detail::CallTypeGetter_t< F > > ArgType_t
bool IsChecked(int row) const
QVariant GetDataForRole(detail::RoleTag< Qt::CheckStateRole >, const auto &, int row, int column)
bool SetData(Item &, int row, int column, const QVariant &value, int role)
QHash< int, Qt::CheckState > RowsStates_
static Qt::ItemFlags GetFlags(int column)
static Qt::ItemFlags GetFlags(int column)
static bool SetData(Item &item, int, int column, const QVariant &value, int role)
static QVariant GetDataForRole(detail::RoleTag< Qt::CheckStateRole >, const auto &item, int, int column)
static QVariant GetDataForRole(detail::RoleTag< Qt::DecorationRole >, const auto &item, int column)
Qt::ItemFlags GetFlags(int column) const
static constexpr auto Role
static constexpr auto Getter
static constexpr auto Role
RoleOf(RoleOf &&other)=default
RoleOf & operator=(const RoleOf &other)=default
bool operator==(const U &value) const
RoleOf(const RoleOf &other)=default
static bool SetData(auto &&...)
static void GetDataForRole()
static Qt::ItemFlags GetFlags(auto &&...)
ParameterizedExtension(const std::tuple< Params... > &args)