Introduce Group::aboutToMove() and moved() signals.

Emit them instead of remove/add when groups are moved within
a database.
This commit is contained in:
Felix Geyer 2012-04-23 16:57:08 +02:00
parent 6340ed8993
commit bddc29101c
10 changed files with 239 additions and 37 deletions

View File

@ -95,6 +95,8 @@ Q_SIGNALS:
void groupAdded();
void groupAboutToRemove(Group* group);
void groupRemoved();
void groupAboutToMove(Group* group, Group* toGroup, int index);
void groupMoved();
void modified();
private:

View File

@ -260,36 +260,48 @@ void Group::setParent(Group* parent, int index)
// setting a new parent for root groups is not allowed
Q_ASSERT(!m_db || (m_db->rootGroup() != this));
bool moveWithinDatabase = (m_db && m_db == parent->m_db);
if (index == -1) {
index = parent->children().size();
}
if (m_parent == parent && index == parent->children().indexOf(this)) {
if (m_parent == parent && parent->children().indexOf(this) == index) {
return;
}
if (!moveWithinDatabase) {
cleanupParent();
m_parent = parent;
if (m_db != parent->m_db) {
if (parent->m_db) {
recCreateDelObjects();
recSetDatabase(parent->m_db);
}
QObject::setParent(parent);
Q_EMIT aboutToAdd(this, index);
parent->m_children.insert(index, this);
}
else {
Q_EMIT aboutToMove(this, parent, index);
m_parent->m_children.removeAll(this);
m_parent = parent;
QObject::setParent(parent);
parent->m_children.insert(index, this);
}
if (m_updateTimeinfo) {
m_timeInfo.setLocationChanged(QDateTime::currentDateTimeUtc());
}
Q_EMIT modified();
if (!moveWithinDatabase) {
Q_EMIT added();
}
else {
Q_EMIT moved();
}
}
void Group::setParent(Database* db)
{
@ -389,6 +401,8 @@ void Group::recSetDatabase(Database* db)
disconnect(SIGNAL(removed()), m_db);
disconnect(SIGNAL(aboutToAdd(Group*,int)), m_db);
disconnect(SIGNAL(added()), m_db);
disconnect(SIGNAL(aboutToMove(Group*,Group*,int)), m_db);
disconnect(SIGNAL(moved()), m_db);
disconnect(SIGNAL(modified()), m_db);
}
@ -404,6 +418,8 @@ void Group::recSetDatabase(Database* db)
connect(this, SIGNAL(removed()), db, SIGNAL(groupRemoved()));
connect(this, SIGNAL(aboutToAdd(Group*,int)), db, SIGNAL(groupAboutToAdd(Group*,int)));
connect(this, SIGNAL(added()), db, SIGNAL(groupAdded()));
connect(this, SIGNAL(aboutToMove(Group*,Group*,int)), db, SIGNAL(groupAboutToMove(Group*,Group*,int)));
connect(this, SIGNAL(moved()), db, SIGNAL(groupMoved()));
connect(this, SIGNAL(modified()), db, SIGNAL(modified()));
m_db = db;

View File

@ -85,6 +85,11 @@ Q_SIGNALS:
void added();
void aboutToRemove(Group* group);
void removed();
/**
* Group moved within the database.
*/
void aboutToMove(Group* group, Group* toGroup, int index);
void moved();
void entryAboutToAdd(Entry* entry);
void entryAdded();

View File

@ -29,6 +29,8 @@ GroupModel::GroupModel(Database* db, QObject* parent)
connect(db, SIGNAL(groupAdded()), SLOT(groupAdded()));
connect(db, SIGNAL(groupAboutToRemove(Group*)), SLOT(groupAboutToRemove(Group*)));
connect(db, SIGNAL(groupRemoved()), SLOT(groupRemoved()));
connect(db, SIGNAL(groupAboutToMove(Group*,Group*,int)), SLOT(groupAboutToMove(Group*,Group*,int)));
connect(db, SIGNAL(groupMoved()), SLOT(groupMoved()));
}
int GroupModel::rowCount(const QModelIndex& parent) const
@ -180,3 +182,24 @@ void GroupModel::groupAdded()
{
endInsertRows();
}
void GroupModel::groupAboutToMove(Group* group, Group* toGroup, int pos)
{
Q_ASSERT(group->parentGroup());
QModelIndex oldParentIndex = parent(group);
QModelIndex newParentIndex = index(toGroup);
int oldPos = group->parentGroup()->children().indexOf(group);
if (group->parentGroup() == toGroup && pos > oldPos) {
// beginMoveRows() has a bit different semantics than Group::setParent() and
// QList::move() when the new position is greater than the old
pos++;
}
beginMoveRows(oldParentIndex, oldPos, oldPos, newParentIndex, pos);
}
void GroupModel::groupMoved()
{
endMoveRows();
}

View File

@ -48,6 +48,8 @@ private Q_SLOTS:
void groupRemoved();
void groupAboutToAdd(Group* group, int index);
void groupAdded();
void groupAboutToMove(Group* group, Group* toGroup, int pos);
void groupMoved();
private:
Group* m_root;

View File

@ -99,26 +99,82 @@ void TestGroup::testParenting()
void TestGroup::testSignals()
{
Database* db = new Database();
Database* db2 = new Database();
QPointer<Group> root = db->rootGroup();
Group* g1 = new Group();
Group* g2 = new Group();
g1->setParent(root);
g2->setParent(root);
QSignalSpy spyAboutToAdd(db, SIGNAL(groupAboutToAdd(Group*,int)));
QSignalSpy spyAdded(db, SIGNAL(groupAdded()));
QSignalSpy spyAboutToRemove(db, SIGNAL(groupAboutToRemove(Group*)));
QSignalSpy spyRemoved(db, SIGNAL(groupRemoved()));
QSignalSpy spyAboutToMove(db, SIGNAL(groupAboutToMove(Group*,Group*,int)));
QSignalSpy spyMoved(db, SIGNAL(groupMoved()));
g2->setParent(root, 0);
QSignalSpy spyAboutToAdd2(db2, SIGNAL(groupAboutToAdd(Group*,int)));
QSignalSpy spyAdded2(db2, SIGNAL(groupAdded()));
QSignalSpy spyAboutToRemove2(db2, SIGNAL(groupAboutToRemove(Group*)));
QSignalSpy spyRemoved2(db2, SIGNAL(groupRemoved()));
QSignalSpy spyAboutToMove2(db2, SIGNAL(groupAboutToMove(Group*,Group*,int)));
QSignalSpy spyMoved2(db2, SIGNAL(groupMoved()));
Group* g1 = new Group();
Group* g2 = new Group();
g1->setParent(root);
QCOMPARE(spyAboutToAdd.count(), 1);
QCOMPARE(spyAdded.count(), 1);
QCOMPARE(spyAboutToRemove.count(), 0);
QCOMPARE(spyRemoved.count(), 0);
QCOMPARE(spyAboutToMove.count(), 0);
QCOMPARE(spyMoved.count(), 0);
g2->setParent(root);
QCOMPARE(spyAboutToAdd.count(), 2);
QCOMPARE(spyAdded.count(), 2);
QCOMPARE(spyAboutToRemove.count(), 0);
QCOMPARE(spyRemoved.count(), 0);
QCOMPARE(spyAboutToMove.count(), 0);
QCOMPARE(spyMoved.count(), 0);
g2->setParent(root, 0);
QCOMPARE(spyAboutToAdd.count(), 2);
QCOMPARE(spyAdded.count(), 2);
QCOMPARE(spyAboutToRemove.count(), 0);
QCOMPARE(spyRemoved.count(), 0);
QCOMPARE(spyAboutToMove.count(), 1);
QCOMPARE(spyMoved.count(), 1);
g1->setParent(g2);
QCOMPARE(spyAboutToAdd.count(), 2);
QCOMPARE(spyAdded.count(), 2);
QCOMPARE(spyAboutToRemove.count(), 0);
QCOMPARE(spyRemoved.count(), 0);
QCOMPARE(spyAboutToMove.count(), 2);
QCOMPARE(spyMoved.count(), 2);
delete g1;
QCOMPARE(spyAboutToAdd.count(), 2);
QCOMPARE(spyAdded.count(), 2);
QCOMPARE(spyAboutToRemove.count(), 1);
QCOMPARE(spyRemoved.count(), 1);
QCOMPARE(spyAboutToMove.count(), 2);
QCOMPARE(spyMoved.count(), 2);
g2->setParent(db2->rootGroup());
QCOMPARE(spyAboutToAdd.count(), 2);
QCOMPARE(spyAdded.count(), 2);
QCOMPARE(spyAboutToRemove.count(), 2);
QCOMPARE(spyRemoved.count(), 2);
QCOMPARE(spyAboutToMove.count(), 2);
QCOMPARE(spyMoved.count(), 2);
QCOMPARE(spyAboutToAdd2.count(), 1);
QCOMPARE(spyAdded2.count(), 1);
QCOMPARE(spyAboutToRemove2.count(), 0);
QCOMPARE(spyRemoved2.count(), 0);
QCOMPARE(spyAboutToMove2.count(), 0);
QCOMPARE(spyMoved2.count(), 0);
delete db;
delete db2;
QVERIFY(root.isNull());
}

View File

@ -61,11 +61,6 @@ void TestGroupModel::test()
group121->setName("group121");
group121->setParent(group12);
Group* group2 = new Group();
group1->setObjectName("group2");
group2->setName("group2");
group2->setParent(groupRoot);
GroupModel* model = new GroupModel(db, this);
ModelTest* modelTest = new ModelTest(model, this);
@ -73,33 +68,78 @@ void TestGroupModel::test()
QModelIndex indexRoot = model->index(0, 0);
QModelIndex index1 = model->index(0, 0, indexRoot);
QModelIndex index11 = model->index(0, 0, index1);
QModelIndex index12 = model->index(1, 0, index1);
QPersistentModelIndex index12 = model->index(1, 0, index1);
QModelIndex index121 = model->index(0, 0, index12);
QModelIndex index2 = model->index(1, 0, indexRoot);
QCOMPARE(model->data(indexRoot).toString(), QString("groupRoot"));
QCOMPARE(model->data(index1).toString(), QString("group1"));
QCOMPARE(model->data(index11).toString(), QString("group11"));
QCOMPARE(model->data(index12).toString(), QString("group12"));
QCOMPARE(model->data(index121).toString(), QString("group121"));
QCOMPARE(model->data(index2).toString(), QString("group2"));
QSignalSpy spy1(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)));
QSignalSpy spy1(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
group11->setName("test");
group121->setIcon(4);
QCOMPARE(spy1.count(), 2);
QCOMPARE(model->data(index11).toString(), QString("test"));
QSignalSpy spyAboutToAdd(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex&,int,int)));
QSignalSpy spyAdded(model, SIGNAL(rowsInserted(const QModelIndex&,int,int)));
QSignalSpy spyAboutToRemove(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&,int,int)));
QSignalSpy spyRemoved(model, SIGNAL(rowsRemoved(const QModelIndex&,int,int)));
QSignalSpy spyAboutToAdd(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
QSignalSpy spyAdded(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
QSignalSpy spyAboutToRemove(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
QSignalSpy spyRemoved(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
QSignalSpy spyAboutToMove(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
QSignalSpy spyMoved(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
Group* group2 = new Group();
group1->setObjectName("group2");
group2->setName("group2");
group2->setParent(groupRoot);
QModelIndex index2 = model->index(1, 0, indexRoot);
QCOMPARE(spyAboutToAdd.count(), 1);
QCOMPARE(spyAdded.count(), 1);
QCOMPARE(spyAboutToRemove.count(), 0);
QCOMPARE(spyRemoved.count(), 0);
QCOMPARE(spyAboutToMove.count(), 0);
QCOMPARE(spyMoved.count(), 0);
QCOMPARE(model->data(index2).toString(), QString("group2"));
group12->setParent(group1, 0);
QCOMPARE(spyAboutToAdd.count(), 1);
QCOMPARE(spyAdded.count(), 1);
QCOMPARE(spyAboutToRemove.count(), 0);
QCOMPARE(spyRemoved.count(), 0);
QCOMPARE(spyAboutToMove.count(), 1);
QCOMPARE(spyMoved.count(), 1);
QCOMPARE(model->data(index12).toString(), QString("group12"));
group12->setParent(group1, 1);
QCOMPARE(spyAboutToAdd.count(), 1);
QCOMPARE(spyAdded.count(), 1);
QCOMPARE(spyAboutToRemove.count(), 0);
QCOMPARE(spyRemoved.count(), 0);
QCOMPARE(spyAboutToMove.count(), 2);
QCOMPARE(spyMoved.count(), 2);
QCOMPARE(model->data(index12).toString(), QString("group12"));
group12->setParent(group2);
QCOMPARE(spyAboutToAdd.count(), 1);
QCOMPARE(spyAdded.count(), 1);
QCOMPARE(spyAboutToRemove.count(), 0);
QCOMPARE(spyRemoved.count(), 0);
QCOMPARE(spyAboutToMove.count(), 3);
QCOMPARE(spyMoved.count(), 3);
QVERIFY(index12.isValid());
QCOMPARE(model->data(index12).toString(), QString("group12"));
QCOMPARE(model->data(index12.child(0, 0)).toString(), QString("group121"));
delete group12;
QCOMPARE(spyAboutToAdd.count(), 1);
QCOMPARE(spyAdded.count(), 1);
QCOMPARE(spyAboutToRemove.count(), 1);
QCOMPARE(spyRemoved.count(), 1);
QCOMPARE(spyAboutToMove.count(), 3);
QCOMPARE(spyMoved.count(), 3);
QVERIFY(!index12.isValid());
// test removing a group that has children
delete group1;

View File

@ -52,6 +52,9 @@ void TestModified::testSignals()
g2->setParent(root);
QCOMPARE(spyModified.count(), ++spyCount);
g2->setParent(root, 0);
QCOMPARE(spyModified.count(), ++spyCount);
Entry* entry1 = new Entry();
entry1->setGroup(g1);
QCOMPARE(spyModified.count(), ++spyCount);

View File

@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
@ -94,6 +93,12 @@ ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject (
connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
this, SLOT ( rowsRemoved ( const QModelIndex &, int, int ) ) );
connect ( model, SIGNAL (rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT (rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) );
connect ( model, SIGNAL (rowsMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT (rowsMoved(QModelIndex,int,int,QModelIndex,int)) );
runAllTests();
}
@ -559,3 +564,50 @@ void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end )
QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
QVERIFY( c.next == model->data ( model->index ( start, 0, c.parent ) ) );
}
void ModelTest::rowsAboutToBeMoved( const QModelIndex &srcParent, int start, int end, const QModelIndex &destParent, int destinationRow )
{
Changing cs;
cs.parent = srcParent;
cs.oldSize = model->rowCount ( srcParent );
cs.last = model->data ( model->index ( start - 1, 0, srcParent ) );
cs.next = model->data ( model->index ( end + 1, 0, srcParent ) );
remove.push ( cs );
Changing cd;
cd.parent = destParent;
cd.oldSize = model->rowCount ( destParent );
cd.last = model->data ( model->index ( destinationRow - 1, 0, destParent ) );
cd.next = model->data ( model->index ( destinationRow, 0, destParent ) );
insert.push ( cd );
}
void ModelTest::rowsMoved( const QModelIndex &srcParent, int start, int end, const QModelIndex &destParent, int destinationRow )
{
Changing cd = insert.pop();
Q_ASSERT ( cd.parent == destParent );
if (srcParent == destParent) {
Q_ASSERT ( cd.oldSize == model->rowCount ( destParent ) );
// TODO: Find out what I can assert here about last and next.
// Q_ASSERT ( cd.last == model->data ( model->index ( destinationRow - 1, 0, cd.parent ) ) );
// Q_ASSERT ( cd.next == model->data ( model->index ( destinationRow + (end - start + 1), 0, cd.parent ) ) );
}
else {
Q_ASSERT ( cd.oldSize + ( end - start + 1 ) == model->rowCount ( destParent ) );
Q_ASSERT ( cd.last == model->data ( model->index ( destinationRow - 1, 0, cd.parent ) ) );
Q_ASSERT ( cd.next == model->data ( model->index ( destinationRow + (end - start + 1), 0, cd.parent ) ) );
}
Changing cs = remove.pop();
Q_ASSERT ( cs.parent == srcParent );
if (srcParent == destParent) {
Q_ASSERT ( cs.oldSize == model->rowCount ( srcParent ) );
}
else {
Q_ASSERT ( cs.oldSize - ( end - start + 1 ) == model->rowCount ( srcParent ) );
Q_ASSERT ( cs.last == model->data ( model->index ( start - 1, 0, srcParent ) ) );
Q_ASSERT ( cs.next == model->data ( model->index ( start, 0, srcParent ) ) );
}
}

View File

@ -71,6 +71,9 @@ protected Q_SLOTS:
void rowsInserted( const QModelIndex & parent, int start, int end );
void rowsAboutToBeRemoved( const QModelIndex &parent, int start, int end );
void rowsRemoved( const QModelIndex & parent, int start, int end );
void rowsAboutToBeMoved ( const QModelIndex &srcParent, int start, int end, const QModelIndex &destParent, int destinationRow );
void rowsMoved ( const QModelIndex &srcParent, int start, int end, const QModelIndex &destParent, int destinationRow );
private:
void checkChildren( const QModelIndex &parent, int currentDepth = 0 );