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 (t.*F); };
142 const QHash<int, FieldGetter_t> Role2Getter_;
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; }... }
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)
239 result [this->
DataRole + i + 1] = std::move (fields [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>
275 requires (std::is_same_v<Param, 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;
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
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...;
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
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
bool operator==(const U &value) const
static constexpr auto Role
RoleOf(RoleOf &&other)=default
RoleOf & operator=(const RoleOf &other)=default
RoleOf(const RoleOf &other)=default
static bool SetData(auto &&...)
static void GetDataForRole()
static Qt::ItemFlags GetFlags(auto &&...)
ParameterizedExtension(const std::tuple< Params... > &args)