diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2009-08-28 09:41:00 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2009-08-28 09:41:00 (GMT) |
commit | 55865ff0bffb9a9218f6ce2d7516d8736437cfa3 (patch) | |
tree | f1bfcb92a69d976e6b77f16198007bb934384c39 | |
parent | c065a7e1d26dc434cfe33177332473797db74152 (diff) | |
parent | e88a947cd8ac7bd78922a5468cd8b631b8ccf479 (diff) | |
download | Qt-55865ff0bffb9a9218f6ce2d7516d8736437cfa3.zip Qt-55865ff0bffb9a9218f6ce2d7516d8736437cfa3.tar.gz Qt-55865ff0bffb9a9218f6ce2d7516d8736437cfa3.tar.bz2 |
Merge branch '4.6' of git:qt/qt into 4.6
-rw-r--r-- | src/corelib/animation/qabstractanimation.cpp | 31 | ||||
-rw-r--r-- | src/corelib/kernel/qabstractitemmodel.cpp | 48 | ||||
-rw-r--r-- | src/corelib/kernel/qabstractitemmodel.h | 3 | ||||
-rw-r--r-- | src/corelib/statemachine/qabstracttransition_p.h | 2 | ||||
-rw-r--r-- | src/corelib/statemachine/qsignalevent.h | 2 | ||||
-rw-r--r-- | src/corelib/statemachine/qsignaltransition.cpp | 17 | ||||
-rw-r--r-- | src/corelib/statemachine/qsignaltransition_p.h | 3 | ||||
-rw-r--r-- | src/corelib/statemachine/qstatemachine.cpp | 7 | ||||
-rw-r--r-- | src/gui/itemviews/qsortfilterproxymodel.cpp | 11 | ||||
-rw-r--r-- | src/gui/itemviews/qsortfilterproxymodel.h | 1 | ||||
-rw-r--r-- | tests/auto/qabstractitemmodel/dynamictreemodel.cpp | 118 | ||||
-rw-r--r-- | tests/auto/qabstractitemmodel/dynamictreemodel.h | 39 | ||||
-rw-r--r-- | tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp | 106 | ||||
-rw-r--r-- | tests/auto/qstatemachine/tst_qstatemachine.cpp | 42 |
14 files changed, 380 insertions, 50 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index dfd6779..49bd8e9 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -259,28 +259,33 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) } state = newState; - QPointer<QAbstractAnimation> guard(q); + QWeakPointer<QAbstractAnimation> guard(q); - guard->updateState(oldState, newState); + q->updateState(oldState, newState); + if (!guard) + return; //this is to be safe if updateState changes the state if (state == oldState) return; // Notify state change - if (guard) - emit guard->stateChanged(oldState, newState); + emit q->stateChanged(oldState, newState); + if (!guard) + return; - switch (state) - { + switch (state) { case QAbstractAnimation::Paused: case QAbstractAnimation::Running: //this ensures that the value is updated now that the animation is running - if(oldState == QAbstractAnimation::Stopped && guard) - guard->setCurrentTime(currentTime); + if(oldState == QAbstractAnimation::Stopped) { + q->setCurrentTime(currentTime); + if (!guard) + return; + } // Register timer if our parent is not running. - if (state == QAbstractAnimation::Running && guard) { + if (state == QAbstractAnimation::Running) { if (!group || group->state() == QAbstractAnimation::Stopped) { QUnifiedTimer::instance()->registerAnimation(q); } @@ -292,7 +297,10 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) case QAbstractAnimation::Stopped: // Leave running state. int dura = q->duration(); - if (deleteWhenStopped && guard) + if (!guard) + return; + + if (deleteWhenStopped) q->deleteLater(); QUnifiedTimer::instance()->unregisterAnimation(q); @@ -300,8 +308,7 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) if (dura == -1 || loopCount < 0 || (oldDirection == QAbstractAnimation::Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * loopCount)) || (oldDirection == QAbstractAnimation::Backward && oldCurrentTime == 0)) { - if (guard) - emit q->finished(); + emit q->finished(); } break; } diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 1c9104a..5e8848b 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -1339,7 +1339,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent, \endlist - \sa layoutAboutToBeChanged(), dataChanged(), headerDataChanged(), reset(), + \sa layoutAboutToBeChanged(), dataChanged(), headerDataChanged(), modelReset(), changePersistentIndex() */ @@ -2769,7 +2769,24 @@ void QAbstractItemModel::endMoveColumns() /*! Resets the model to its original state in any attached views. - The view to which the model is attached to will be reset as well. + \note Use beginResetModel() and endResetModel() instead whenever possible. + Use this method only if there is no way to call beginResetModel() before invalidating the model. + Otherwise it could lead to unexcpected behaviour, especially when used with proxy models. +*/ +void QAbstractItemModel::reset() +{ + Q_D(QAbstractItemModel); + emit modelAboutToBeReset(); + d->invalidatePersistentIndexes(); + emit modelReset(); +} + +/*! + Begins a model reset operation. + + A reset operation resets the model to its current state in any attached views. + + \note Any views attached to this model will be reset as well. When a model is reset it means that any previous data reported from the model is now invalid and has to be queried for again. This also means that @@ -2779,12 +2796,29 @@ void QAbstractItemModel::endMoveColumns() call this function rather than emit dataChanged() to inform other components when the underlying data source, or its structure, has changed. - \sa modelAboutToBeReset(), modelReset() + You must call this function before resetting any internal data structures in your model + or proxy model. + + \sa modelAboutToBeReset(), modelReset(), endResetModel() + \since 4.6 */ -void QAbstractItemModel::reset() +void QAbstractItemModel::beginResetModel() { - Q_D(QAbstractItemModel); emit modelAboutToBeReset(); +} + +/*! + Completes a model reset operation. + + You must call this function after resetting any internal data structure in your model + or proxy model. + + \sa beginResetModel() + \since 4.6 +*/ +void QAbstractItemModel::endResetModel() +{ + Q_D(QAbstractItemModel); d->invalidatePersistentIndexes(); emit modelReset(); } @@ -3256,7 +3290,7 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti This signal is emitted when reset() is called, before the model's internal state (e.g. persistent model indexes) has been invalidated. - \sa reset(), modelReset() + \sa beginResetModel(), modelReset() */ /*! @@ -3266,7 +3300,7 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti This signal is emitted when reset() is called, after the model's internal state (e.g. persistent model indexes) has been invalidated. - \sa reset(), modelAboutToBeReset() + \sa endResetModel(), modelAboutToBeReset() */ /*! diff --git a/src/corelib/kernel/qabstractitemmodel.h b/src/corelib/kernel/qabstractitemmodel.h index b47e4cb..1ca6cbe 100644 --- a/src/corelib/kernel/qabstractitemmodel.h +++ b/src/corelib/kernel/qabstractitemmodel.h @@ -293,6 +293,9 @@ protected: void reset(); + void beginResetModel(); + void endResetModel(); + void changePersistentIndex(const QModelIndex &from, const QModelIndex &to); void changePersistentIndexList(const QModelIndexList &from, const QModelIndexList &to); QModelIndexList persistentIndexList() const; diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h index 328be16..33e4474 100644 --- a/src/corelib/statemachine/qabstracttransition_p.h +++ b/src/corelib/statemachine/qabstracttransition_p.h @@ -75,7 +75,7 @@ public: static QAbstractTransitionPrivate *get(QAbstractTransition *q); bool callEventTest(QEvent *e); - void callOnTransition(QEvent *e); + virtual void callOnTransition(QEvent *e); QState *sourceState() const; QStateMachine *machine() const; void emitTriggered(); diff --git a/src/corelib/statemachine/qsignalevent.h b/src/corelib/statemachine/qsignalevent.h index 7e5d888..de166f4 100644 --- a/src/corelib/statemachine/qsignalevent.h +++ b/src/corelib/statemachine/qsignalevent.h @@ -70,6 +70,8 @@ private: QObject *m_sender; int m_signalIndex; QList<QVariant> m_arguments; + + friend class QSignalTransitionPrivate; }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp index e34448f..fb28c08 100644 --- a/src/corelib/statemachine/qsignaltransition.cpp +++ b/src/corelib/statemachine/qsignaltransition.cpp @@ -245,6 +245,23 @@ bool QSignalTransition::event(QEvent *e) return QAbstractTransition::event(e); } +void QSignalTransitionPrivate::callOnTransition(QEvent *e) +{ + Q_Q(QSignalTransition); + + QSignalEvent *se = static_cast<QSignalEvent *>(e); + int savedSignalIndex; + if (e->type() == QEvent::Signal) { + savedSignalIndex = se->m_signalIndex; + se->m_signalIndex = originalSignalIndex; + } + + q->onTransition(e); + + if (e->type() == QEvent::Signal) + se->m_signalIndex = savedSignalIndex; +} + QT_END_NAMESPACE #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qsignaltransition_p.h b/src/corelib/statemachine/qsignaltransition_p.h index 21082ab..69bbcc9 100644 --- a/src/corelib/statemachine/qsignaltransition_p.h +++ b/src/corelib/statemachine/qsignaltransition_p.h @@ -69,9 +69,12 @@ public: void unregister(); void maybeRegister(); + virtual void callOnTransition(QEvent *e); + QObject *sender; QByteArray signal; int signalIndex; + int originalSignalIndex; }; QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index d6946de..e5bca2c 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -1408,6 +1408,7 @@ void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transitio signal.remove(0, 1); const QMetaObject *meta = sender->metaObject(); int signalIndex = meta->indexOfSignal(signal); + int originalSignalIndex = signalIndex; if (signalIndex == -1) { signalIndex = meta->indexOfSignal(QMetaObject::normalizedSignature(signal)); if (signalIndex == -1) { @@ -1416,6 +1417,11 @@ void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transitio return; } } + // The signal index we actually want to connect to is the one + // that is going to be sent, i.e. the non-cloned original index. + while (meta->method(signalIndex).attributes() & QMetaMethod::Cloned) + --signalIndex; + QVector<int> &connectedSignalIndexes = connections[sender]; if (connectedSignalIndexes.size() <= signalIndex) connectedSignalIndexes.resize(signalIndex+1); @@ -1435,6 +1441,7 @@ void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transitio } ++connectedSignalIndexes[signalIndex]; QSignalTransitionPrivate::get(transition)->signalIndex = signalIndex; + QSignalTransitionPrivate::get(transition)->originalSignalIndex = originalSignalIndex; #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": added signal transition from" << transition->sourceState() << ": ( sender =" << sender << ", signal =" << signal diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index d173efe..18fbf7b 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -174,6 +174,7 @@ public: const QModelIndex &source_bottom_right); void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end); + void _q_sourceAboutToBeReset(); void _q_sourceReset(); void _q_sourceLayoutAboutToBeChanged(); @@ -1148,11 +1149,17 @@ void QSortFilterProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation or emit q->headerDataChanged(orientation, proxy_start, proxy_end); } +void QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset() +{ + Q_Q(QSortFilterProxyModel); + q->beginResetModel(); +} + void QSortFilterProxyModelPrivate::_q_sourceReset() { Q_Q(QSortFilterProxyModel); // All internal structures are deleted in clear() - q->reset(); + q->endResetModel(); update_source_sort_column(); if (dynamic_sortfilter) sort(); @@ -1499,6 +1506,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_sourceLayoutChanged())); + disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); QAbstractProxyModel::setSourceModel(sourceModel); @@ -1539,6 +1547,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_sourceLayoutChanged())); + connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); d->clear_mapping(); diff --git a/src/gui/itemviews/qsortfilterproxymodel.h b/src/gui/itemviews/qsortfilterproxymodel.h index 12baa19..0314aec 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.h +++ b/src/gui/itemviews/qsortfilterproxymodel.h @@ -177,6 +177,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right)) Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sourceReset()) Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged()) Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged()) diff --git a/tests/auto/qabstractitemmodel/dynamictreemodel.cpp b/tests/auto/qabstractitemmodel/dynamictreemodel.cpp index 6c3e0cb..374b7db 100644 --- a/tests/auto/qabstractitemmodel/dynamictreemodel.cpp +++ b/tests/auto/qabstractitemmodel/dynamictreemodel.cpp @@ -204,42 +204,106 @@ ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent) { } +bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow); +} void ModelMoveCommand::doCommand() { - QModelIndex srcParent = findIndex(m_rowNumbers); - QModelIndex destParent = findIndex(m_destRowNumbers); - - if (!m_model->beginMoveRows(srcParent, m_startRow, m_endRow, destParent, m_destRow)) - { - return; - } - - for (int column = 0; column < m_numCols; ++column) - { - QList<qint64> l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 ); + QModelIndex srcParent = findIndex(m_rowNumbers); + QModelIndex destParent = findIndex(m_destRowNumbers); - for (int i = m_startRow; i <= m_endRow ; i++) + if (!emitPreSignal(srcParent, m_startRow, m_endRow, destParent, m_destRow)) { - m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow); - } - int d; - if (m_destRow < m_startRow) - d = m_destRow; - else - { - if (srcParent == destParent) - d = m_destRow - (m_endRow - m_startRow + 1); - else - d = m_destRow - (m_endRow - m_startRow) + 1; + return; } - foreach(const qint64 id, l) + for (int column = 0; column < m_numCols; ++column) { - m_model->m_childItems[destParent.internalId()][column].insert(d++, id); + QList<qint64> l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 ); + + for (int i = m_startRow; i <= m_endRow ; i++) + { + m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow); + } + int d; + if (m_destRow < m_startRow) + d = m_destRow; + else + { + if (srcParent == destParent) + d = m_destRow - (m_endRow - m_startRow + 1); + else + d = m_destRow - (m_endRow - m_startRow) + 1; + } + + foreach(const qint64 id, l) + { + m_model->m_childItems[destParent.internalId()][column].insert(d++, id); + } } - } - m_model->endMoveRows(); + emitPostSignal(); +} + +void ModelMoveCommand::emitPostSignal() +{ + m_model->endMoveRows(); +} + +ModelResetCommand::ModelResetCommand(DynamicTreeModel* model, QObject* parent) + : ModelMoveCommand(model, parent) +{ + +} + +ModelResetCommand::~ModelResetCommand() +{ + +} + +bool ModelResetCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + Q_UNUSED(srcParent); + Q_UNUSED(srcStart); + Q_UNUSED(srcEnd); + Q_UNUSED(destParent); + Q_UNUSED(destRow); + + return true; +} + +void ModelResetCommand::emitPostSignal() +{ + m_model->reset(); +} + +ModelResetCommandFixed::ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent) + : ModelMoveCommand(model, parent) +{ + +} + +ModelResetCommandFixed::~ModelResetCommandFixed() +{ + +} + +bool ModelResetCommandFixed::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + Q_UNUSED(srcParent); + Q_UNUSED(srcStart); + Q_UNUSED(srcEnd); + Q_UNUSED(destParent); + Q_UNUSED(destRow); + + m_model->beginResetModel(); + return true; +} + +void ModelResetCommandFixed::emitPostSignal() +{ + m_model->endResetModel(); } diff --git a/tests/auto/qabstractitemmodel/dynamictreemodel.h b/tests/auto/qabstractitemmodel/dynamictreemodel.h index 88e293c..c19ed9d 100644 --- a/tests/auto/qabstractitemmodel/dynamictreemodel.h +++ b/tests/auto/qabstractitemmodel/dynamictreemodel.h @@ -70,6 +70,8 @@ private: friend class ModelInsertCommand; friend class ModelMoveCommand; + friend class ModelResetCommand; + friend class ModelResetCommandFixed; }; @@ -118,6 +120,7 @@ public: virtual void doCommand(); }; + class ModelMoveCommand : public ModelChangeCommand { Q_OBJECT @@ -126,8 +129,12 @@ public: virtual ~ModelMoveCommand() {} + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); + virtual void doCommand(); + virtual void emitPostSignal(); + void setDestAncestors( QList<int> rows ) { m_destRowNumbers = rows; } void setDestRow(int row) { m_destRow = row; } @@ -137,5 +144,37 @@ protected: int m_destRow; }; +/** + A command which does a move and emits a reset signal. +*/ +class ModelResetCommand : public ModelMoveCommand +{ + Q_OBJECT +public: + ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0); + + virtual ~ModelResetCommand(); + + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); + virtual void emitPostSignal(); + +}; + +/** + A command which does a move and emits a beginResetModel and endResetModel signals. +*/ +class ModelResetCommandFixed : public ModelMoveCommand +{ + Q_OBJECT +public: + ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent = 0); + + virtual ~ModelResetCommandFixed(); + + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); + virtual void emitPostSignal(); + +}; + #endif diff --git a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp index 9c83474..61eeae7 100644 --- a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -43,6 +43,8 @@ #include <QtTest/QtTest> #include <QtCore/QtCore> +#include <QSortFilterProxyModel> + //TESTED_CLASS=QAbstractListModel QAbstractTableModel //TESTED_FILES= @@ -110,6 +112,8 @@ private slots: void testMoveWithinOwnRange_data(); void testMoveWithinOwnRange(); + void testReset(); + private: DynamicTreeModel *m_model; @@ -814,7 +818,7 @@ void tst_QAbstractItemModel::complexChangesWithPersistent() //remove a bunch of columns model.removeColumns(2, 4); - + QVERIFY(a == model.index(1, 1, QModelIndex())); QVERIFY(b == model.index(9, 3, QModelIndex())); QVERIFY(c == model.index(5, 2, QModelIndex())); @@ -825,7 +829,7 @@ void tst_QAbstractItemModel::complexChangesWithPersistent() QVERIFY(!e[i].isValid()); for (int i=6; i <10 ; i++) QVERIFY(e[i] == model.index(2, i-4 , QModelIndex())); - + //move some indexes around model.setPersistent(model.index(1, 1 , QModelIndex()), model.index(9, 3 , QModelIndex())); model.setPersistent(model.index(9, 3 , QModelIndex()), model.index(8, 4 , QModelIndex())); @@ -1652,6 +1656,104 @@ void tst_QAbstractItemModel::testMoveWithinOwnRange() } +class ListenerObject : public QObject +{ + Q_OBJECT +public: + ListenerObject(QAbstractProxyModel *parent); + +protected: + void fillIndexStores(const QModelIndex &parent); + +public slots: + void slotAboutToBeReset(); + void slotReset(); + +private: + QAbstractProxyModel *m_model; + QList<QPersistentModelIndex> m_persistentIndexes; + QModelIndexList m_nonPersistentIndexes; +}; + + +ListenerObject::ListenerObject(QAbstractProxyModel *parent) + : QObject(parent), m_model(parent) +{ + connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(slotAboutToBeReset())); + connect(m_model, SIGNAL(modelReset()), SLOT(slotReset())); + + fillIndexStores(QModelIndex()); +} + +void ListenerObject::fillIndexStores(const QModelIndex &parent) +{ + const int column = 0; + int row = 0; + QModelIndex idx = m_model->index(row, column, parent); + while (idx.isValid()) + { + m_persistentIndexes << QPersistentModelIndex(idx); + m_nonPersistentIndexes << idx; + if (m_model->hasChildren(idx)) + { + fillIndexStores(idx); + } + ++row; + idx = m_model->index(row, column, parent); + } +} + +void ListenerObject::slotAboutToBeReset() +{ + // Nothing has been changed yet. All indexes should be the same. + for (int i = 0; i < m_persistentIndexes.size(); ++i) + { + QModelIndex idx = m_persistentIndexes.at(i); + QVERIFY(idx == m_nonPersistentIndexes.at(i)); + QVERIFY(m_model->mapToSource(idx).isValid()); + } +} + +void ListenerObject::slotReset() +{ + foreach(const QModelIndex &idx, m_persistentIndexes) + { + QVERIFY(!idx.isValid()); + } +} + + +void tst_QAbstractItemModel::testReset() +{ + QSignalSpy beforeResetSpy(m_model, SIGNAL(modelAboutToBeReset())); + QSignalSpy afterResetSpy(m_model, SIGNAL(modelReset())); + + + QSortFilterProxyModel *nullProxy = new QSortFilterProxyModel(this); + nullProxy->setSourceModel(m_model); + + // Makes sure the model and proxy are in a consistent state. before and after reset. + new ListenerObject(nullProxy); + + ModelResetCommandFixed *resetCommand = new ModelResetCommandFixed(m_model, this); + + resetCommand->setNumCols(4); + resetCommand->setStartRow(0); + resetCommand->setEndRow(0); + resetCommand->setDestRow(0); + resetCommand->setDestAncestors(QList<int>() << 5); + resetCommand->doCommand(); + + // Verify that the correct signals were emitted + QVERIFY(beforeResetSpy.size() == 1); + QVERIFY(afterResetSpy.size() == 1); + + // Verify that the move actually happened. + QVERIFY(m_model->rowCount() == 9); + QModelIndex destIndex = m_model->index(4, 0); + QVERIFY(m_model->rowCount(destIndex) == 11); + +} QTEST_MAIN(tst_QAbstractItemModel) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 20e69ce..643daa2 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -93,10 +93,13 @@ Q_OBJECT { emit signalWithIntArg(arg); } void emitSignalWithStringArg(const QString &arg) { emit signalWithStringArg(arg); } + void emitSignalWithDefaultArg() + { emit signalWithDefaultArg(); } Q_SIGNALS: void signalWithNoArg(); void signalWithIntArg(int); void signalWithStringArg(const QString &); + void signalWithDefaultArg(int i = 42); }; class tst_QStateMachine : public QObject @@ -193,6 +196,8 @@ private slots: void nestedStateMachines(); void goToState(); + + void task260403_clonedSignals(); }; tst_QStateMachine::tst_QStateMachine() @@ -3937,5 +3942,42 @@ void tst_QStateMachine::goToState() QVERIFY(machine.configuration().contains(s2_1)); } +class CloneSignalTransition : public QSignalTransition +{ +public: + CloneSignalTransition(QObject *sender, const char *signal, QAbstractState *target) + : QSignalTransition(sender, signal) + { + setTargetState(target); + } + + void onTransition(QEvent *e) + { + QSignalTransition::onTransition(e); + QSignalEvent *se = static_cast<QSignalEvent*>(e); + eventSignalIndex = se->signalIndex(); + } + + int eventSignalIndex; +}; + +void tst_QStateMachine::task260403_clonedSignals() +{ + SignalEmitter emitter; + QStateMachine machine; + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); + CloneSignalTransition *t1 = new CloneSignalTransition(&emitter, SIGNAL(signalWithDefaultArg()), s2); + s1->addTransition(t1); + + machine.setInitialState(s1); + machine.start(); + QTest::qWait(1); + + emitter.emitSignalWithDefaultArg(); + QTest::qWait(1); + QCOMPARE(t1->eventSignalIndex, emitter.metaObject()->indexOfSignal("signalWithDefaultArg()")); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" |