Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdatawidgetmapper.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qdatawidgetmapper.h"
5
7#include "qitemdelegate.h"
8#include "qmetaobject.h"
9#include "qwidget.h"
10#include "qstyleditemdelegate.h"
11#include "private/qobject_p.h"
12#include "private/qabstractitemmodel_p.h"
13
14#include <iterator>
15
17
19{
20public:
21 Q_DECLARE_PUBLIC(QDataWidgetMapper)
22
24 : model(QAbstractItemModelPrivate::staticEmptyModel()), delegate(nullptr),
25 orientation(Qt::Horizontal), submitPolicy(QDataWidgetMapper::AutoSubmit)
26 {
27 }
28
35
36 inline int itemCount()
37 {
41 }
42
43 inline int currentIdx() const
44 {
46 }
47
48 inline QModelIndex indexAt(int itemPos)
49 {
51 ? model->index(currentIdx(), itemPos, rootIndex)
52 : model->index(itemPos, currentIdx(), rootIndex);
53 }
54
56 QAbstractItemDelegate *newDelegate) const
57 {
58 for (const WidgetMapper &e : widgetMap) {
59 QWidget *w = e.widget;
60 if (!w)
61 continue;
62 w->removeEventFilter(oldDelegate);
63 w->installEventFilter(newDelegate);
64 }
65 }
66
67 void populate();
68
69 // private slots
70 void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
71 const QList<int> &);
72 void _q_commitData(QWidget *);
74 void _q_modelDestroyed();
75
77 {
82 };
83
84 void populate(WidgetMapper &m);
85 int findWidget(QWidget *w) const;
86
87 bool commit(const WidgetMapper &m);
88
89 std::vector<WidgetMapper> widgetMap;
90};
92
94{
95 for (const WidgetMapper &e : widgetMap) {
96 if (e.widget == w)
97 return int(&e - &widgetMap.front());
98 }
99 return -1;
100}
101
103{
104 if (m.widget.isNull())
105 return true; // just ignore
106
107 if (!m.currentIndex.isValid())
108 return false;
109
110 // Create copy to avoid passing the widget mappers data
111 QModelIndex idx = m.currentIndex;
112 if (m.property.isEmpty())
113 delegate->setModelData(m.widget, model, idx);
114 else
115 model->setData(idx, m.widget->property(m.property), Qt::EditRole);
116
117 return true;
118}
119
121{
122 if (m.widget.isNull())
123 return;
124
125 m.currentIndex = indexAt(m.section);
126 if (m.property.isEmpty())
127 delegate->setEditorData(m.widget, m.currentIndex);
128 else
129 m.widget->setProperty(m.property, m.currentIndex.data(Qt::EditRole));
130}
131
133{
134 for (WidgetMapper &e : widgetMap)
135 populate(e);
136}
137
138static bool qContainsIndex(const QModelIndex &idx, const QModelIndex &topLeft,
139 const QModelIndex &bottomRight)
140{
141 return idx.row() >= topLeft.row() && idx.row() <= bottomRight.row()
142 && idx.column() >= topLeft.column() && idx.column() <= bottomRight.column();
143}
144
146 const QModelIndex &bottomRight, const QList<int> &)
147{
148 if (topLeft.parent() != rootIndex)
149 return; // not in our hierarchy
150
151 for (WidgetMapper &e : widgetMap) {
152 if (qContainsIndex(e.currentIndex, topLeft, bottomRight))
153 populate(e);
154 }
155}
156
158{
160 return;
161
162 int idx = findWidget(w);
163 if (idx == -1)
164 return; // not our widget
165
166 commit(widgetMap[idx]);
167}
168
170{
171 int idx = findWidget(w);
172 if (idx == -1)
173 return; // not our widget
174
175 switch (hint) {
177 populate(widgetMap[idx]);
178 break; }
180 w->focusNextChild();
181 break;
183 w->focusPreviousChild();
184 break;
187 // nothing
188 break;
189 }
190}
191
193{
195
196 model = nullptr;
198}
199
293{
295}
296
301{
302}
303
311{
313
314 if (d->model == model)
315 return;
316
317 if (d->model) {
318 disconnect(d->model, SIGNAL(dataChanged(QModelIndex, QModelIndex, QList<int>)), this,
319 SLOT(_q_dataChanged(QModelIndex, QModelIndex, QList<int>)));
320 disconnect(d->model, SIGNAL(destroyed()), this,
321 SLOT(_q_modelDestroyed()));
322 }
323 clearMapping();
324 d->rootIndex = QModelIndex();
325 d->currentTopLeft = QModelIndex();
326
327 d->model = model;
328
330 SLOT(_q_dataChanged(QModelIndex, QModelIndex, QList<int>)));
331 connect(model, SIGNAL(destroyed()), SLOT(_q_modelDestroyed()));
332}
333
340{
341 Q_D(const QDataWidgetMapper);
343 ? static_cast<QAbstractItemModel *>(nullptr)
344 : d->model;
345}
346
364{
366 QAbstractItemDelegate *oldDelegate = d->delegate;
367 if (oldDelegate) {
368 disconnect(oldDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(_q_commitData(QWidget*)));
370 this, SLOT(_q_closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
371 }
372
373 d->delegate = delegate;
374
375 if (delegate) {
376 connect(delegate, SIGNAL(commitData(QWidget*)), SLOT(_q_commitData(QWidget*)));
379 }
380
381 d->flipEventFilters(oldDelegate, delegate);
382}
383
388{
389 Q_D(const QDataWidgetMapper);
390 return d->delegate;
391}
392
401{
403 d->rootIndex = index;
404}
405
412{
413 Q_D(const QDataWidgetMapper);
414 return QModelIndex(d->rootIndex);
415}
416
442{
444
446 d->widgetMap.push_back({widget, section, d->indexAt(section), QByteArray()});
447 widget->installEventFilter(d->delegate);
448}
449
459void QDataWidgetMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName)
460{
462
464 d->widgetMap.push_back({widget, section, d->indexAt(section), propertyName});
465 widget->installEventFilter(d->delegate);
466}
467
474{
476
477 int idx = d->findWidget(widget);
478 if (idx == -1)
479 return;
480
481 d->widgetMap.erase(d->widgetMap.begin() + idx);
482 widget->removeEventFilter(d->delegate);
483}
484
492{
493 Q_D(const QDataWidgetMapper);
494
495 int idx = d->findWidget(widget);
496 if (idx == -1)
497 return -1;
498
499 return d->widgetMap[idx].section;
500}
501
511{
512 Q_D(const QDataWidgetMapper);
513
514 int idx = d->findWidget(widget);
515 if (idx == -1)
516 return QByteArray();
517 const auto &m = d->widgetMap[idx];
518 if (m.property.isEmpty())
519 return m.widget->metaObject()->userProperty().name();
520 else
521 return m.property;
522}
523
531{
532 Q_D(const QDataWidgetMapper);
533
534 for (auto &e : d->widgetMap) {
535 if (e.section == section)
536 return e.widget;
537 }
538
539 return nullptr;
540}
541
549{
551
552 d->populate();
553}
554
570{
572
573 for (auto &e : d->widgetMap) {
574 if (!d->commit(e))
575 return false;
576 }
577
578 return d->model->submit();
579}
580
591{
593}
594
605{
607 setCurrentIndex(d->itemCount() - 1);
608}
609
610
622{
624 setCurrentIndex(d->currentIdx() + 1);
625}
626
638{
640 setCurrentIndex(d->currentIdx() - 1);
641}
642
654{
656
657 if (index < 0 || index >= d->itemCount())
658 return;
659 d->currentTopLeft = d->orientation == Qt::Horizontal
660 ? d->model->index(index, 0, d->rootIndex)
661 : d->model->index(0, index, d->rootIndex);
662 d->populate();
663
665}
666
668{
669 Q_D(const QDataWidgetMapper);
670 return d->currentIdx();
671}
672
693{
695
696 if (!index.isValid()
697 || index.model() != d->model
698 || index.parent() != d->rootIndex)
699 return;
700
701 setCurrentIndex(d->orientation == Qt::Horizontal ? index.row() : index.column());
702}
703
710{
712
713 decltype(d->widgetMap) copy;
714 d->widgetMap.swap(copy); // a C++98 move
715 for (auto it = copy.crbegin(), end = copy.crend(); it != end; ++it) {
716 if (it->widget)
717 it->widget->removeEventFilter(d->delegate);
718 }
719}
720
756{
758
759 if (d->orientation == orientation)
760 return;
761
762 clearMapping();
763 d->orientation = orientation;
764}
765
767{
768 Q_D(const QDataWidgetMapper);
769 return d->orientation;
770}
771
780{
782 if (policy == d->submitPolicy)
783 return;
784
785 revert();
786 d->submitPolicy = policy;
787}
788
790{
791 Q_D(const QDataWidgetMapper);
792 return d->submitPolicy;
793}
794
796
797#include "moc_qdatawidgetmapper.cpp"
The QAbstractItemDelegate class is used to display and edit data items from a model.
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const
Sets the contents of the given editor to the data for the item at the given index.
EndEditHint
This enum describes the different hints that the delegate can give to the model and view components t...
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
Sets the data for the item at the given index in the model to the contents of the given editor.
static QAbstractItemModel * staticEmptyModel()
virtual Q_INVOKABLE int rowCount(const QModelIndex &parent=QModelIndex()) const =0
Returns the number of rows under the given parent.
virtual Q_INVOKABLE bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Sets the role data for the item at index to value.
virtual Q_INVOKABLE int columnCount(const QModelIndex &parent=QModelIndex()) const =0
Returns the number of columns for the children of the given parent.
virtual Q_INVOKABLE QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const =0
Returns the index of the item in the model specified by the given row, column and parent index.
\inmodule QtCore
Definition qbytearray.h:57
QPersistentModelIndex rootIndex
bool commit(const WidgetMapper &m)
void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &)
QPersistentModelIndex currentTopLeft
QAbstractItemDelegate * delegate
QModelIndex indexAt(int itemPos)
void _q_closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)
int findWidget(QWidget *w) const
void flipEventFilters(QAbstractItemDelegate *oldDelegate, QAbstractItemDelegate *newDelegate) const
QDataWidgetMapper::SubmitPolicy submitPolicy
QAbstractItemModel * model
std::vector< WidgetMapper > widgetMap
The QDataWidgetMapper class provides mapping between a section of a data model to widgets.
QModelIndex rootIndex() const
Returns the current root index.
SubmitPolicy submitPolicy
the current submit policy
void revert()
Repopulates all widgets with the current data of the model.
bool submit()
Submits all changes from the mapped widgets to the model.
void setSubmitPolicy(SubmitPolicy policy)
virtual void setCurrentIndex(int index)
void toLast()
Populates the widgets with data from the last row of the model if the orientation is horizontal (the ...
void toFirst()
Populates the widgets with data from the first row of the model if the orientation is horizontal (the...
QDataWidgetMapper(QObject *parent=nullptr)
Constructs a new QDataWidgetMapper with parent object parent.
void clearMapping()
Clears all mappings.
void currentIndexChanged(int index)
This signal is emitted after the current index has changed and all widgets were populated with new da...
void setItemDelegate(QAbstractItemDelegate *delegate)
Sets the item delegate to delegate.
void setRootIndex(const QModelIndex &index)
Sets the root item to index.
int mappedSection(QWidget *widget) const
Returns the section the widget is mapped to or -1 if the widget is not mapped.
int currentIndex
the current row or column
Qt::Orientation orientation
the orientation of the model
void toNext()
Populates the widgets with data from the next row of the model if the orientation is horizontal (the ...
SubmitPolicy
This enum describes the possible submit policies a QDataWidgetMapper supports.
QByteArray mappedPropertyName(QWidget *widget) const
~QDataWidgetMapper()
Destroys the object.
void addMapping(QWidget *widget, int section)
Adds a mapping between a widget and a section from the model.
QAbstractItemModel * model() const
Returns the current model.
void setCurrentModelIndex(const QModelIndex &index)
Sets the current index to the row of the index if the orientation is horizontal (the default),...
void setOrientation(Qt::Orientation aOrientation)
void toPrevious()
Populates the widgets with data from the previous row of the model if the orientation is horizontal (...
QWidget * mappedWidgetAt(int section) const
Returns the widget that is mapped at section, or 0 if no widget is mapped at that section.
QAbstractItemDelegate * itemDelegate() const
Returns the current item delegate.
void removeMapping(QWidget *widget)
Removes the mapping for the given widget.
void setModel(QAbstractItemModel *model)
Sets the current model to model.
Definition qlist.h:74
\inmodule QtCore
constexpr int row() const noexcept
Returns the row this model index refers to.
QModelIndex parent() const
Returns the parent of the model index, or QModelIndex() if it has no parent.
constexpr int column() const noexcept
Returns the column this model index refers to.
\inmodule QtCore
Definition qobject.h:90
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2269
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
void removeEventFilter(QObject *obj)
Removes an event filter object obj from this object.
Definition qobject.cpp:2300
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
int column() const
Returns the column this persistent model index refers to.
int row() const
Returns the row this persistent model index refers to.
\inmodule QtCore
Definition qpointer.h:18
The QStyledItemDelegate class provides display and editing facilities for data items from a model.
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
QOpenGLWidget * widget
[1]
double e
QSet< QString >::iterator it
Combined button and popup list for selecting options.
Orientation
Definition qnamespace.h:97
@ Horizontal
Definition qnamespace.h:98
@ EditRole
static jboolean copy(JNIEnv *, jobject)
static bool qContainsIndex(const QModelIndex &idx, const QModelIndex &topLeft, const QModelIndex &bottomRight)
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
const GLfloat * m
GLfloat GLfloat GLfloat w
[0]
GLuint index
[2]
GLuint GLuint end
GLint GLint GLint GLint GLsizei GLsizei GLsizei GLboolean commit
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define emit
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:145
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
QSqlQueryModel * model
[16]
myObject disconnect()
[26]
QSizePolicy policy
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent