/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdatawidgetmapper.h"

#include "qabstractitemmodel.h"
#include "qitemdelegate.h"
#include "qmetaobject.h"
#include "qwidget.h"
#include "private/qobject_p.h"
#include "private/qabstractitemmodel_p.h"

#include <iterator>

QT_BEGIN_NAMESPACE

class QDataWidgetMapperPrivate: public QObjectPrivate
{
public:
    Q_DECLARE_PUBLIC(QDataWidgetMapper)

    QDataWidgetMapperPrivate()
        : model(QAbstractItemModelPrivate::staticEmptyModel()), delegate(nullptr),
          orientation(Qt::Horizontal), submitPolicy(QDataWidgetMapper::AutoSubmit)
    {
    }

    QAbstractItemModel *model;
    QAbstractItemDelegate *delegate;
    Qt::Orientation orientation;
    QDataWidgetMapper::SubmitPolicy submitPolicy;
    QPersistentModelIndex rootIndex;
    QPersistentModelIndex currentTopLeft;

    inline int itemCount()
    {
        return orientation == Qt::Horizontal
            ? model->rowCount(rootIndex)
            : model->columnCount(rootIndex);
    }

    inline int currentIdx() const
    {
        return orientation == Qt::Horizontal ? currentTopLeft.row() : currentTopLeft.column();
    }

    inline QModelIndex indexAt(int itemPos)
    {
        return orientation == Qt::Horizontal
            ? model->index(currentIdx(), itemPos, rootIndex)
            : model->index(itemPos, currentIdx(), rootIndex);
    }

    void flipEventFilters(QAbstractItemDelegate *oldDelegate,
                          QAbstractItemDelegate *newDelegate) const
    {
        for (const WidgetMapper &e : widgetMap) {
            QWidget *w = e.widget;
            if (!w)
                continue;
            w->removeEventFilter(oldDelegate);
            w->installEventFilter(newDelegate);
        }
    }

    void populate();

    // private slots
    void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &);
    void _q_commitData(QWidget *);
    void _q_closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint);
    void _q_modelDestroyed();

    struct WidgetMapper
    {
        QPointer<QWidget> widget;
        int section;
        QPersistentModelIndex currentIndex;
        QByteArray property;
    };

    void populate(WidgetMapper &m);
    int findWidget(QWidget *w) const;

    bool commit(const WidgetMapper &m);

    std::vector<WidgetMapper> widgetMap;
};
Q_DECLARE_TYPEINFO(QDataWidgetMapperPrivate::WidgetMapper, Q_MOVABLE_TYPE);

int QDataWidgetMapperPrivate::findWidget(QWidget *w) const
{
    for (const WidgetMapper &e : widgetMap) {
        if (e.widget == w)
            return int(&e - &widgetMap.front());
    }
    return -1;
}

bool QDataWidgetMapperPrivate::commit(const WidgetMapper &m)
{
    if (m.widget.isNull())
        return true; // just ignore

    if (!m.currentIndex.isValid())
        return false;

    // Create copy to avoid passing the widget mappers data
    QModelIndex idx = m.currentIndex;
    if (m.property.isEmpty())
        delegate->setModelData(m.widget, model, idx);
    else
        model->setData(idx, m.widget->property(m.property), Qt::EditRole);

    return true;
}

void QDataWidgetMapperPrivate::populate(WidgetMapper &m)
{
    if (m.widget.isNull())
        return;

    m.currentIndex = indexAt(m.section);
    if (m.property.isEmpty())
        delegate->setEditorData(m.widget, m.currentIndex);
    else
        m.widget->setProperty(m.property, m.currentIndex.data(Qt::EditRole));
}

void QDataWidgetMapperPrivate::populate()
{
    for (WidgetMapper &e : widgetMap)
        populate(e);
}

static bool qContainsIndex(const QModelIndex &idx, const QModelIndex &topLeft,
                           const QModelIndex &bottomRight)
{
    return idx.row() >= topLeft.row() && idx.row() <= bottomRight.row()
           && idx.column() >= topLeft.column() && idx.column() <= bottomRight.column();
}

void QDataWidgetMapperPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &)
{
    if (topLeft.parent() != rootIndex)
        return; // not in our hierarchy

    for (WidgetMapper &e : widgetMap) {
        if (qContainsIndex(e.currentIndex, topLeft, bottomRight))
            populate(e);
    }
}

void QDataWidgetMapperPrivate::_q_commitData(QWidget *w)
{
    if (submitPolicy == QDataWidgetMapper::ManualSubmit)
        return;

    int idx = findWidget(w);
    if (idx == -1)
        return; // not our widget

    commit(widgetMap[idx]);
}

void QDataWidgetMapperPrivate::_q_closeEditor(QWidget *w, QAbstractItemDelegate::EndEditHint hint)
{
    int idx = findWidget(w);
    if (idx == -1)
        return; // not our widget

    switch (hint) {
    case QAbstractItemDelegate::RevertModelCache: {
        populate(widgetMap[idx]);
        break; }
    case QAbstractItemDelegate::EditNextItem:
        w->focusNextChild();
        break;
    case QAbstractItemDelegate::EditPreviousItem:
        w->focusPreviousChild();
        break;
    case QAbstractItemDelegate::SubmitModelCache:
    case QAbstractItemDelegate::NoHint:
        // nothing
        break;
    }
}

void QDataWidgetMapperPrivate::_q_modelDestroyed()
{
    Q_Q(QDataWidgetMapper);

    model = nullptr;
    q->setModel(QAbstractItemModelPrivate::staticEmptyModel());
}

/*!
    \class QDataWidgetMapper
    \brief The QDataWidgetMapper class provides mapping between a section
    of a data model to widgets.
    \since 4.2
    \ingroup model-view
    \ingroup advanced
    \inmodule QtWidgets

    QDataWidgetMapper can be used to create data-aware widgets by mapping
    them to sections of an item model. A section is a column of a model
    if the orientation is horizontal (the default), otherwise a row.

    Every time the current index changes, each widget is updated with data
    from the model via the property specified when its mapping was made.
    If the user edits the contents of a widget, the changes are read using
    the same property and written back to the model.
    By default, each widget's \l{Q_PROPERTY()}{user property} is used to
    transfer data between the model and the widget. Since Qt 4.3, an
    additional addMapping() function enables a named property to be used
    instead of the default user property.

    It is possible to set an item delegate to support custom widgets. By default,
    a QItemDelegate is used to synchronize the model with the widgets.

    Let us assume that we have an item model named \c{model} with the following contents:

    \table
    \row \li 1 \li Qt Norway       \li Oslo
    \row \li 2 \li Qt Australia    \li Brisbane
    \row \li 3 \li Qt USA          \li Palo Alto
    \row \li 4 \li Qt China        \li Beijing
    \row \li 5 \li Qt Germany      \li Berlin
    \endtable

    The following code will map the columns of the model to widgets called \c mySpinBox,
    \c myLineEdit and \c{myCountryChooser}:

    \snippet code/src_gui_itemviews_qdatawidgetmapper.cpp 0

    After the call to toFirst(), \c mySpinBox displays the value \c{1}, \c myLineEdit
    displays \c{Qt Norway} and \c myCountryChooser displays \c{Oslo}. The
    navigational functions toFirst(), toNext(), toPrevious(), toLast() and setCurrentIndex()
    can be used to navigate in the model and update the widgets with contents from
    the model.

    The setRootIndex() function enables a particular item in a model to be
    specified as the root index - children of this item will be mapped to
    the relevant widgets in the user interface.

    QDataWidgetMapper supports two submit policies, \c AutoSubmit and \c{ManualSubmit}.
    \c AutoSubmit will update the model as soon as the current widget loses focus,
    \c ManualSubmit will not update the model unless submit() is called. \c ManualSubmit
    is useful when displaying a dialog that lets the user cancel all modifications.
    Also, other views that display the model won't update until the user finishes
    all their modifications and submits.

    Note that QDataWidgetMapper keeps track of external modifications. If the contents
    of the model are updated in another module of the application, the widgets are
    updated as well.

    \sa QAbstractItemModel, QAbstractItemDelegate
 */

/*! \enum QDataWidgetMapper::SubmitPolicy

    This enum describes the possible submit policies a QDataWidgetMapper
    supports.

    \value AutoSubmit    Whenever a widget loses focus, the widget's current
                         value is set to the item model.
    \value ManualSubmit  The model is not updated until submit() is called.
 */

/*!
    \fn void QDataWidgetMapper::currentIndexChanged(int index)

    This signal is emitted after the current index has changed and
    all widgets were populated with new data. \a index is the new
    current index.

    \sa currentIndex(), setCurrentIndex()
 */

/*!
    Constructs a new QDataWidgetMapper with parent object \a parent.
    By default, the orientation is horizontal and the submit policy
    is \c{AutoSubmit}.

    \sa setOrientation(), setSubmitPolicy()
 */
QDataWidgetMapper::QDataWidgetMapper(QObject *parent)
    : QObject(*new QDataWidgetMapperPrivate, parent)
{
    // ### Qt6: QStyledItemDelegate
    setItemDelegate(new QItemDelegate(this));
}

/*!
    Destroys the object.
 */
QDataWidgetMapper::~QDataWidgetMapper()
{
}

/*!
     Sets the current model to \a model. If another model was set,
     all mappings to that old model are cleared.

     \sa model()
 */
void QDataWidgetMapper::setModel(QAbstractItemModel *model)
{
    Q_D(QDataWidgetMapper);

    if (d->model == model)
        return;

    if (d->model) {
        disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this,
                   SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
        disconnect(d->model, SIGNAL(destroyed()), this,
                   SLOT(_q_modelDestroyed()));
    }
    clearMapping();
    d->rootIndex = QModelIndex();
    d->currentTopLeft = QModelIndex();

    d->model = model;

    connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
            SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
    connect(model, SIGNAL(destroyed()), SLOT(_q_modelDestroyed()));
}

/*!
    Returns the current model.

    \sa setModel()
 */
QAbstractItemModel *QDataWidgetMapper::model() const
{
    Q_D(const QDataWidgetMapper);
    return d->model == QAbstractItemModelPrivate::staticEmptyModel()
            ? static_cast<QAbstractItemModel *>(nullptr)
            : d->model;
}

/*!
    Sets the item delegate to \a delegate. The delegate will be used to write
    data from the model into the widget and from the widget to the model,
    using QAbstractItemDelegate::setEditorData() and QAbstractItemDelegate::setModelData().

    The delegate also decides when to apply data and when to change the editor,
    using QAbstractItemDelegate::commitData() and QAbstractItemDelegate::closeEditor().

    \warning You should not share the same instance of a delegate between widget mappers
    or views. Doing so can cause incorrect or unintuitive editing behavior since each
    view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
    signal, and attempt to access, modify or close an editor that has already been closed.
 */
void QDataWidgetMapper::setItemDelegate(QAbstractItemDelegate *delegate)
{
    Q_D(QDataWidgetMapper);
    QAbstractItemDelegate *oldDelegate = d->delegate;
    if (oldDelegate) {
        disconnect(oldDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(_q_commitData(QWidget*)));
        disconnect(oldDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
                   this, SLOT(_q_closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
    }

    d->delegate = delegate;

    if (delegate) {
        connect(delegate, SIGNAL(commitData(QWidget*)), SLOT(_q_commitData(QWidget*)));
        connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
                SLOT(_q_closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
    }

    d->flipEventFilters(oldDelegate, delegate);
}

/*!
    Returns the current item delegate.
 */
QAbstractItemDelegate *QDataWidgetMapper::itemDelegate() const
{
    Q_D(const QDataWidgetMapper);
    return d->delegate;
}

/*!
    Sets the root item to \a index. This can be used to display
    a branch of a tree. Pass an invalid model index to display
    the top-most branch.

    \sa rootIndex()
 */
void QDataWidgetMapper::setRootIndex(const QModelIndex &index)
{
    Q_D(QDataWidgetMapper);
    d->rootIndex = index;
}

/*!
    Returns the current root index.

    \sa setRootIndex()
*/
QModelIndex QDataWidgetMapper::rootIndex() const
{
    Q_D(const QDataWidgetMapper);
    return QModelIndex(d->rootIndex);
}

/*!
    Adds a mapping between a \a widget and a \a section from the model.
    The \a section is a column in the model if the orientation is
    horizontal (the default), otherwise a row.

    For the following example, we assume a model \c myModel that
    has two columns: the first one contains the names of people in a
    group, and the second column contains their ages. The first column
    is mapped to the QLineEdit \c nameLineEdit, and the second is
    mapped to the QSpinBox \c{ageSpinBox}:

    \snippet code/src_gui_itemviews_qdatawidgetmapper.cpp 1

    \b{Notes:}
    \list
    \li If the \a widget is already mapped to a section, the
    old mapping will be replaced by the new one.
    \li Only one-to-one mappings between sections and widgets are allowed.
    It is not possible to map a single section to multiple widgets, or to
    map a single widget to multiple sections.
    \endlist

    \sa removeMapping(), mappedSection(), clearMapping()
 */
void QDataWidgetMapper::addMapping(QWidget *widget, int section)
{
    Q_D(QDataWidgetMapper);

    removeMapping(widget);
    d->widgetMap.push_back({widget, section, d->indexAt(section), QByteArray()});
    widget->installEventFilter(d->delegate);
}

/*!
  \since 4.3

  Essentially the same as addMapping(), but adds the possibility to specify
  the property to use specifying \a propertyName.

  \sa addMapping()
*/

void QDataWidgetMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName)
{
    Q_D(QDataWidgetMapper);

    removeMapping(widget);
    d->widgetMap.push_back({widget, section, d->indexAt(section), propertyName});
    widget->installEventFilter(d->delegate);
}

/*!
    Removes the mapping for the given \a widget.

    \sa addMapping(), clearMapping()
 */
void QDataWidgetMapper::removeMapping(QWidget *widget)
{
    Q_D(QDataWidgetMapper);

    int idx = d->findWidget(widget);
    if (idx == -1)
        return;

    d->widgetMap.erase(d->widgetMap.begin() + idx);
    widget->removeEventFilter(d->delegate);
}

/*!
    Returns the section the \a widget is mapped to or -1
    if the widget is not mapped.

    \sa addMapping(), removeMapping()
 */
int QDataWidgetMapper::mappedSection(QWidget *widget) const
{
    Q_D(const QDataWidgetMapper);

    int idx = d->findWidget(widget);
    if (idx == -1)
        return -1;

    return d->widgetMap[idx].section;
}

/*!
  \since 4.3
  Returns the name of the property that is used when mapping
  data to the given \a widget.

  \sa mappedSection(), addMapping(), removeMapping()
*/

QByteArray QDataWidgetMapper::mappedPropertyName(QWidget *widget) const
{
    Q_D(const QDataWidgetMapper);

    int idx = d->findWidget(widget);
    if (idx == -1)
        return QByteArray();
    const auto &m = d->widgetMap[idx];
    if (m.property.isEmpty())
        return m.widget->metaObject()->userProperty().name();
    else
        return m.property;
}

/*!
    Returns the widget that is mapped at \a section, or
    0 if no widget is mapped at that section.

    \sa addMapping(), removeMapping()
 */
QWidget *QDataWidgetMapper::mappedWidgetAt(int section) const
{
    Q_D(const QDataWidgetMapper);

    for (auto &e : d->widgetMap) {
        if (e.section == section)
            return e.widget;
    }

    return nullptr;
}

/*!
    Repopulates all widgets with the current data of the model.
    All unsubmitted changes will be lost.

    \sa submit(), setSubmitPolicy()
 */
void QDataWidgetMapper::revert()
{
    Q_D(QDataWidgetMapper);

    d->populate();
}

/*!
    Submits all changes from the mapped widgets to the model.

    For every mapped section, the item delegate reads the current
    value from the widget and sets it in the model. Finally, the
    model's \l {QAbstractItemModel::}{submit()} method is invoked.

    Returns \c true if all the values were submitted, otherwise false.

    Note: For database models, QSqlQueryModel::lastError() can be
    used to retrieve the last error.

    \sa revert(), setSubmitPolicy()
 */
bool QDataWidgetMapper::submit()
{
    Q_D(QDataWidgetMapper);

    for (auto &e : d->widgetMap) {
        if (!d->commit(e))
            return false;
    }

    return d->model->submit();
}

/*!
    Populates the widgets with data from the first row of the model
    if the orientation is horizontal (the default), otherwise
    with data from the first column.

    This is equivalent to calling \c setCurrentIndex(0).

    \sa toLast(), setCurrentIndex()
 */
void QDataWidgetMapper::toFirst()
{
    setCurrentIndex(0);
}

/*!
    Populates the widgets with data from the last row of the model
    if the orientation is horizontal (the default), otherwise
    with data from the last column.

    Calls setCurrentIndex() internally.

    \sa toFirst(), setCurrentIndex()
 */
void QDataWidgetMapper::toLast()
{
    Q_D(QDataWidgetMapper);
    setCurrentIndex(d->itemCount() - 1);
}


/*!
    Populates the widgets with data from the next row of the model
    if the orientation is horizontal (the default), otherwise
    with data from the next column.

    Calls setCurrentIndex() internally. Does nothing if there is
    no next row in the model.

    \sa toPrevious(), setCurrentIndex()
 */
void QDataWidgetMapper::toNext()
{
    Q_D(QDataWidgetMapper);
    setCurrentIndex(d->currentIdx() + 1);
}

/*!
    Populates the widgets with data from the previous row of the model
    if the orientation is horizontal (the default), otherwise
    with data from the previous column.

    Calls setCurrentIndex() internally. Does nothing if there is
    no previous row in the model.

    \sa toNext(), setCurrentIndex()
 */
void QDataWidgetMapper::toPrevious()
{
    Q_D(QDataWidgetMapper);
    setCurrentIndex(d->currentIdx() - 1);
}

/*!
    \property QDataWidgetMapper::currentIndex
    \brief the current row or column

    The widgets are populated with with data from the row at \a index
    if the orientation is horizontal (the default), otherwise with
    data from the column at \a index.

    \sa setCurrentModelIndex(), toFirst(), toNext(), toPrevious(), toLast()
*/
void QDataWidgetMapper::setCurrentIndex(int index)
{
    Q_D(QDataWidgetMapper);

    if (index < 0 || index >= d->itemCount())
        return;
    d->currentTopLeft = d->orientation == Qt::Horizontal
                            ? d->model->index(index, 0, d->rootIndex)
                            : d->model->index(0, index, d->rootIndex);
    d->populate();

    emit currentIndexChanged(index);
}

int QDataWidgetMapper::currentIndex() const
{
    Q_D(const QDataWidgetMapper);
    return d->currentIdx();
}

/*!
    Sets the current index to the row of the \a index if the
    orientation is horizontal (the default), otherwise to the
    column of the \a index.

    Calls setCurrentIndex() internally. This convenience slot can be
    connected to the signal \l
    {QItemSelectionModel::}{currentRowChanged()} or \l
    {QItemSelectionModel::}{currentColumnChanged()} of another view's
    \l {QItemSelectionModel}{selection model}.

    The following example illustrates how to update all widgets
    with new data whenever the selection of a QTableView named
    \c myTableView changes:

    \snippet code/src_gui_itemviews_qdatawidgetmapper.cpp 2

    \sa currentIndex()
*/
void QDataWidgetMapper::setCurrentModelIndex(const QModelIndex &index)
{
    Q_D(QDataWidgetMapper);

    if (!index.isValid()
        || index.model() != d->model
        || index.parent() != d->rootIndex)
        return;

    setCurrentIndex(d->orientation == Qt::Horizontal ? index.row() : index.column());
}

/*!
    Clears all mappings.

    \sa addMapping(), removeMapping()
 */
void QDataWidgetMapper::clearMapping()
{
    Q_D(QDataWidgetMapper);

    decltype(d->widgetMap) copy;
    d->widgetMap.swap(copy); // a C++98 move
    for (auto it = copy.crbegin(), end = copy.crend(); it != end; ++it) {
        if (it->widget)
            it->widget->removeEventFilter(d->delegate);
    }
}

/*!
    \property QDataWidgetMapper::orientation
    \brief the orientation of the model

    If the orientation is Qt::Horizontal (the default), a widget is
    mapped to a column of a data model. The widget will be populated
    with the model's data from its mapped column and the row that
    currentIndex() points at.

    Use Qt::Horizontal for tabular data that looks like this:

    \table
    \row \li 1 \li Qt Norway       \li Oslo
    \row \li 2 \li Qt Australia    \li Brisbane
    \row \li 3 \li Qt USA          \li Silicon Valley
    \row \li 4 \li Qt China        \li Beijing
    \row \li 5 \li Qt Germany      \li Berlin
    \endtable

    If the orientation is set to Qt::Vertical, a widget is mapped to
    a row. Calling setCurrentIndex() will change the current column.
    The widget will be populates with the model's data from its
    mapped row and the column that currentIndex() points at.

    Use Qt::Vertical for tabular data that looks like this:

    \table
    \row \li 1 \li 2 \li 3 \li 4 \li 5
    \row \li Qt Norway \li Qt Australia \li Qt USA \li Qt China \li Qt Germany
    \row \li Oslo \li Brisbane \li Silicon Valley \li Beijing \li Berlin
    \endtable

    Changing the orientation clears all existing mappings.
*/
void QDataWidgetMapper::setOrientation(Qt::Orientation orientation)
{
    Q_D(QDataWidgetMapper);

    if (d->orientation == orientation)
        return;

    clearMapping();
    d->orientation = orientation;
}

Qt::Orientation QDataWidgetMapper::orientation() const
{
    Q_D(const QDataWidgetMapper);
    return d->orientation;
}

/*!
    \property QDataWidgetMapper::submitPolicy
    \brief the current submit policy

    Changing the current submit policy will revert all widgets
    to the current data from the model.
*/
void QDataWidgetMapper::setSubmitPolicy(SubmitPolicy policy)
{
    Q_D(QDataWidgetMapper);
    if (policy == d->submitPolicy)
        return;

    revert();
    d->submitPolicy = policy;
}

QDataWidgetMapper::SubmitPolicy QDataWidgetMapper::submitPolicy() const
{
    Q_D(const QDataWidgetMapper);
    return d->submitPolicy;
}

QT_END_NAMESPACE

#include "moc_qdatawidgetmapper.cpp"
