17 template<
typename T,
int RoleV>
20 constexpr
static auto Role = RoleV;
34 template<
typename U = T>
40 template<
typename U = T>
43 Value_ = std::forward<U> (value);
47 template<
typename U = T>
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>
102 using FieldType_t = decltype (GetFieldAt<I> (std::declval<T> ()));
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...>)
128 return QHash<int, FieldGetter_t<T>> { Role2GetterPair<T, Ixs> ()... };
129 } (std::make_index_sequence<FieldsCount_v<T>> {});
142 const QHash<int, FieldGetter_t> Role2Getter_;
146 , Role2Getter_ { detail::MkGetters<T> () }
152 , Role2Getter_ { getters }
156 template<auto F,
typename V>
159 if (this->
Items_ [idx].*F == value)
162 this->
Items_ [idx].*F = std::forward<V> (value);
163 emit this->dataChanged (this->
index (idx, 0), this->
index (idx, 0),
164 { std::decay_t<decltype (T {}.*F)>::Role });
167 template<
auto... Fs,
typename... Vs>
171 changedRoles.reserve (
sizeof... (values));
174 if (this->
Items_ [idx].*Fs != std::forward<Vs> (values))
176 this->
Items_ [idx].*Fs = std::forward<Vs> (values);
177 changedRoles << std::decay_t<decltype (T {}.*Fs)>::Role;
181 if (!changedRoles.isEmpty ())
182 emit this->dataChanged (this->
index (idx, 0), this->
index (idx, 0), changedRoles);
185 QVariant
GetData (
int row,
int,
int role)
const override 187 if (
const auto getter = Role2Getter_.value (role))
188 return getter (this->
Items_.at (row));
194 template<CtString RoleArg, auto GetterArg>
197 static constexpr
auto Getter = GetterArg;
198 static constexpr
auto Role = RoleArg;
201 template<CtString RoleArg, auto GetterArg>
211 const QVector<FieldGetter_t> Fields_;
212 const QHash<int, QByteArray> Roles_;
214 template<
typename... Fields>
217 ,
Fields_ { +[] (
const T& t) -> QVariant {
return t.*Fields::Getter; }... }
218 , Roles_ { MakeRoles ({ ToByteArray<Fields::Role> ()... }) }
227 QVariant
GetData (
int row,
int,
int role)
const override 229 if (
const auto getter =
Fields_.value (role - this->DataRole - 1))
230 return getter (this->
Items_.at (row));
234 QHash<int, QByteArray> MakeRoles (QVector<QByteArray>
fields)
const 237 result.reserve (result.size () +
fields.size ());
238 for (
int i = 0; i <
fields.size (); ++i)
244 template<auto Getter>
252 template<Qt::ItemDataRole Role>
253 using RoleTag = std::integral_constant<Qt::ItemDataRole, Role>;
259 static Qt::ItemFlags
GetFlags (
auto&&...) {
return {}; }
260 static bool SetData (
auto&&...) {
return false; }
274 template<
typename... Params>
283 template<auto IconField>
286 using Extension::Extension;
292 return item.*IconField;
298 using ParameterizedExtension::ParameterizedExtension;
302 return Param_.contains (column) ? Qt::ItemIsEditable : Qt::ItemFlags {};
306 template<auto CheckField>
309 using Extension::Extension;
313 return column ? Qt::ItemFlags {} : Qt::ItemIsUserCheckable;
321 if constexpr (std::is_same_v<std::decay_t<decltype (item.*CheckField)>, Qt::CheckState>)
322 return item.*CheckField;
323 else if constexpr (std::is_same_v<std::decay_t<decltype (item.*CheckField)>,
bool>)
324 return item.*CheckField ? Qt::Checked : Qt::Unchecked;
326 static_assert (
false,
"expected Qt::CheckState or bool field");
329 template<
typename Item>
330 static bool SetData (
Item& item,
int,
int column,
const QVariant& value,
int role)
332 if (role != Qt::CheckStateRole || column)
335 const auto state = value.value<Qt::CheckState> ();
336 if constexpr (std::is_same_v<std::decay_t<decltype (item.*CheckField)>, Qt::CheckState>)
337 item.*CheckField = state;
338 else if constexpr (std::is_same_v<std::decay_t<decltype (item.*CheckField)>,
bool>)
339 item.*CheckField = state == Qt::Checked;
341 static_assert (
false,
"expected Qt::CheckState or bool field");
354 using ParameterizedExtension::ParameterizedExtension;
358 return column ? Qt::ItemFlags {} : Qt::ItemIsUserCheckable;
363 return RowsStates_.value (row, Param_) == Qt::Checked;
368 return column ? QVariant {} : RowsStates_.value (row, Param_);
371 template<
typename Item>
372 bool SetData (
Item&,
int row,
int column,
const QVariant& value,
int role)
374 if (role != Qt::CheckStateRole || column)
377 RowsStates_ [row] = value.value<Qt::CheckState> ();
382 template<
typename T,
typename... Extensions>
384 ,
public Extensions...
386 using FieldGetter_t = QVariant (*) (
const T&);
387 const QVector<FieldGetter_t>
Fields_;
389 using FieldSetter_t = void (*) (T&,
const QVariant&);
390 const QVector<FieldSetter_t> Setters_;
392 template<
auto... Getter>
398 template<
auto... Member,
typename... ExtParams>
401 , Extensions { extParams }...
402 ,
Fields_ { +[] (
const T& t) -> QVariant {
return t.*Member; }... }
403 , Setters_ { +[] (T& t,
const QVariant& v) { t.*Member = v.value<std::decay_t<decltype (t.*Member)>> (); }... }
407 Qt::ItemFlags
flags (
const QModelIndex&
index)
const override 410 flags |= (Extensions::GetFlags (
index.column ()) | ...);
414 bool setData (
const QModelIndex&
index,
const QVariant& value,
int role)
override 416 auto& item = this->
Items_ [index.row ()];
417 if ((Extensions::SetData (item,
index.row (),
index.column (), value, role) ||...))
423 if (role != Qt::EditRole)
426 Setters_ [
index.column ()] (item, value);
431 QVariant
GetData (
int row,
int column,
int role)
const override 433 const auto& item = this->
Items_ [row];
437 case Qt::DisplayRole:
439 if (
const auto getter =
Fields_.value (column))
440 return getter (item);
442 case Qt::CheckStateRole:
444 case Qt::DecorationRole:
451 using Extensions::GetDataForRole...;
static QVariant GetDataForRole(detail::RoleTag< Qt::CheckStateRole >, const auto &item, int, int column)
NamedItemsModel(QObject *parent, Fields...) noexcept
ItemsModel(const Field< Getter > &... fields)
QModelIndex index(int row, int col, const QModelIndex &parent={}) const override
RoleOf & operator=(const RoleOf &other)=default
RoledItemsModel(QObject *parent=nullptr)
bool setData(const QModelIndex &index, const QVariant &value, int role) override
std::integral_constant< Qt::ItemDataRole, Role > RoleTag
bool IsChecked(int row) const
QVariant GetData(int row, int, int role) const override
static Qt::ItemFlags GetFlags(int column)
static QVariant GetDataForRole(detail::RoleTag< Qt::DecorationRole >, const auto &item, int column)
QHash< int, FieldGetter_t< T > > MkGetters()
static Qt::ItemFlags GetFlags(int column)
QVariant GetData(int row, int, int role) const override
QVariant GetData(int row, int column, int role) const override
QVariant(*)(const T &) FieldGetter_t
QHash< int, Qt::CheckState > RowsStates_
requires(std::is_same_v< Param, Params >||...) explicit ParameterizedExtension(const std
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptrs... > > tuple
static constexpr auto Role
void SetFields(int idx, Vs &&... values)
requires requires(T t, U u)
QVariant GetDataForRole(detail::RoleTag< Qt::CheckStateRole >, const auto &, int row, int column)
NamedMemberField< RoleArg, GetterArg > NamedMemberField_v
Qt::ItemFlags flags(const QModelIndex &index) const override
decltype(GetFieldAt< I >(std::declval< T >())) FieldType_t
RoledItemsModel(const QHash< int, FieldGetter_t > &getters, QObject *parent=nullptr)
static QVariant GetDataForRole(auto &&...)
static void GetDataForRole()
detail::FieldGetter_t< T > FieldGetter_t
static bool SetData(auto &&...)
constexpr size_t FieldsCount_v
QVector< QPair< QByteArray, FieldGetter_t > > FieldsList_t
QModelIndex parent(const QModelIndex &) const override
detail::FieldGetter_t< Item > FieldGetter_t
static bool SetData(Item &item, int, int column, const QVariant &value, int role)
requires(Tup1Size==Tup2Size) const expr auto ZipWith(Tup1 &&tup1
void SetField(int idx, V &&value)
std::tuple_element_t< Idx+1, detail::CallTypeGetter_t< F > > ArgType_t
std::pair< int, FieldGetter_t< T > > Role2GetterPair()
bool operator==(const U &value) const
bool SetData(Item &, int row, int column, const QVariant &value, int role)
auto Tup2 &&tup2 noexcept
constexpr detail::MemberPtrs< Ptrs... > fields
Qt::ItemFlags GetFlags(int column) const
constexpr auto GetFieldsCount(auto &&val)
static Qt::ItemFlags GetFlags(auto &&...)
ItemsModel(const std::tuple< ExtParams... > &extParams, const Field< Member > &... fields)
constexpr auto GetFieldAt(auto &&val)
QHash< int, QByteArray > roleNames() const override
static constexpr auto Role
static constexpr auto DataRole
static constexpr auto Getter