Support Entry History and DeletedObjects.

This commit is contained in:
Felix Geyer 2010-08-25 13:52:59 +02:00
parent 5efccf32c9
commit 3193adc215
8 changed files with 140 additions and 17 deletions

View File

@ -99,3 +99,13 @@ Group* Database::recFindGroup(const Uuid& uuid, Group* group)
return 0; return 0;
} }
QList<DeletedObject> Database::deletedObjects()
{
return m_deletedObjects;
}
void Database::addDeletedObject(const DeletedObject& delObj)
{
m_deletedObjects.append(delObj);
}

View File

@ -27,6 +27,12 @@
class Metadata; class Metadata;
struct DeletedObject
{
Uuid uuid;
QDateTime deletionTime;
};
class Database : public QObject class Database : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -41,6 +47,8 @@ public:
QImage customIcon(const Uuid& uuid) const; QImage customIcon(const Uuid& uuid) const;
Entry* resolveEntry(const Uuid& uuid); Entry* resolveEntry(const Uuid& uuid);
Group* resolveGroup(const Uuid& uuid); Group* resolveGroup(const Uuid& uuid);
QList<DeletedObject> deletedObjects();
void addDeletedObject(const DeletedObject& delObj);
Q_SIGNALS: Q_SIGNALS:
void groupDataChanged(Group* group); void groupDataChanged(Group* group);
@ -57,6 +65,7 @@ private:
Group* m_rootGroup; Group* m_rootGroup;
QHash<Uuid, QImage> m_customIcons; QHash<Uuid, QImage> m_customIcons;
DbAttribute m_unhandledAttirbute; DbAttribute m_unhandledAttirbute;
QList<DeletedObject> m_deletedObjects;
}; };
#endif // KEEPASSX_DATABASE_H #endif // KEEPASSX_DATABASE_H

View File

@ -29,6 +29,7 @@ Entry::Entry()
Entry::~Entry() Entry::~Entry()
{ {
// TODO notify group // TODO notify group
qDeleteAll(m_history);
} }
Uuid Entry::uuid() const Uuid Entry::uuid() const
@ -236,6 +237,23 @@ void Entry::setNotes(const QString& notes)
addAttribute("Notes", notes); addAttribute("Notes", notes);
} }
QList<Entry*> Entry::historyItems()
{
return m_history;
}
const QList<Entry*>& Entry::historyItems() const
{
return m_history;
}
void Entry::addHistoryItem(Entry* entry)
{
Q_ASSERT(!entry->parent());
m_history.append(entry);
}
void Entry::setGroup(Group* group) void Entry::setGroup(Group* group)
{ {
if (m_group) { if (m_group) {

View File

@ -81,8 +81,13 @@ public:
void setPassword(const QString& password); void setPassword(const QString& password);
void setNotes(const QString& notes); void setNotes(const QString& notes);
QList<Entry*> historyItems();
const QList<Entry*>& historyItems() const;
void addHistoryItem(Entry* entry);
void setGroup(Group* group); void setGroup(Group* group);
Q_SIGNALS: Q_SIGNALS:
void dataChanged(Entry* entry); void dataChanged(Entry* entry);
@ -101,6 +106,7 @@ private:
QHash<QString, QString> m_attributes; QHash<QString, QString> m_attributes;
QHash<QString, QByteArray> m_binaries; QHash<QString, QByteArray> m_binaries;
QList<Entry*> m_history;
Group* m_group; Group* m_group;
const Database* m_db; const Database* m_db;
}; };

View File

@ -228,8 +228,7 @@ void Parser::parseRoot()
} }
} }
else if (m_xml.name() == "DeletedObjects") { else if (m_xml.name() == "DeletedObjects") {
// TODO implement parseDeletedObjects();
skipCurrentElement();
} }
else { else {
skipCurrentElement(); skipCurrentElement();
@ -325,7 +324,7 @@ Group* Parser::parseGroup()
} }
} }
else if (m_xml.name() == "Entry") { else if (m_xml.name() == "Entry") {
Entry* newEntry = parseEntry(); Entry* newEntry = parseEntry(false);
if (newEntry) { if (newEntry) {
newEntry->setGroup(group); newEntry->setGroup(group);
} }
@ -338,7 +337,48 @@ Group* Parser::parseGroup()
return group; return group;
} }
Entry* Parser::parseEntry() void Parser::parseDeletedObjects()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "DeletedObjects");
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "DeletedObject") {
parseDeletedObject();
}
else {
skipCurrentElement();
}
}
}
void Parser::parseDeletedObject()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "DeletedObject");
DeletedObject delObj;
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "UUID") {
Uuid uuid = readUuid();
if (uuid.isNull()) {
raiseError();
}
else {
delObj.uuid = uuid;
}
}
else if (m_xml.name() == "DeletionTime") {
delObj.deletionTime = readDateTime();
}
else {
skipCurrentElement();
}
}
m_db->addDeletedObject(delObj);
}
Entry* Parser::parseEntry(bool history)
{ {
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Entry"); Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Entry");
@ -350,8 +390,13 @@ Entry* Parser::parseEntry()
raiseError(); raiseError();
} }
else { else {
entry = getEntry(uuid); if (history) {
} entry = new Entry();
}
else {
entry = getEntry(uuid);
}
}
} }
else if (m_xml.name() == "IconID") { else if (m_xml.name() == "IconID") {
int iconId = readNumber(); int iconId = readNumber();
@ -389,7 +434,12 @@ Entry* Parser::parseEntry()
parseAutoType(entry); parseAutoType(entry);
} }
else if (m_xml.name() == "History") { else if (m_xml.name() == "History") {
parseEntryHistory(); if (history) {
raiseError();
}
else {
parseEntryHistory(entry);
}
} }
else { else {
skipCurrentElement(); skipCurrentElement();
@ -477,14 +527,14 @@ void Parser::parseAutoTypeAssoc(Entry *entry)
} }
} }
void Parser::parseEntryHistory() void Parser::parseEntryHistory(Entry* entry)
{ {
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "History"); Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "History");
while (!m_xml.error() && m_xml.readNextStartElement()) { while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Entry") { if (m_xml.name() == "Entry") {
// TODO implement Entry* historyItem = parseEntry(true);
skipCurrentElement(); entry->addHistoryItem(historyItem);
} }
else { else {
skipCurrentElement(); skipCurrentElement();

View File

@ -48,12 +48,14 @@ private:
void parseCustomData(); void parseCustomData();
void parseRoot(); void parseRoot();
Group* parseGroup(); Group* parseGroup();
Entry* parseEntry(); void parseDeletedObjects();
void parseDeletedObject();
Entry* parseEntry(bool history);
void parseEntryString(Entry* entry); void parseEntryString(Entry* entry);
void parseEntryBinary(Entry* entry); void parseEntryBinary(Entry* entry);
void parseAutoType(Entry* entry); void parseAutoType(Entry* entry);
void parseAutoTypeAssoc(Entry* entry); void parseAutoTypeAssoc(Entry* entry);
void parseEntryHistory(); void parseEntryHistory(Entry* entry);
TimeInfo parseTimes(); TimeInfo parseTimes();
QString readString(); QString readString();

View File

@ -20,7 +20,6 @@
#include <QtCore/QBuffer> #include <QtCore/QBuffer>
#include <QtCore/QFile> #include <QtCore/QFile>
#include "core/Database.h"
#include "core/Metadata.h" #include "core/Metadata.h"
Writer::Writer(Database* db) Writer::Writer(Database* db)
@ -29,7 +28,7 @@ Writer::Writer(Database* db)
, m_meta(db->metadata()) , m_meta(db->metadata())
{ {
m_xml.setAutoFormatting(true); m_xml.setAutoFormatting(true);
m_xml.setAutoFormattingIndent(-1); m_xml.setAutoFormattingIndent(-1); // 1 tab
m_xml.setCodec("UTF-8"); m_xml.setCodec("UTF-8");
} }
@ -140,7 +139,11 @@ void Writer::writeRoot()
m_xml.writeStartElement("Root"); m_xml.writeStartElement("Root");
writeGroup(m_db->rootGroup()); writeGroup(m_db->rootGroup());
m_xml.writeStartElement("DeletedObjects"); m_xml.writeStartElement("DeletedObjects");
m_xml.writeEndElement(); m_xml.writeEndElement();
m_xml.writeEndElement(); m_xml.writeEndElement();
@ -215,6 +218,27 @@ void Writer::writeTimes(const TimeInfo& ti)
m_xml.writeEndElement(); m_xml.writeEndElement();
} }
void Writer::writeDeletedObjects()
{
m_xml.writeStartElement("DeletedObjects");
Q_FOREACH (const DeletedObject& delObj, m_db->deletedObjects()) {
writeDeletedObject(delObj);
}
m_xml.writeEndElement();
}
void Writer::writeDeletedObject(const DeletedObject& delObj)
{
m_xml.writeStartElement("DeletedObject");
writeUuid("UUID", delObj.uuid);
writeDateTime("DeletionTime", delObj.deletionTime);
m_xml.writeEndElement();
}
void Writer::writeEntry(const Entry* entry) void Writer::writeEntry(const Entry* entry)
{ {
m_xml.writeStartElement("Entry"); m_xml.writeStartElement("Entry");
@ -278,8 +302,10 @@ void Writer::writeEntryHistory(const Entry* entry)
{ {
m_xml.writeStartElement("History"); m_xml.writeStartElement("History");
// TODO implement const QList<Entry*>& historyItems = entry->historyItems();
Q_UNUSED(entry); Q_FOREACH (const Entry* item, historyItems) {
writeEntry(item);
}
m_xml.writeEndElement(); m_xml.writeEndElement();
} }

View File

@ -23,11 +23,11 @@
#include <QtGui/QColor> #include <QtGui/QColor>
#include <QtGui/QImage> #include <QtGui/QImage>
#include "core/Database.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "core/TimeInfo.h" #include "core/TimeInfo.h"
#include "core/Uuid.h" #include "core/Uuid.h"
class Database;
class Group; class Group;
class Metadata; class Metadata;
@ -49,6 +49,8 @@ private:
void writeRoot(); void writeRoot();
void writeGroup(const Group* group); void writeGroup(const Group* group);
void writeTimes(const TimeInfo& ti); void writeTimes(const TimeInfo& ti);
void writeDeletedObjects();
void writeDeletedObject(const DeletedObject& delObj);
void writeEntry(const Entry* entry); void writeEntry(const Entry* entry);
void writeAutoType(const Entry* entry); void writeAutoType(const Entry* entry);
void writeAutoTypeAssoc(const AutoTypeAssociation& assoc); void writeAutoTypeAssoc(const AutoTypeAssociation& assoc);