20class QDataWidgetMapperPrivate:
public QObjectPrivate
23 Q_DECLARE_PUBLIC(QDataWidgetMapper)
25 QDataWidgetMapperPrivate()
26 : model(QAbstractItemModelPrivate::staticEmptyModel()), delegate(
nullptr),
27 orientation(Qt::Horizontal), submitPolicy(QDataWidgetMapper::AutoSubmit)
31 QAbstractItemModel *model;
32 QAbstractItemDelegate *delegate;
33 Qt::Orientation orientation;
34 QDataWidgetMapper::SubmitPolicy submitPolicy;
35 QPersistentModelIndex rootIndex;
36 QPersistentModelIndex currentTopLeft;
38 inline int itemCount()
40 return orientation == Qt::Horizontal
41 ? model->rowCount(rootIndex)
42 : model->columnCount(rootIndex);
45 inline int currentIdx()
const
47 return orientation == Qt::Horizontal ? currentTopLeft.row() : currentTopLeft.column();
50 inline QModelIndex indexAt(
int itemPos)
52 return orientation == Qt::Horizontal
53 ? model->index(currentIdx(), itemPos, rootIndex)
54 : model->index(itemPos, currentIdx(), rootIndex);
57 void flipEventFilters(QAbstractItemDelegate *oldDelegate,
58 QAbstractItemDelegate *newDelegate)
const
60 for (
const WidgetMapper &e : widgetMap) {
61 QWidget *w = e.widget;
64 w->removeEventFilter(oldDelegate);
65 w->installEventFilter(newDelegate);
72 void dataChanged(
const QModelIndex &topLeft,
const QModelIndex &bottomRight,
74 void commitData(QWidget *);
75 void closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint);
76 void modelDestroyed();
78 void disconnectModel()
80 for (
const QMetaObject::Connection &connection : modelConnections)
81 QObject::disconnect(connection);
83 void disconnectDelegate()
85 for (
const QMetaObject::Connection &connection : delegateConnections)
86 QObject::disconnect(connection);
91 QPointer<QWidget> widget;
93 QPersistentModelIndex currentIndex;
97 void populate(WidgetMapper &m);
98 int findWidget(QWidget *w)
const;
100 bool commit(
const WidgetMapper &m);
102 std::vector<WidgetMapper> widgetMap;
103 std::array<QMetaObject::Connection, 2> modelConnections;
104 std::array<QMetaObject::Connection, 2> delegateConnections;
117bool QDataWidgetMapperPrivate::commit(
const WidgetMapper &m)
119 if (m.widget.isNull())
122 if (!m.currentIndex.isValid())
127 if (m.property.isEmpty())
128 delegate->setModelData(m.widget, model, idx);
130 model->setData(idx, m.widget->property(m.property), Qt::EditRole);
135void QDataWidgetMapperPrivate::populate(WidgetMapper &m)
137 if (m.widget.isNull())
140 m.currentIndex = indexAt(m.section);
141 if (m.property.isEmpty())
142 delegate->setEditorData(m.widget, m.currentIndex);
144 m.widget->setProperty(m.property, m.currentIndex.data(Qt::EditRole));
184void QDataWidgetMapperPrivate::closeEditor(QWidget *w, QAbstractItemDelegate::EndEditHint hint)
186 int idx = findWidget(w);
191 case QAbstractItemDelegate::RevertModelCache: {
192 populate(widgetMap[idx]);
194 case QAbstractItemDelegate::EditNextItem:
197 case QAbstractItemDelegate::EditPreviousItem:
198 w->focusPreviousChild();
200 case QAbstractItemDelegate::SubmitModelCache:
201 case QAbstractItemDelegate::NoHint:
327void QDataWidgetMapper::setModel(QAbstractItemModel *model)
329 Q_D(QDataWidgetMapper);
331 if (d->model == model)
334 d->disconnectModel();
336 d->rootIndex = QModelIndex();
337 d->currentTopLeft = QModelIndex();
341 d->modelConnections = {
342 QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
343 d, &QDataWidgetMapperPrivate::dataChanged),
344 QObjectPrivate::connect(model, &QAbstractItemModel::destroyed,
345 d, &QDataWidgetMapperPrivate::modelDestroyed)
378void QDataWidgetMapper::setItemDelegate(QAbstractItemDelegate *delegate)
380 Q_D(QDataWidgetMapper);
381 QAbstractItemDelegate *oldDelegate = d->delegate;
382 d->disconnectDelegate();
384 d->delegate = delegate;
387 d->delegateConnections = {
388 QObjectPrivate::connect(delegate, &QAbstractItemDelegate::commitData,
389 d, &QDataWidgetMapperPrivate::commitData),
390 QObjectPrivate::connect(delegate, &QAbstractItemDelegate::closeEditor,
391 d, &QDataWidgetMapperPrivate::closeEditor)
395 d->flipEventFilters(oldDelegate, delegate);
455void QDataWidgetMapper::addMapping(QWidget *widget,
int section)
457 Q_D(QDataWidgetMapper);
459 removeMapping(widget);
460 d->widgetMap.push_back({widget, section, d->indexAt(section), QByteArray()});
461 widget->installEventFilter(d->delegate);
471void QDataWidgetMapper::addMapping(QWidget *widget,
int section,
const QByteArray &propertyName)
473 Q_D(QDataWidgetMapper);
475 removeMapping(widget);
476 d->widgetMap.push_back({widget, section, d->indexAt(section), propertyName});
477 widget->installEventFilter(d->delegate);
664void QDataWidgetMapper::setCurrentIndex(
int index)
666 Q_D(QDataWidgetMapper);
668 if (index < 0 || index >= d->itemCount())
670 d->currentTopLeft = d->orientation == Qt::Horizontal
671 ? d->model->index(index, 0, d->rootIndex)
672 : d->model->index(0, index, d->rootIndex);
675 emit currentIndexChanged(index);