mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
More work on the parser and Entry/Group data structures.
This commit is contained in:
parent
3e3c23e4ad
commit
dae532d659
@ -28,8 +28,75 @@ Database::Database(const QString& filename)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Group* Database::rootGroup()
|
||||||
|
{
|
||||||
|
return m_rootGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::setRootGroup(Group* group)
|
||||||
|
{
|
||||||
|
m_rootGroup = group;
|
||||||
|
group->setParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Metadata* Database::metadata()
|
||||||
|
{
|
||||||
|
return m_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
void Database::open()
|
void Database::open()
|
||||||
{
|
{
|
||||||
Parser* parser = new Parser(this);
|
Parser* parser = new Parser(this);
|
||||||
parser->parse(m_filename);
|
parser->parse(m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QImage Database::icon(int number)
|
||||||
|
{
|
||||||
|
// TODO implement
|
||||||
|
return QImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage Database::customIcon(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
return m_customIcons[uuid];
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry* Database::resolveEntry(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
return recFindEntry(uuid, m_rootGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry* Database::recFindEntry(const Uuid& uuid, Group* group)
|
||||||
|
{
|
||||||
|
Q_FOREACH (Entry* entry, group->entries()) {
|
||||||
|
if (entry->uuid() == uuid)
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_FOREACH (Group* child, group->children()) {
|
||||||
|
Entry* result = recFindEntry(uuid, child);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Group* Database::resolveGroup(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
return recFindGroup(uuid, m_rootGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
Group* Database::recFindGroup(const Uuid& uuid, Group* group)
|
||||||
|
{
|
||||||
|
if (group->uuid() == uuid)
|
||||||
|
return group;
|
||||||
|
|
||||||
|
Q_FOREACH (Group* child, group->children()) {
|
||||||
|
Group* result = recFindGroup(uuid, child);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -27,20 +27,30 @@
|
|||||||
|
|
||||||
class Metadata;
|
class Metadata;
|
||||||
|
|
||||||
class Database
|
class Database : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Database(const QString& filename);
|
Database(const QString& filename);
|
||||||
Group* rootGroup();
|
Group* rootGroup();
|
||||||
|
void setRootGroup(Group* group);
|
||||||
|
Metadata* metadata();
|
||||||
|
static QImage icon(int number);
|
||||||
|
QImage customIcon(const Uuid& uuid);
|
||||||
|
Entry* resolveEntry(const Uuid& uuid);
|
||||||
|
Group* resolveGroup(const Uuid& uuid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void open();
|
void open();
|
||||||
|
Entry* recFindEntry(const Uuid& uuid, Group* group);
|
||||||
|
Group* recFindGroup(const Uuid& uuid, Group* group);
|
||||||
|
|
||||||
QString m_filename;
|
QString m_filename;
|
||||||
Metadata* m_metadata;
|
Metadata* m_metadata;
|
||||||
Group* m_rootGroup;
|
Group* m_rootGroup;
|
||||||
QHash<Uuid, QImage> customImages;
|
QHash<Uuid, QImage> m_customIcons;
|
||||||
DbAttribute unhandledAttirbute;
|
DbAttribute m_unhandledAttirbute;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_DATABASE_H
|
#endif // KEEPASSX_DATABASE_H
|
||||||
|
@ -17,6 +17,145 @@
|
|||||||
|
|
||||||
#include "Entry.h"
|
#include "Entry.h"
|
||||||
|
|
||||||
Entry::Entry()
|
#include "Group.h"
|
||||||
|
|
||||||
|
Entry::Entry() : m_group(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uuid Entry::uuid() const
|
||||||
|
{
|
||||||
|
return m_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage Entry::icon() const
|
||||||
|
{
|
||||||
|
// TODO implement
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor Entry::foregroundColor() const
|
||||||
|
{
|
||||||
|
return m_foregroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor Entry::backgroundColor() const
|
||||||
|
{
|
||||||
|
return m_backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Entry::overrideUrl() const
|
||||||
|
{
|
||||||
|
return m_overrideUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeInfo Entry::timeInfo() const
|
||||||
|
{
|
||||||
|
return m_timeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Entry::autoTypeEnabled() const
|
||||||
|
{
|
||||||
|
return m_autoTypeEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entry::autoTypeObfuscation() const
|
||||||
|
{
|
||||||
|
return m_autoTypeObfuscation;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Entry::defaultAutoTypeSequence() const
|
||||||
|
{
|
||||||
|
return m_defaultAutoTypeSequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<AutoTypeAssociation>& Entry::autoTypeAssociations() const
|
||||||
|
{
|
||||||
|
return m_autoTypeAssociations;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QHash<QString, QString>& Entry::attributes() const
|
||||||
|
{
|
||||||
|
return m_attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QHash<QString, QByteArray>& Entry::attachments() const
|
||||||
|
{
|
||||||
|
return m_binaries;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setUuid(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
m_uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setIcon(int iconNumber)
|
||||||
|
{
|
||||||
|
m_iconNumber = iconNumber;
|
||||||
|
m_customIcon = Uuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setIcon(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
m_iconNumber = 0;
|
||||||
|
m_customIcon = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setForegroundColor(const QColor& color)
|
||||||
|
{
|
||||||
|
m_foregroundColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setBackgroundColor(const QColor& color)
|
||||||
|
{
|
||||||
|
m_backgroundColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setOverrideUrl(const QString& url)
|
||||||
|
{
|
||||||
|
m_overrideUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setTimeInfo(const TimeInfo& timeInfo)
|
||||||
|
{
|
||||||
|
m_timeInfo = timeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setAutoTypeEnabled(bool enable)
|
||||||
|
{
|
||||||
|
m_autoTypeEnabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setAutoTypeObfuscation(int obfuscation)
|
||||||
|
{
|
||||||
|
m_autoTypeObfuscation = obfuscation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setDefaultAutoTypeSequence(const QString& sequence)
|
||||||
|
{
|
||||||
|
m_defaultAutoTypeSequence = sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::addAutoTypeAssociation(const AutoTypeAssociation& assoc)
|
||||||
|
{
|
||||||
|
m_autoTypeAssociations << assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::addAttribute(const QString& key, const QString& value)
|
||||||
|
{
|
||||||
|
m_attributes.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::addAttachment(const QString& key, const QByteArray& value)
|
||||||
|
{
|
||||||
|
m_binaries.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::setGroup(Group* group)
|
||||||
|
{
|
||||||
|
if (m_group) {
|
||||||
|
group->removeEntry(this);
|
||||||
|
}
|
||||||
|
group->addEntry(this);
|
||||||
|
m_group = group;
|
||||||
|
QObject::setParent(group);
|
||||||
|
}
|
||||||
|
@ -18,21 +18,73 @@
|
|||||||
#ifndef KEEPASSX_ENTRY_H
|
#ifndef KEEPASSX_ENTRY_H
|
||||||
#define KEEPASSX_ENTRY_H
|
#define KEEPASSX_ENTRY_H
|
||||||
|
|
||||||
|
#include <QtCore/QHash>
|
||||||
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtGui/QColor>
|
||||||
|
#include <QtGui/QImage>
|
||||||
|
|
||||||
|
#include "TimeInfo.h"
|
||||||
#include "Uuid.h"
|
#include "Uuid.h"
|
||||||
|
|
||||||
#include <QtCore/QHash>
|
class Group;
|
||||||
|
|
||||||
class Entry
|
struct AutoTypeAssociation
|
||||||
{
|
{
|
||||||
|
QString window;
|
||||||
|
QString sequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Entry : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Entry();
|
Entry();
|
||||||
|
Uuid uuid() const;
|
||||||
|
QImage icon() const;
|
||||||
|
QColor foregroundColor() const;
|
||||||
|
QColor backgroundColor() const;
|
||||||
|
QString overrideUrl() const;
|
||||||
|
TimeInfo timeInfo() const;
|
||||||
|
bool autoTypeEnabled() const;
|
||||||
|
int autoTypeObfuscation() const;
|
||||||
|
QString defaultAutoTypeSequence() const;
|
||||||
|
const QList<AutoTypeAssociation>& autoTypeAssociations() const;
|
||||||
|
const QHash<QString, QString>& attributes() const;
|
||||||
|
const QHash<QString, QByteArray>& attachments() const;
|
||||||
|
|
||||||
|
void setUuid(const Uuid& uuid);
|
||||||
|
void setIcon(int iconNumber);
|
||||||
|
void setIcon(const Uuid& uuid);
|
||||||
|
void setForegroundColor(const QColor& color);
|
||||||
|
void setBackgroundColor(const QColor& color);
|
||||||
|
void setOverrideUrl(const QString& url);
|
||||||
|
void setTimeInfo(const TimeInfo& timeInfo);
|
||||||
|
void setAutoTypeEnabled(bool enable);
|
||||||
|
void setAutoTypeObfuscation(int obfuscation);
|
||||||
|
void setDefaultAutoTypeSequence(const QString& sequence);
|
||||||
|
void addAutoTypeAssociation(const AutoTypeAssociation& assoc);
|
||||||
|
void addAttribute(const QString& key, const QString& value);
|
||||||
|
void addAttachment(const QString& key, const QByteArray& value);
|
||||||
|
|
||||||
|
void setGroup(Group* group);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Uuid m_uuid;
|
Uuid m_uuid;
|
||||||
int m_icon;
|
int m_iconNumber;
|
||||||
Uuid m_customIcon;
|
Uuid m_customIcon;
|
||||||
|
QColor m_foregroundColor;
|
||||||
|
QColor m_backgroundColor;
|
||||||
|
QString m_overrideUrl;
|
||||||
|
TimeInfo m_timeInfo;
|
||||||
|
bool m_autoTypeEnabled;
|
||||||
|
int m_autoTypeObfuscation;
|
||||||
|
QString m_defaultAutoTypeSequence;
|
||||||
|
QList<AutoTypeAssociation> m_autoTypeAssociations;
|
||||||
QHash<QString, QString> m_attributes;
|
QHash<QString, QString> m_attributes;
|
||||||
QHash<QString, QByteArray> m_binaries;
|
QHash<QString, QByteArray> m_binaries;
|
||||||
|
|
||||||
|
Group* m_group;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_ENTRY_H
|
#endif // KEEPASSX_ENTRY_H
|
||||||
|
@ -20,3 +20,139 @@
|
|||||||
|
|
||||||
#include "Group.h"
|
#include "Group.h"
|
||||||
|
|
||||||
|
#include "Database.h"
|
||||||
|
|
||||||
|
Group::Group() : m_parent(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Uuid Group::uuid() const
|
||||||
|
{
|
||||||
|
return m_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Group::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Group::notes() const
|
||||||
|
{
|
||||||
|
return m_notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage Group::icon() const
|
||||||
|
{
|
||||||
|
if (m_iconNumber == 0)
|
||||||
|
return m_db->customIcon(m_customIcon);
|
||||||
|
else
|
||||||
|
return Database::icon(m_iconNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeInfo Group::timeInfo() const
|
||||||
|
{
|
||||||
|
return m_timeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Group::isExpanded() const
|
||||||
|
{
|
||||||
|
return m_isExpanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Group::defaultAutoTypeSequence() const
|
||||||
|
{
|
||||||
|
return m_defaultAutoTypeSequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry* Group::lastTopVisibleEntry() const
|
||||||
|
{
|
||||||
|
return m_lastTopVisibleEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setUuid(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
m_uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setName(const QString& name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setNotes(const QString& notes)
|
||||||
|
{
|
||||||
|
m_notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setIcon(int iconNumber)
|
||||||
|
{
|
||||||
|
m_iconNumber = iconNumber;
|
||||||
|
m_customIcon = Uuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setIcon(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
m_iconNumber = 0;
|
||||||
|
m_customIcon = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setTimeInfo(const TimeInfo& timeInfo)
|
||||||
|
{
|
||||||
|
m_timeInfo = timeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setExpanded(bool expanded)
|
||||||
|
{
|
||||||
|
m_isExpanded = expanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setDefaultAutoTypeSequence(const QString& sequence)
|
||||||
|
{
|
||||||
|
m_defaultAutoTypeSequence = sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setLastTopVisibleEntry(Entry* entry)
|
||||||
|
{
|
||||||
|
m_lastTopVisibleEntry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setParent(Group* parent)
|
||||||
|
{
|
||||||
|
if (m_parent) {
|
||||||
|
m_parent->m_children.removeAll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_db = parent->m_db;
|
||||||
|
QObject::setParent(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::setParent(Database* db)
|
||||||
|
{
|
||||||
|
if (m_db) {
|
||||||
|
m_db->setRootGroup(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_parent = 0;
|
||||||
|
m_db = db;
|
||||||
|
QObject::setParent(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Group*> Group::children() const
|
||||||
|
{
|
||||||
|
return m_children;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Entry*> Group::entries() const
|
||||||
|
{
|
||||||
|
return m_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::addEntry(Entry *entry)
|
||||||
|
{
|
||||||
|
m_entries << entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::removeEntry(Entry* entry)
|
||||||
|
{
|
||||||
|
m_entries.removeAll(entry);
|
||||||
|
}
|
||||||
|
@ -18,19 +18,62 @@
|
|||||||
#ifndef KEEPASSX_GROUP_H
|
#ifndef KEEPASSX_GROUP_H
|
||||||
#define KEEPASSX_GROUP_H
|
#define KEEPASSX_GROUP_H
|
||||||
|
|
||||||
|
#include <QtGui/QImage>
|
||||||
|
|
||||||
#include "Entry.h"
|
#include "Entry.h"
|
||||||
|
#include "TimeInfo.h"
|
||||||
#include "Uuid.h"
|
#include "Uuid.h"
|
||||||
|
|
||||||
class Group {
|
class Database;
|
||||||
|
|
||||||
|
class Group : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Group();
|
||||||
|
Uuid uuid() const;
|
||||||
|
QString name() const;
|
||||||
|
QString notes() const;
|
||||||
|
QImage icon() const;
|
||||||
|
TimeInfo timeInfo() const;
|
||||||
|
bool isExpanded() const;
|
||||||
|
QString defaultAutoTypeSequence() const;
|
||||||
|
Entry* lastTopVisibleEntry() const;
|
||||||
|
|
||||||
|
void setUuid(const Uuid& uuid);
|
||||||
|
void setName(const QString& name);
|
||||||
|
void setNotes(const QString& notes);
|
||||||
|
void setIcon(int iconNumber);
|
||||||
|
void setIcon(const Uuid& uuid);
|
||||||
|
void setTimeInfo(const TimeInfo& timeInfo);
|
||||||
|
void setExpanded(bool expanded);
|
||||||
|
void setDefaultAutoTypeSequence(const QString& sequence);
|
||||||
|
void setLastTopVisibleEntry(Entry* entry);
|
||||||
|
|
||||||
|
void setParent(Group* parent);
|
||||||
|
void setParent(Database* db);
|
||||||
|
|
||||||
|
QList<Group*> children() const;
|
||||||
|
QList<Entry*> entries() const;
|
||||||
|
void addEntry(Entry* entry);
|
||||||
|
void removeEntry(Entry* entry);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Database* m_db;
|
||||||
Uuid m_uuid;
|
Uuid m_uuid;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_notes;
|
QString m_notes;
|
||||||
int m_icon;
|
int m_iconNumber;
|
||||||
Uuid m_customIcon;
|
Uuid m_customIcon;
|
||||||
|
TimeInfo m_timeInfo;
|
||||||
bool m_isExpanded;
|
bool m_isExpanded;
|
||||||
|
QString m_defaultAutoTypeSequence;
|
||||||
|
Entry* m_lastTopVisibleEntry;
|
||||||
|
QList<Group*> m_children;
|
||||||
|
QList<Entry*> m_entries;
|
||||||
|
|
||||||
QList<Entry> m_children;
|
Group* m_parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_GROUP_H
|
#endif // KEEPASSX_GROUP_H
|
||||||
|
@ -24,112 +24,117 @@ Metadata::Metadata()
|
|||||||
QString Metadata::generator() const
|
QString Metadata::generator() const
|
||||||
{
|
{
|
||||||
return m_generator;
|
return m_generator;
|
||||||
};
|
}
|
||||||
|
|
||||||
QString Metadata::name() const
|
QString Metadata::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
};
|
}
|
||||||
|
|
||||||
QDateTime Metadata::nameChanged() const
|
QDateTime Metadata::nameChanged() const
|
||||||
{
|
{
|
||||||
return m_nameChanged;
|
return m_nameChanged;
|
||||||
};
|
}
|
||||||
|
|
||||||
QString Metadata::description() const
|
QString Metadata::description() const
|
||||||
{
|
{
|
||||||
return m_description;
|
return m_description;
|
||||||
};
|
}
|
||||||
|
|
||||||
QDateTime Metadata::descriptionChanged() const
|
QDateTime Metadata::descriptionChanged() const
|
||||||
{
|
{
|
||||||
return m_descriptionChanged;
|
return m_descriptionChanged;
|
||||||
};
|
}
|
||||||
|
|
||||||
QString Metadata::defaultUserName() const
|
QString Metadata::defaultUserName() const
|
||||||
{
|
{
|
||||||
return m_defaultUserName;
|
return m_defaultUserName;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
QDateTime Metadata::defaultUserNameChanged() const
|
||||||
|
{
|
||||||
|
return m_defaultUserNameChanged;
|
||||||
|
}
|
||||||
|
|
||||||
int Metadata::maintenanceHistoryDays() const
|
int Metadata::maintenanceHistoryDays() const
|
||||||
{
|
{
|
||||||
return m_maintenanceHistoryDays;
|
return m_maintenanceHistoryDays;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool Metadata::protectTitle() const
|
bool Metadata::protectTitle() const
|
||||||
{
|
{
|
||||||
return m_protectTitle;
|
return m_protectTitle;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool Metadata::protectUsername() const
|
bool Metadata::protectUsername() const
|
||||||
{
|
{
|
||||||
return m_protectUsername;
|
return m_protectUsername;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool Metadata::protectPassword() const
|
bool Metadata::protectPassword() const
|
||||||
{
|
{
|
||||||
return m_protectPassword;
|
return m_protectPassword;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool Metadata::protectUrl() const
|
bool Metadata::protectUrl() const
|
||||||
{
|
{
|
||||||
return m_protectUrl;
|
return m_protectUrl;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool Metadata::protectNotes() const
|
bool Metadata::protectNotes() const
|
||||||
{
|
{
|
||||||
return m_protectNotes;
|
return m_protectNotes;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool Metadata::autoEnableVisualHiding() const
|
bool Metadata::autoEnableVisualHiding() const
|
||||||
{
|
{
|
||||||
return m_autoEnableVisualHiding;
|
return m_autoEnableVisualHiding;
|
||||||
};
|
}
|
||||||
|
|
||||||
QHash<Uuid, QImage> Metadata::customIcons() const
|
QHash<Uuid, QImage> Metadata::customIcons() const
|
||||||
{
|
{
|
||||||
return m_customIcons;
|
return m_customIcons;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool Metadata::recycleBinEnabled() const
|
bool Metadata::recycleBinEnabled() const
|
||||||
{
|
{
|
||||||
return m_recycleBinEnabled;
|
return m_recycleBinEnabled;
|
||||||
};
|
}
|
||||||
|
|
||||||
Uuid Metadata::recycleBinUuid() const
|
Uuid Metadata::recycleBinUuid() const
|
||||||
{
|
{
|
||||||
return m_recycleBinUuid;
|
return m_recycleBinUuid;
|
||||||
};
|
}
|
||||||
|
|
||||||
QDateTime Metadata::recycleBinChanged() const
|
QDateTime Metadata::recycleBinChanged() const
|
||||||
{
|
{
|
||||||
return m_recycleBinChanged;
|
return m_recycleBinChanged;
|
||||||
};
|
}
|
||||||
|
|
||||||
Uuid Metadata::entryTemplatesGroup() const
|
Uuid Metadata::entryTemplatesGroup() const
|
||||||
{
|
{
|
||||||
return m_entryTemplatesGroup;
|
return m_entryTemplatesGroup;
|
||||||
};
|
}
|
||||||
|
|
||||||
QDateTime Metadata::entryTemplatesGroupChanged() const
|
QDateTime Metadata::entryTemplatesGroupChanged() const
|
||||||
{
|
{
|
||||||
return m_entryTemplatesGroupChanged;
|
return m_entryTemplatesGroupChanged;
|
||||||
};
|
}
|
||||||
|
|
||||||
Uuid Metadata::lastSelectedGroup() const
|
Uuid Metadata::lastSelectedGroup() const
|
||||||
{
|
{
|
||||||
return m_lastSelectedGroup;
|
return m_lastSelectedGroup;
|
||||||
};
|
}
|
||||||
|
|
||||||
Uuid Metadata::lastTopVisibleGroup() const
|
Uuid Metadata::lastTopVisibleGroup() const
|
||||||
{
|
{
|
||||||
return m_lastTopVisibleGroup;
|
return m_lastTopVisibleGroup;
|
||||||
};
|
}
|
||||||
|
|
||||||
QHash<QString, QString> Metadata::customFields() const
|
QHash<QString, QString> Metadata::customFields() const
|
||||||
{
|
{
|
||||||
return m_customFields;
|
return m_customFields;
|
||||||
};
|
}
|
||||||
|
|
||||||
void Metadata::setGenerator(const QString& value)
|
void Metadata::setGenerator(const QString& value)
|
||||||
{
|
{
|
||||||
@ -161,6 +166,11 @@ void Metadata::setDefaultUserName(const QString& value)
|
|||||||
m_defaultUserName = value;
|
m_defaultUserName = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Metadata::setDefaultUserNameChanged(const QDateTime& value)
|
||||||
|
{
|
||||||
|
m_defaultUserNameChanged = value;
|
||||||
|
}
|
||||||
|
|
||||||
void Metadata::setMaintenanceHistoryDays(int value)
|
void Metadata::setMaintenanceHistoryDays(int value)
|
||||||
{
|
{
|
||||||
m_maintenanceHistoryDays = value;
|
m_maintenanceHistoryDays = value;
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
QString description() const;
|
QString description() const;
|
||||||
QDateTime descriptionChanged() const;
|
QDateTime descriptionChanged() const;
|
||||||
QString defaultUserName() const;
|
QString defaultUserName() const;
|
||||||
|
QDateTime defaultUserNameChanged() const;
|
||||||
int maintenanceHistoryDays() const;
|
int maintenanceHistoryDays() const;
|
||||||
bool protectTitle() const;
|
bool protectTitle() const;
|
||||||
bool protectUsername() const;
|
bool protectUsername() const;
|
||||||
@ -58,6 +59,7 @@ public:
|
|||||||
void setDescription(const QString& value);
|
void setDescription(const QString& value);
|
||||||
void setDescriptionChanged(const QDateTime& value);
|
void setDescriptionChanged(const QDateTime& value);
|
||||||
void setDefaultUserName(const QString& value);
|
void setDefaultUserName(const QString& value);
|
||||||
|
void setDefaultUserNameChanged(const QDateTime& value);
|
||||||
void setMaintenanceHistoryDays(int value);
|
void setMaintenanceHistoryDays(int value);
|
||||||
void setProtectTitle(bool value);
|
void setProtectTitle(bool value);
|
||||||
void setProtectUsername(bool value);
|
void setProtectUsername(bool value);
|
||||||
@ -84,6 +86,7 @@ private:
|
|||||||
QString m_description;
|
QString m_description;
|
||||||
QDateTime m_descriptionChanged;
|
QDateTime m_descriptionChanged;
|
||||||
QString m_defaultUserName;
|
QString m_defaultUserName;
|
||||||
|
QDateTime m_defaultUserNameChanged;
|
||||||
int m_maintenanceHistoryDays;
|
int m_maintenanceHistoryDays;
|
||||||
|
|
||||||
bool m_protectTitle;
|
bool m_protectTitle;
|
||||||
|
@ -19,9 +19,13 @@
|
|||||||
|
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
|
|
||||||
|
#include "Database.h"
|
||||||
|
#include "Metadata.h"
|
||||||
|
|
||||||
Parser::Parser(Database* db)
|
Parser::Parser(Database* db)
|
||||||
{
|
{
|
||||||
m_db = db;
|
m_db = db;
|
||||||
|
m_meta = db->metadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::parse(const QString& filename)
|
bool Parser::parse(const QString& filename)
|
||||||
@ -30,16 +34,22 @@ bool Parser::parse(const QString& filename)
|
|||||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
m_xml.setDevice(&file);
|
m_xml.setDevice(&file);
|
||||||
|
|
||||||
|
m_tmpParent = new Group();
|
||||||
|
|
||||||
if (m_xml.readNextStartElement()) {
|
if (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "KeePassFile") {
|
if (m_xml.name() == "KeePassFile") {
|
||||||
parseKeePassFile();
|
parseKeePassFile();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.raiseError(tr("Invalid database file"));
|
raiseError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_tmpParent->children().isEmpty()) {
|
||||||
|
delete m_tmpParent;
|
||||||
|
raiseError();
|
||||||
|
}
|
||||||
|
|
||||||
return !m_xml.error();
|
return !m_xml.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +57,7 @@ void Parser::parseKeePassFile()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "KeePassFile");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "KeePassFile");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Meta") {
|
if (m_xml.name() == "Meta") {
|
||||||
parseMeta();
|
parseMeta();
|
||||||
}
|
}
|
||||||
@ -55,7 +65,7 @@ void Parser::parseKeePassFile()
|
|||||||
parseRoot();
|
parseRoot();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.raiseError(tr("Invalid database file"));
|
m_xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,30 +74,30 @@ void Parser::parseMeta()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Meta");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Meta");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Generator") {
|
if (m_xml.name() == "Generator") {
|
||||||
|
m_meta->setGenerator(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DatabaseName") {
|
else if (m_xml.name() == "DatabaseName") {
|
||||||
|
m_meta->setName(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DatabaseNameChanged") {
|
else if (m_xml.name() == "DatabaseNameChanged") {
|
||||||
|
m_meta->setNameChanged(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DatabaseDescription") {
|
else if (m_xml.name() == "DatabaseDescription") {
|
||||||
|
m_meta->setDescription(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DatabaseDescriptionChanged") {
|
else if (m_xml.name() == "DatabaseDescriptionChanged") {
|
||||||
|
m_meta->setDescriptionChanged(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DefaultUserName") {
|
else if (m_xml.name() == "DefaultUserName") {
|
||||||
|
m_meta->setDefaultUserName(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DefaultUserNameChanged") {
|
else if (m_xml.name() == "DefaultUserNameChanged") {
|
||||||
|
m_meta->setDefaultUserNameChanged(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "MaintenanceHistoryDays") {
|
else if (m_xml.name() == "MaintenanceHistoryDays") {
|
||||||
|
m_meta->setMaintenanceHistoryDays(readNumber());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "MemoryProtection") {
|
else if (m_xml.name() == "MemoryProtection") {
|
||||||
parseMemoryProtection();
|
parseMemoryProtection();
|
||||||
@ -96,25 +106,25 @@ void Parser::parseMeta()
|
|||||||
parseCustomIcons();
|
parseCustomIcons();
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "RecycleBinEnabled") {
|
else if (m_xml.name() == "RecycleBinEnabled") {
|
||||||
|
m_meta->setRecycleBinEnabled(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "RecycleBinUUID") {
|
else if (m_xml.name() == "RecycleBinUUID") {
|
||||||
|
m_meta->setRecycleBinUuid(readUuid());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "RecycleBinChanged") {
|
else if (m_xml.name() == "RecycleBinChanged") {
|
||||||
|
m_meta->setRecycleBinChanged(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "EntryTemplatesGroup") {
|
else if (m_xml.name() == "EntryTemplatesGroup") {
|
||||||
|
m_meta->setEntryTemplatesGroup(readUuid());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "EntryTemplatesGroupChanged") {
|
else if (m_xml.name() == "EntryTemplatesGroupChanged") {
|
||||||
|
m_meta->setEntryTemplatesGroupChanged(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "LastSelectedGroup") {
|
else if (m_xml.name() == "LastSelectedGroup") {
|
||||||
|
m_meta->setLastSelectedGroup(readUuid());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "LastTopVisibleGroup") {
|
else if (m_xml.name() == "LastTopVisibleGroup") {
|
||||||
|
m_meta->setLastTopVisibleGroup(readUuid());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "CustomData") {
|
else if (m_xml.name() == "CustomData") {
|
||||||
parseCustomData();
|
parseCustomData();
|
||||||
@ -129,24 +139,24 @@ void Parser::parseMemoryProtection()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "MemoryProtection");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "MemoryProtection");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "ProtectTitle") {
|
if (m_xml.name() == "ProtectTitle") {
|
||||||
|
m_meta->setProtectTitle(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "ProtectUserName") {
|
else if (m_xml.name() == "ProtectUserName") {
|
||||||
|
m_meta->setProtectUsername(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "ProtectPassword") {
|
else if (m_xml.name() == "ProtectPassword") {
|
||||||
|
m_meta->setProtectPassword(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "ProtectURL") {
|
else if (m_xml.name() == "ProtectURL") {
|
||||||
|
m_meta->setProtectUrl(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "ProtectNotes") {
|
else if (m_xml.name() == "ProtectNotes") {
|
||||||
|
m_meta->setProtectNotes(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "AutoEnableVisualHiding") {
|
else if (m_xml.name() == "AutoEnableVisualHiding") {
|
||||||
|
m_meta->setAutoEnableVisualHiding(readBool());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
@ -158,7 +168,7 @@ void Parser::parseCustomIcons()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "CustomIcons");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "CustomIcons");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Icon") {
|
if (m_xml.name() == "Icon") {
|
||||||
parseIcon();
|
parseIcon();
|
||||||
}
|
}
|
||||||
@ -172,12 +182,15 @@ void Parser::parseIcon()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Icon");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Icon");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
Uuid uuid;
|
||||||
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "UUID") {
|
if (m_xml.name() == "UUID") {
|
||||||
|
uuid = readUuid();
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Data") {
|
else if (m_xml.name() == "Data") {
|
||||||
|
QImage image;
|
||||||
|
image.loadFromData(readBinary());
|
||||||
|
m_meta->addCustomIcon(uuid, image);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
@ -196,12 +209,15 @@ void Parser::parseRoot()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Root");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Root");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Group") {
|
if (m_xml.name() == "Group") {
|
||||||
parseGroup();
|
Group* rootGroup = parseGroup();
|
||||||
|
if (rootgroup) {
|
||||||
|
rootGroup->setParent(m_db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DeletedObjects") {
|
else if (m_xml.name() == "DeletedObjects") {
|
||||||
// ?????????????????
|
// TODO implement
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
@ -209,87 +225,125 @@ void Parser::parseRoot()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseGroup()
|
Group* Parser::parseGroup()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Group");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Group");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
Group* group = 0;
|
||||||
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "UUID") {
|
if (m_xml.name() == "UUID") {
|
||||||
|
Uuid uuid = readUuid();
|
||||||
|
if (uuid.isNull()) {
|
||||||
|
raiseError();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
group = getGroup(uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Name") {
|
else if (m_xml.name() == "Name") {
|
||||||
|
group->setName(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Notes") {
|
else if (m_xml.name() == "Notes") {
|
||||||
|
group->setNotes(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "IconID") {
|
else if (m_xml.name() == "IconID") {
|
||||||
|
int iconId = readNumber();
|
||||||
|
if (iconId != 0)
|
||||||
|
group->setIcon(iconId);
|
||||||
|
}
|
||||||
|
else if (m_xml.name() == "CustomIconUUID") {
|
||||||
|
Uuid uuid = readUuid();
|
||||||
|
if (!uuid.isNull()) {
|
||||||
|
group->setIcon(uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Times") {
|
else if (m_xml.name() == "Times") {
|
||||||
parseTimes();
|
group->setTimeInfo(parseTimes());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "IsExpanded") {
|
else if (m_xml.name() == "IsExpanded") {
|
||||||
|
group->setExpanded(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DefaultAutoTypeSequence") {
|
else if (m_xml.name() == "DefaultAutoTypeSequence") {
|
||||||
|
group->setDefaultAutoTypeSequence(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "EnableAutoType") {
|
else if (m_xml.name() == "EnableAutoType") {
|
||||||
|
// TODO implement
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "EnableSearching") {
|
else if (m_xml.name() == "EnableSearching") {
|
||||||
|
// TODO implement
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "LastTopVisibleEntry") {
|
else if (m_xml.name() == "LastTopVisibleEntry") {
|
||||||
|
Uuid uuid = readUuid();
|
||||||
|
if (uuid.isNull())
|
||||||
|
group->setLastTopVisibleEntry(0);
|
||||||
|
else
|
||||||
|
group->setLastTopVisibleEntry(getEntry(uuid));
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Group") {
|
else if (m_xml.name() == "Group") {
|
||||||
parseGroup();
|
Group* newGroup = parseGroup();
|
||||||
|
if (newGroup) {
|
||||||
|
newGroup->setParent(group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Entry") {
|
else if (m_xml.name() == "Entry") {
|
||||||
parseEntry();
|
Entry* newEntry = parseEntry();
|
||||||
|
if (newEntry) {
|
||||||
|
newEntry->setGroup(group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseEntry()
|
Entry* Parser::parseEntry()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Entry");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Entry");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
Entry* entry = 0;
|
||||||
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "UUID") {
|
if (m_xml.name() == "UUID") {
|
||||||
|
Uuid uuid = readUuid();
|
||||||
|
if (uuid.isNull()) {
|
||||||
|
raiseError();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entry = getEntry(uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "IconID") {
|
else if (m_xml.name() == "IconID") {
|
||||||
|
int iconId = readNumber();
|
||||||
|
if (iconId != 0)
|
||||||
|
entry->setIcon(iconId);
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "CustomIconUUID") {
|
else if (m_xml.name() == "CustomIconUUID") {
|
||||||
|
Uuid uuid = readUuid();
|
||||||
|
if (!uuid.isNull())
|
||||||
|
entry->setIcon(uuid);
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "ForegroundColor") {
|
else if (m_xml.name() == "ForegroundColor") {
|
||||||
|
entry->setForegroundColor(readColor());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "BackgroundColor") {
|
else if (m_xml.name() == "BackgroundColor") {
|
||||||
|
entry->setBackgroundColor(readColor());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "OverrideURL") {
|
else if (m_xml.name() == "OverrideURL") {
|
||||||
|
entry->setOverrideUrl(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Times") {
|
else if (m_xml.name() == "Times") {
|
||||||
parseTimes();
|
entry->setTimeInfo(parseTimes());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "String") {
|
else if (m_xml.name() == "String") {
|
||||||
parseEntryString();
|
parseEntryString(entry);
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Binary") {
|
else if (m_xml.name() == "Binary") {
|
||||||
parseEntryBinary();
|
parseEntryBinary(entry);
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "AutoType") {
|
else if (m_xml.name() == "AutoType") {
|
||||||
parseAutoType();
|
parseAutoType(entry);
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "History") {
|
else if (m_xml.name() == "History") {
|
||||||
parseEntryHistory();
|
parseEntryHistory();
|
||||||
@ -300,16 +354,17 @@ void Parser::parseEntry()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseEntryString()
|
void Parser::parseEntryString(Entry *entry)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "String");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "String");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
QString key;
|
||||||
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Key") {
|
if (m_xml.name() == "Key") {
|
||||||
|
key = readString();
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Value") {
|
else if (m_xml.name() == "Value") {
|
||||||
|
entry->addAttribute(key, readString());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
@ -317,16 +372,17 @@ void Parser::parseEntryString()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseEntryBinary()
|
void Parser::parseEntryBinary(Entry *entry)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Binary");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Binary");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
QString key;
|
||||||
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Key") {
|
if (m_xml.name() == "Key") {
|
||||||
|
key = readString();
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Value") {
|
else if (m_xml.name() == "Value") {
|
||||||
|
entry->addAttachment(key, readBinary());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
@ -334,19 +390,22 @@ void Parser::parseEntryBinary()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseAutoType()
|
void Parser::parseAutoType(Entry* entry)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "AutoType");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "AutoType");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Enabled") {
|
if (m_xml.name() == "Enabled") {
|
||||||
|
entry->setAutoTypeEnabled(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "DataTransferObfuscation") {
|
else if (m_xml.name() == "DataTransferObfuscation") {
|
||||||
|
entry->setAutoTypeObfuscation(readNumber());
|
||||||
|
}
|
||||||
|
else if (m_xml.name() == "DefaultSequence") {
|
||||||
|
entry->setDefaultAutoTypeSequence(readString());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Association") {
|
else if (m_xml.name() == "Association") {
|
||||||
parseAutoTypeAssoc();
|
parseAutoTypeAssoc(entry);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
@ -354,16 +413,18 @@ void Parser::parseAutoType()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseAutoTypeAssoc()
|
void Parser::parseAutoTypeAssoc(Entry *entry)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Association");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Association");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
AutoTypeAssociation assoc;
|
||||||
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Window") {
|
if (m_xml.name() == "Window") {
|
||||||
|
assoc.window = readString();
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "KeystrokeSequence") {
|
else if (m_xml.name() == "KeystrokeSequence") {
|
||||||
|
assoc.sequence = readString();
|
||||||
|
entry->addAutoTypeAssociation(assoc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
@ -375,9 +436,9 @@ void Parser::parseEntryHistory()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "History");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "History");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Entry") {
|
if (m_xml.name() == "Entry") {
|
||||||
parseEntry();
|
// TODO implement
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
@ -385,36 +446,39 @@ void Parser::parseEntryHistory()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseTimes()
|
TimeInfo Parser::parseTimes()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Times");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Times");
|
||||||
|
|
||||||
while (m_xml.readNextStartElement()) {
|
TimeInfo timeInfo;
|
||||||
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "LastModificationTime") {
|
if (m_xml.name() == "LastModificationTime") {
|
||||||
|
timeInfo.setLastModificationTime(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "CreationTime") {
|
else if (m_xml.name() == "CreationTime") {
|
||||||
|
timeInfo.setCreationTime(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "LastAccessTime") {
|
else if (m_xml.name() == "LastAccessTime") {
|
||||||
|
timeInfo.setLastAccessTime(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "ExpiryTime") {
|
else if (m_xml.name() == "ExpiryTime") {
|
||||||
|
timeInfo.setExpiryTime(readDateTime());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Expires") {
|
else if (m_xml.name() == "Expires") {
|
||||||
|
timeInfo.setExpires(readBool());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "UsageCount") {
|
else if (m_xml.name() == "UsageCount") {
|
||||||
|
timeInfo.setUsageCount(readNumber());
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "LocationChanged") {
|
else if (m_xml.name() == "LocationChanged") {
|
||||||
|
timeInfo.setLocationChanged(readDateTime());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return timeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Parser::readString()
|
QString Parser::readString()
|
||||||
@ -433,7 +497,7 @@ bool Parser::readBool()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO error
|
raiseError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,23 +507,102 @@ QDateTime Parser::readDateTime()
|
|||||||
QDateTime dt = QDateTime::fromString(str, Qt::ISODate);
|
QDateTime dt = QDateTime::fromString(str, Qt::ISODate);
|
||||||
|
|
||||||
if (!dt.isValid()) {
|
if (!dt.isValid()) {
|
||||||
// TODO error
|
raiseError();
|
||||||
}
|
}
|
||||||
|
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Parser::readInt()
|
QColor Parser::readColor()
|
||||||
{
|
{
|
||||||
// TODO
|
QString colorStr = readString();
|
||||||
|
if (colorStr.length() != 7 || colorStr[0] != '#') {
|
||||||
|
raiseError();
|
||||||
|
return QColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor color;
|
||||||
|
for (int i=0; i<= 2; i++) {
|
||||||
|
QString rgbPartStr = colorStr.mid(1 + 2*i, 2);
|
||||||
|
bool ok;
|
||||||
|
int rgbPart = rgbPartStr.toInt(&ok);
|
||||||
|
if (!ok || rgbPart > 255) {
|
||||||
|
raiseError();
|
||||||
|
return QColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
color.setRed(rgbPart);
|
||||||
|
}
|
||||||
|
else if (i == 1) {
|
||||||
|
color.setGreen(rgbPart);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
color.setBlue(rgbPart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Parser::readNumber()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
int result = readString().toInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
raiseError();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uuid Parser::readUuid()
|
Uuid Parser::readUuid()
|
||||||
{
|
{
|
||||||
// TODO
|
QByteArray uuidBin = readBinary();
|
||||||
|
if (uuidBin.length() != Uuid::length) {
|
||||||
|
raiseError();
|
||||||
|
return Uuid();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Uuid(readBinary());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray Parser::readBinary()
|
QByteArray Parser::readBinary()
|
||||||
{
|
{
|
||||||
// TODO
|
return QByteArray::fromBase64(readString().toAscii());
|
||||||
|
}
|
||||||
|
|
||||||
|
Group* Parser::getGroup(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
Q_FOREACH (Group* group, m_groups) {
|
||||||
|
if (group->uuid() == uuid) {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group* group = new Group();
|
||||||
|
group->setUuid(uuid);
|
||||||
|
group->setParent(m_tmpParent);
|
||||||
|
m_groups << group;
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry* Parser::getEntry(const Uuid& uuid)
|
||||||
|
{
|
||||||
|
Q_FOREACH (Entry* entry, m_entries) {
|
||||||
|
if (entry->uuid() == uuid) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry* entry = new Entry();
|
||||||
|
entry->setUuid(uuid);
|
||||||
|
entry->setGroup(m_tmpParent);
|
||||||
|
m_entries << entry;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::raiseError()
|
||||||
|
{
|
||||||
|
m_xml.raiseError(tr("Invalid database file"));
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,14 @@
|
|||||||
|
|
||||||
#include <QtCore/QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
#include <QtCore/QXmlStreamReader>
|
#include <QtCore/QXmlStreamReader>
|
||||||
|
#include <QtGui/QColor>
|
||||||
|
|
||||||
#include "Uuid.h"
|
#include "Uuid.h"
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
class Entry;
|
||||||
|
class Group;
|
||||||
|
class Metadata;
|
||||||
|
|
||||||
class Parser : public QObject
|
class Parser : public QObject
|
||||||
{
|
{
|
||||||
@ -41,24 +45,33 @@ private:
|
|||||||
void parseIcon();
|
void parseIcon();
|
||||||
void parseCustomData();
|
void parseCustomData();
|
||||||
void parseRoot();
|
void parseRoot();
|
||||||
void parseGroup();
|
Group* parseGroup();
|
||||||
void parseEntry();
|
Entry* parseEntry();
|
||||||
void parseEntryString();
|
void parseEntryString(Entry* entry);
|
||||||
void parseEntryBinary();
|
void parseEntryBinary(Entry* entry);
|
||||||
void parseAutoType();
|
void parseAutoType(Entry* entry);
|
||||||
void parseAutoTypeAssoc();
|
void parseAutoTypeAssoc(Entry* entry);
|
||||||
void parseEntryHistory();
|
void parseEntryHistory();
|
||||||
void parseTimes();
|
TimeInfo parseTimes();
|
||||||
|
|
||||||
QString readString();
|
QString readString();
|
||||||
bool readBool();
|
bool readBool();
|
||||||
QDateTime readDateTime();
|
QDateTime readDateTime();
|
||||||
int readInt();
|
QColor readColor();
|
||||||
|
int readNumber();
|
||||||
Uuid readUuid();
|
Uuid readUuid();
|
||||||
QByteArray readBinary();
|
QByteArray readBinary();
|
||||||
|
|
||||||
|
Group* getGroup(const Uuid& uuid);
|
||||||
|
Entry* getEntry(const Uuid& uuid);
|
||||||
|
void raiseError();
|
||||||
|
|
||||||
QXmlStreamReader m_xml;
|
QXmlStreamReader m_xml;
|
||||||
Database* m_db;
|
Database* m_db;
|
||||||
|
Metadata* m_meta;
|
||||||
|
Group* m_tmpParent;
|
||||||
|
QList<Group*> m_groups;
|
||||||
|
QList<Entry*> m_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_PARSER_H
|
#endif // KEEPASSX_PARSER_H
|
||||||
|
@ -20,3 +20,72 @@
|
|||||||
TimeInfo::TimeInfo()
|
TimeInfo::TimeInfo()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDateTime TimeInfo::lastModificationTime() const
|
||||||
|
{
|
||||||
|
return m_lastModificationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime TimeInfo::creationTime() const
|
||||||
|
{
|
||||||
|
return m_creationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime TimeInfo::lastAccessTime() const
|
||||||
|
{
|
||||||
|
return m_lastAccessTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime TimeInfo::expiryTime() const
|
||||||
|
{
|
||||||
|
return m_expiryTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimeInfo::expires() const
|
||||||
|
{
|
||||||
|
return m_expires;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TimeInfo::usageCount() const
|
||||||
|
{
|
||||||
|
return m_usageCount;
|
||||||
|
}
|
||||||
|
QDateTime TimeInfo::locationChanged() const
|
||||||
|
{
|
||||||
|
return m_locationChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeInfo::setLastModificationTime(const QDateTime& dateTime)
|
||||||
|
{
|
||||||
|
m_lastModificationTime = dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeInfo::setCreationTime(const QDateTime& dateTime)
|
||||||
|
{
|
||||||
|
m_creationTime = dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeInfo::setLastAccessTime(const QDateTime& dateTime)
|
||||||
|
{
|
||||||
|
m_lastAccessTime = dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeInfo::setExpiryTime(const QDateTime& dateTime)
|
||||||
|
{
|
||||||
|
m_expiryTime = dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeInfo::setExpires(bool expires)
|
||||||
|
{
|
||||||
|
m_expires = expires;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeInfo::setUsageCount(int count)
|
||||||
|
{
|
||||||
|
m_usageCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeInfo::setLocationChanged(const QDateTime& dateTime)
|
||||||
|
{
|
||||||
|
m_locationChanged = dateTime;
|
||||||
|
}
|
||||||
|
@ -18,10 +18,37 @@
|
|||||||
#ifndef KEEPASSX_DBTIMEINFO_H
|
#ifndef KEEPASSX_DBTIMEINFO_H
|
||||||
#define KEEPASSX_DBTIMEINFO_H
|
#define KEEPASSX_DBTIMEINFO_H
|
||||||
|
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
|
|
||||||
class TimeInfo
|
class TimeInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TimeInfo();
|
TimeInfo();
|
||||||
|
|
||||||
|
QDateTime lastModificationTime() const;
|
||||||
|
QDateTime creationTime() const;
|
||||||
|
QDateTime lastAccessTime() const;
|
||||||
|
QDateTime expiryTime() const;
|
||||||
|
bool expires() const;
|
||||||
|
int usageCount() const;
|
||||||
|
QDateTime locationChanged() const;
|
||||||
|
|
||||||
|
void setLastModificationTime(const QDateTime& dateTime);
|
||||||
|
void setCreationTime(const QDateTime& dateTime);
|
||||||
|
void setLastAccessTime(const QDateTime& dateTime);
|
||||||
|
void setExpiryTime(const QDateTime& dateTime);
|
||||||
|
void setExpires(bool expires);
|
||||||
|
void setUsageCount(int count);
|
||||||
|
void setLocationChanged(const QDateTime& dateTime);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QDateTime m_lastModificationTime;
|
||||||
|
QDateTime m_creationTime;
|
||||||
|
QDateTime m_lastAccessTime;
|
||||||
|
QDateTime m_expiryTime;
|
||||||
|
bool m_expires;
|
||||||
|
int m_usageCount;
|
||||||
|
QDateTime m_locationChanged;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_DBTIMEINFO_H
|
#endif // KEEPASSX_DBTIMEINFO_H
|
||||||
|
@ -17,11 +17,13 @@
|
|||||||
|
|
||||||
#include "Uuid.h"
|
#include "Uuid.h"
|
||||||
|
|
||||||
Uuid::Uuid() : m_data(16, 0)
|
const int Uuid::length = 16;
|
||||||
|
|
||||||
|
Uuid::Uuid() : m_data(length, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Uuid::Uuid(bool generate) : m_data(16, 0)
|
Uuid::Uuid(bool generate) : m_data(length, 0)
|
||||||
{
|
{
|
||||||
if (generate) {
|
if (generate) {
|
||||||
while (isNull()) {
|
while (isNull()) {
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
bool isNull() const;
|
bool isNull() const;
|
||||||
bool operator==(const Uuid& other) const;
|
bool operator==(const Uuid& other) const;
|
||||||
bool operator!=(const Uuid& other) const;
|
bool operator!=(const Uuid& other) const;
|
||||||
|
static const int length;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray m_data;
|
QByteArray m_data;
|
||||||
|
Loading…
Reference in New Issue
Block a user