Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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 "qmetaobject.h"
8#include "qwidget.h"
10
11#include "private/qobject_p.h"
12#include "private/qabstractitemmodel_p.h"
13#include <QtCore/qpointer.h>
14
15#include <array>
16#include <iterator>
17
19
21{
22public:
23 Q_DECLARE_PUBLIC(QDataWidgetMapper)
24
26 : model(QAbstractItemModelPrivate::staticEmptyModel()), delegate(nullptr),
27 orientation(Qt::Horizontal), submitPolicy(QDataWidgetMapper::AutoSubmit)
28 {
29 }
30
37
38 inline int itemCount()
39 {
43 }
44
45 inline int currentIdx() const
46 {
48 }
49
50 inline QModelIndex indexAt(int itemPos)
51 {
53 ? model->index(currentIdx(), itemPos, rootIndex)
54 : model->index(itemPos, currentIdx(), rootIndex);
55 }
56
58 QAbstractItemDelegate *newDelegate) const
59 {
60 for (const WidgetMapper &e : widgetMap) {
61 QWidget *w = e.widget;
62 if (!w)
63 continue;
64 w->removeEventFilter(oldDelegate);
65 w->installEventFilter(newDelegate);
66 }
67 }
68
69 void populate();
70
71 // private slots
72 void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
73 const QList<int> &);
74 void commitData(QWidget *);
76 void modelDestroyed();
77
88
96
97 void populate(WidgetMapper &m);
98 int findWidget(QWidget *w) const;
99
100 bool commit(const WidgetMapper &m);
101
102 std::vector<WidgetMapper> widgetMap;
103 std::array<QMetaObject::Connection, 2> modelConnections;
104 std::array<QMetaObject::Connection, 2> delegateConnections;
105};
107
109{
110 for (const WidgetMapper &e : widgetMap) {
111 if (e.widget == w)
112 return int(&e - &widgetMap.front());
113 }
114 return -1;
115}
116
118{
119 if (m.widget.isNull())
120 return true; // just ignore
121
122 if (!m.currentIndex.isValid())
123 return false;
124
125 // Create copy to avoid passing the widget mappers data
126 QModelIndex idx = m.currentIndex;
127 if (m.property.isEmpty())
128 delegate->setModelData(m.widget, model, idx);
129 else
130 model->setData(idx, m.widget->property(m.property), Qt::EditRole);
131
132 return true;
133}
134
136{
137 if (m.widget.isNull())
138 return;
139
140 m.currentIndex = indexAt(m.section);
141 if (m.property.isEmpty())
142 delegate->setEditorData(m.widget, m.currentIndex);
143 else
144 m.widget->setProperty(m.property, m.currentIndex.data(Qt::EditRole));
145}
146
152
153static bool qContainsIndex(const QModelIndex &idx, const QModelIndex &topLeft,
154 const QModelIndex &bottomRight)
155{
156 return idx.row() >= topLeft.row() && idx.row() <= bottomRight.row()
157 && idx.column() >= topLeft.column() && idx.column() <= bottomRight.column();
158}
159
161 const QModelIndex &bottomRight, const QList<int> &)
162{
163 if (topLeft.parent() != rootIndex)
164 return; // not in our hierarchy
165
166 for (WidgetMapper &e : widgetMap) {
167 if (qContainsIndex(e.currentIndex, topLeft, bottomRight))
168 populate(e);
169 }
170}
171
173{
175 return;
176
177 int idx = findWidget(w);
178 if (idx == -1)
179 return; // not our widget
180
181 commit(widgetMap[idx]);
182}
183
185{
186 int idx = findWidget(w);
187 if (idx == -1)
188 return; // not our widget
189
190 switch (hint) {
192 populate(widgetMap[idx]);
193 break; }
195 w->focusNextChild();
196 break;
198 w->focusPreviousChild();
199 break;
202 // nothing
203 break;
204 }
205}
206
214
311
316{
318 d->disconnectModel();
319 d->disconnectDelegate();
320}
321
329{
331
332 if (d->model == model)
333 return;
334
335 d->disconnectModel();
336 clearMapping();
337 d->rootIndex = QModelIndex();
338 d->currentTopLeft = QModelIndex();
339
340 d->model = model;
341
342 d->modelConnections = {
347 };
348}
349
356{
357 Q_D(const QDataWidgetMapper);
359 ? static_cast<QAbstractItemModel *>(nullptr)
360 : d->model;
361}
362
380{
382 QAbstractItemDelegate *oldDelegate = d->delegate;
383 d->disconnectDelegate();
384
385 d->delegate = delegate;
386
387 if (delegate) {
388 d->delegateConnections = {
393 };
394 }
395
396 d->flipEventFilters(oldDelegate, delegate);
397}
398
403{
404 Q_D(const QDataWidgetMapper);
405 return d->delegate;
406}
407
416{
418 d->rootIndex = index;
419}
420
427{
428 Q_D(const QDataWidgetMapper);
429 return QModelIndex(d->rootIndex);
430}
431
457{
459
461 d->widgetMap.push_back({widget, section, d->indexAt(section), QByteArray()});
462 widget->installEventFilter(d->delegate);
463}
464
474void QDataWidgetMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName)
475{
477
479 d->widgetMap.push_back({widget, section, d->indexAt(section), propertyName});
480 widget->installEventFilter(d->delegate);
481}
482
489{
491
492 int idx = d->findWidget(widget);
493 if (idx == -1)
494 return;
495
496 d->widgetMap.erase(d->widgetMap.begin() + idx);
497 widget->removeEventFilter(d->delegate);
498}
499
507{
508 Q_D(const QDataWidgetMapper);
509
510 int idx = d->findWidget(widget);
511 if (idx == -1)
512 return -1;
513
514 return d->widgetMap[idx].section;
515}
516
526{
527 Q_D(const QDataWidgetMapper);
528
529 int idx = d->findWidget(widget);
530 if (idx == -1)
531 return QByteArray();
532 const auto &m = d->widgetMap[idx];
533 if (m.property.isEmpty())
534 return m.widget->metaObject()->userProperty().name();
535 else
536 return m.property;
537}
538
546{
547 Q_D(const QDataWidgetMapper);
548
549 for (auto &e : d->widgetMap) {
550 if (e.section == section)
551 return e.widget;
552 }
553
554 return nullptr;
555}
556
564{
566
567 d->populate();
568}
569
585{
587
588 for (auto &e : d->widgetMap) {
589 if (!d->commit(e))
590 return false;
591 }
592
593 return d->model->submit();
594}
595
609
620{
622 setCurrentIndex(d->itemCount() - 1);
623}
624
625
637{
639 setCurrentIndex(d->currentIdx() + 1);
640}
641
653{
655 setCurrentIndex(d->currentIdx() - 1);
656}
657
669{
671
672 if (index < 0 || index >= d->itemCount())
673 return;
674 d->currentTopLeft = d->orientation == Qt::Horizontal
675 ? d->model->index(index, 0, d->rootIndex)
676 : d->model->index(0, index, d->rootIndex);
677 d->populate();
678
680}
681
683{
684 Q_D(const QDataWidgetMapper);
685 return d->currentIdx();
686}
687
708{
710
711 if (!index.isValid()
712 || index.model() != d->model
713 || index.parent() != d->rootIndex)
714 return;
715
716 setCurrentIndex(d->orientation == Qt::Horizontal ? index.row() : index.column());
717}
718
725{
727
728 decltype(d->widgetMap) copy;
729 d->widgetMap.swap(copy); // a C++98 move
730 for (auto it = copy.crbegin(), end = copy.crend(); it != end; ++it) {
731 if (it->widget)
732 it->widget->removeEventFilter(d->delegate);
733 }
734}
735
771{
773
774 if (d->orientation == orientation)
775 return;
776
777 clearMapping();
778 d->orientation = orientation;
779}
780
782{
783 Q_D(const QDataWidgetMapper);
784 return d->orientation;
785}
786
795{
797 if (policy == d->submitPolicy)
798 return;
799
800 revert();
801 d->submitPolicy = policy;
802}
803
805{
806 Q_D(const QDataWidgetMapper);
807 return d->submitPolicy;
808}
809
811
812#include "moc_qdatawidgetmapper.cpp"
The QAbstractItemDelegate class is used to display and edit data items from a model.
void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint=NoHint)
This signal is emitted when the user has finished editing an item using the specified editor.
void commitData(QWidget *editor)
This signal must be emitted when the editor widget has completed editing the data,...
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()
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This signal is emitted whenever the data in an existing item changes.
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
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &)
QPersistentModelIndex rootIndex
bool commit(const WidgetMapper &m)
void closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)
std::array< QMetaObject::Connection, 2 > modelConnections
QPersistentModelIndex currentTopLeft
QAbstractItemDelegate * delegate
QModelIndex indexAt(int itemPos)
int findWidget(QWidget *w) const
void flipEventFilters(QAbstractItemDelegate *oldDelegate, QAbstractItemDelegate *newDelegate) const
std::array< QMetaObject::Connection, 2 > delegateConnections
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.
\inmodule QtCore Represents a handle to a signal-slot (or signal-functor) connection.
\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.
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
Definition qobject_p.h:299
\inmodule QtCore
Definition qobject.h:103
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2339
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
void removeEventFilter(QObject *obj)
Removes an event filter object obj from this object.
Definition qobject.cpp:2370
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.
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]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
Definition qcompare.h:63
Orientation
Definition qnamespace.h:98
@ Horizontal
Definition qnamespace.h:99
@ EditRole
static jboolean copy(JNIEnv *, jobject)
static bool qContainsIndex(const QModelIndex &idx, const QModelIndex &topLeft, const QModelIndex &bottomRight)
DBusConnection * connection
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
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:158
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
QSqlQueryModel * model
[16]
QSizePolicy policy