Add flags to Entry::clone() for customized cloning.

This commit is contained in:
Felix Geyer 2013-11-22 13:27:49 +01:00
parent cb804eb143
commit f2dfef8c41
8 changed files with 97 additions and 14 deletions

View File

@ -439,22 +439,40 @@ void Entry::truncateHistory()
}
}
Entry* Entry::clone() const
Entry* Entry::clone(CloneFlags flags) const
{
Entry* entry = new Entry();
entry->setUpdateTimeinfo(false);
entry->m_uuid = Uuid::random();
if (flags & CloneNewUuid) {
entry->m_uuid = Uuid::random();
}
else {
entry->m_uuid = m_uuid;
}
entry->m_data = m_data;
entry->m_attributes->copyDataFrom(m_attributes);
entry->m_attachments->copyDataFrom(m_attachments);
entry->m_autoTypeAssociations->copyDataFrom(this->m_autoTypeAssociations);
if (flags & CloneIncludeHistory) {
Q_FOREACH (Entry* historyItem, m_history) {
Entry* historyItemClone = historyItem->clone(flags & ~CloneIncludeHistory & ~CloneNewUuid);
historyItemClone->setUpdateTimeinfo(false);
historyItemClone->setUuid(entry->uuid());
historyItemClone->setUpdateTimeinfo(true);
entry->addHistoryItem(historyItemClone);
}
}
entry->setUpdateTimeinfo(true);
QDateTime now = Tools::currentDateTimeUtc();
entry->m_data.timeInfo.setCreationTime(now);
entry->m_data.timeInfo.setLastModificationTime(now);
entry->m_data.timeInfo.setLastAccessTime(now);
entry->m_data.timeInfo.setLocationChanged(now);
if (flags & CloneResetTimeInfo) {
QDateTime now = Tools::currentDateTimeUtc();
entry->m_data.timeInfo.setCreationTime(now);
entry->m_data.timeInfo.setLastModificationTime(now);
entry->m_data.timeInfo.setLastAccessTime(now);
entry->m_data.timeInfo.setLocationChanged(now);
}
return entry;
}

View File

@ -110,13 +110,22 @@ public:
void addHistoryItem(Entry* entry);
void removeHistoryItems(const QList<Entry*>& historyEntries);
void truncateHistory();
enum CloneFlag {
CloneNoFlags = 0,
CloneNewUuid = 1, // generate a random uuid for the clone
CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
CloneIncludeHistory = 4 // clone the history items
};
Q_DECLARE_FLAGS(CloneFlags, CloneFlag)
/**
* Creates a duplicate of this entry except that returned entry isn't part
* of any group and all TimeInfo attributes are set to the current time.
* Creates a duplicate of this entry except that the returned entry isn't
* part of any group.
* Note that you need to copy the custom icons manually when inserting the
* new entry into another database.
*/
Entry* clone() const;
Entry* clone(CloneFlags flags) const;
void copyDataFrom(const Entry* other);
QString resolvePlaceholders(const QString& str) const;
@ -166,4 +175,6 @@ private:
bool m_updateTimeinfo;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Entry::CloneFlags)
#endif // KEEPASSX_ENTRY_H

View File

@ -474,7 +474,7 @@ Group* Group::clone() const
clonedGroup->m_data = m_data;
Q_FOREACH (Entry* entry, entries()) {
Entry* clonedEntry = entry->clone();
Entry* clonedEntry = entry->clone(Entry::CloneNewUuid | Entry::CloneResetTimeInfo);
clonedEntry->setGroup(clonedGroup);
}

View File

@ -224,7 +224,7 @@ void DatabaseWidget::cloneEntry()
return;
}
Entry* entry = currentEntry->clone();
Entry* entry = currentEntry->clone(Entry::CloneNewUuid | Entry::CloneResetTimeInfo);
entry->setGroup(currentEntry->group());
m_entryView->setFocus();
m_entryView->setCurrentEntry(entry);

View File

@ -298,7 +298,7 @@ bool GroupModel::dropMimeData(const QMimeData* data, Qt::DropAction action,
entry = dragEntry;
}
else {
entry = dragEntry->clone();
entry = dragEntry->clone(Entry::CloneNewUuid | Entry::CloneResetTimeInfo);
}
Database* sourceDb = dragEntry->group()->database();

View File

@ -21,6 +21,12 @@
#include "tests.h"
#include "core/Entry.h"
#include "crypto/Crypto.h"
void TestEntry::initTestCase()
{
Crypto::init();
}
void TestEntry::testHistoryItemDeletion()
{
@ -74,4 +80,46 @@ void TestEntry::testCopyDataFrom()
QCOMPARE(entry2->autoTypeAssociations()->get(1).window, QString("3"));
}
void TestEntry::testClone()
{
Entry* entryOrg = new Entry();
entryOrg->setUuid(Uuid::random());
entryOrg->setTitle("Original Title");
entryOrg->beginUpdate();
entryOrg->setTitle("New Title");
entryOrg->endUpdate();
TimeInfo entryOrgTime = entryOrg->timeInfo();
QDateTime dateTime;
dateTime.setTimeSpec(Qt::UTC);
dateTime.setMSecsSinceEpoch(60);
entryOrgTime.setCreationTime(dateTime);
entryOrg->setTimeInfo(entryOrgTime);
Entry* entryCloneNone = entryOrg->clone(Entry::CloneNoFlags);
QCOMPARE(entryCloneNone->uuid(), entryOrg->uuid());
QCOMPARE(entryCloneNone->title(), QString("New Title"));
QCOMPARE(entryCloneNone->historyItems().size(), 0);
QCOMPARE(entryCloneNone->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
Entry* entryCloneNewUuid = entryOrg->clone(Entry::CloneNewUuid);
QVERIFY(entryCloneNewUuid->uuid() != entryOrg->uuid());
QVERIFY(!entryCloneNewUuid->uuid().isNull());
QCOMPARE(entryCloneNewUuid->title(), QString("New Title"));
QCOMPARE(entryCloneNewUuid->historyItems().size(), 0);
QCOMPARE(entryCloneNewUuid->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
Entry* entryCloneResetTime = entryOrg->clone(Entry::CloneResetTimeInfo);
QCOMPARE(entryCloneNone->uuid(), entryOrg->uuid());
QCOMPARE(entryCloneResetTime->title(), QString("New Title"));
QCOMPARE(entryCloneResetTime->historyItems().size(), 0);
QVERIFY(entryCloneResetTime->timeInfo().creationTime() != entryOrg->timeInfo().creationTime());
Entry* entryCloneHistory = entryOrg->clone(Entry::CloneIncludeHistory);
QCOMPARE(entryCloneNone->uuid(), entryOrg->uuid());
QCOMPARE(entryCloneHistory->title(), QString("New Title"));
QCOMPARE(entryCloneHistory->historyItems().size(), 1);
QCOMPARE(entryCloneHistory->historyItems().first()->title(), QString("Original Title"));
QCOMPARE(entryCloneHistory->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
}
QTEST_GUILESS_MAIN(TestEntry)

View File

@ -27,8 +27,10 @@ class TestEntry : public QObject
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void testHistoryItemDeletion();
void testCopyDataFrom();
void testClone();
};
#endif // KEEPASSX_TESTENTRY_H

View File

@ -441,8 +441,11 @@ void TestGroup::testClone()
Entry* originalGroupEntry = new Entry();
originalGroupEntry->setGroup(originalGroup);
originalGroupEntry->setTitle("GroupEntry");
originalGroupEntry->setTitle("GroupEntryOld");
originalGroupEntry->setIcon(43);
originalGroupEntry->beginUpdate();
originalGroupEntry->setTitle("GroupEntry");
originalGroupEntry->endUpdate();
Group* subGroup = new Group();
subGroup->setParent(originalGroup);
@ -465,6 +468,7 @@ void TestGroup::testClone()
QVERIFY(clonedGroupEntry->uuid() != originalGroupEntry->uuid());
QCOMPARE(clonedGroupEntry->title(), QString("GroupEntry"));
QCOMPARE(clonedGroupEntry->iconNumber(), 43);
QCOMPARE(clonedGroupEntry->historyItems().size(), 0);
Group* clonedSubGroup = clonedGroup->children().at(0);
QVERIFY(clonedSubGroup->uuid() != subGroup->uuid());