mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-01-11 15:29:51 -05:00
Add EntryModel.
This commit is contained in:
parent
84bc5ef463
commit
8d623f37ca
@ -26,6 +26,7 @@ set(keepassx_SOURCES
|
||||
core/Parser.cpp
|
||||
core/TimeInfo.cpp
|
||||
core/Uuid.cpp
|
||||
gui/EntryModel.cpp
|
||||
gui/GroupModel.cpp
|
||||
)
|
||||
|
||||
|
@ -26,6 +26,11 @@ Entry::Entry()
|
||||
m_db = 0;
|
||||
}
|
||||
|
||||
Entry::~Entry()
|
||||
{
|
||||
// TODO notify group
|
||||
}
|
||||
|
||||
Uuid Entry::uuid() const
|
||||
{
|
||||
return m_uuid;
|
||||
@ -182,6 +187,11 @@ void Entry::addAutoTypeAssociation(const AutoTypeAssociation& assoc)
|
||||
void Entry::addAttribute(const QString& key, const QString& value)
|
||||
{
|
||||
m_attributes.insert(key, value);
|
||||
|
||||
// TODO add all visible oclumns
|
||||
if (key == "Title") {
|
||||
Q_EMIT dataChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::addAttachment(const QString& key, const QByteArray& value)
|
||||
@ -191,27 +201,27 @@ void Entry::addAttachment(const QString& key, const QByteArray& value)
|
||||
|
||||
void Entry::setTitle(const QString& title)
|
||||
{
|
||||
m_attributes.insert("Title", title);
|
||||
addAttribute("Title", title);
|
||||
}
|
||||
|
||||
void Entry::setUrl(const QString& url)
|
||||
{
|
||||
m_attributes.insert("URL", url);
|
||||
addAttribute("URL", url);
|
||||
}
|
||||
|
||||
void Entry::setUsername(const QString& username)
|
||||
{
|
||||
m_attributes.insert("UserName", username);
|
||||
addAttribute("UserName", username);
|
||||
}
|
||||
|
||||
void Entry::setPassword(const QString& password)
|
||||
{
|
||||
m_attributes.insert("Password", password);
|
||||
addAttribute("Password", password);
|
||||
}
|
||||
|
||||
void Entry::setNotes(const QString& notes)
|
||||
{
|
||||
m_attributes.insert("Notes", notes);
|
||||
addAttribute("Notes", notes);
|
||||
}
|
||||
|
||||
void Entry::setGroup(Group* group)
|
||||
|
@ -41,6 +41,7 @@ class Entry : public QObject
|
||||
|
||||
public:
|
||||
Entry();
|
||||
~Entry();
|
||||
Uuid uuid() const;
|
||||
QImage icon() const;
|
||||
QColor foregroundColor() const;
|
||||
@ -80,6 +81,9 @@ public:
|
||||
|
||||
void setGroup(Group* group);
|
||||
|
||||
Q_SIGNALS:
|
||||
void dataChanged(const Entry* entry);
|
||||
|
||||
private:
|
||||
Uuid m_uuid;
|
||||
int m_iconNumber;
|
||||
|
@ -28,6 +28,11 @@ Group::Group()
|
||||
m_db = 0;
|
||||
}
|
||||
|
||||
Group::~Group()
|
||||
{
|
||||
// TODO notify parent
|
||||
}
|
||||
|
||||
Uuid Group::uuid() const
|
||||
{
|
||||
return m_uuid;
|
||||
@ -229,14 +234,24 @@ QList<const Entry*> Group::entries() const
|
||||
|
||||
void Group::addEntry(Entry *entry)
|
||||
{
|
||||
Q_ASSERT(entry != 0);
|
||||
Q_ASSERT(entry);
|
||||
|
||||
Q_EMIT entryAboutToAdd(entry);
|
||||
|
||||
m_entries << entry;
|
||||
connect(entry, SIGNAL(dataChanged(const Entry*)), SIGNAL(entryDataChanged(const Entry*)));
|
||||
|
||||
Q_EMIT entryAdded();
|
||||
}
|
||||
|
||||
void Group::removeEntry(Entry* entry)
|
||||
{
|
||||
Q_EMIT entryAboutToRemove(entry);
|
||||
|
||||
entry->disconnect(this);
|
||||
m_entries.removeAll(entry);
|
||||
|
||||
Q_EMIT entryRemoved();
|
||||
}
|
||||
|
||||
void Group::recSetDatabase(Database* db)
|
||||
|
@ -32,6 +32,7 @@ class Group : public QObject
|
||||
|
||||
public:
|
||||
Group();
|
||||
~Group();
|
||||
Uuid uuid() const;
|
||||
QString name() const;
|
||||
QString notes() const;
|
||||
@ -65,10 +66,18 @@ public:
|
||||
|
||||
Q_SIGNALS:
|
||||
void dataChanged(const Group* group);
|
||||
void aboutToRemove(const Group* group);
|
||||
void removed();
|
||||
|
||||
void aboutToAdd(const Group* group, int index);
|
||||
void added();
|
||||
void aboutToRemove(const Group* group);
|
||||
void removed();
|
||||
|
||||
void entryAboutToAdd(const Entry* entry);
|
||||
void entryAdded();
|
||||
void entryAboutToRemove(const Entry* entry);
|
||||
void entryRemoved();
|
||||
|
||||
void entryDataChanged(const Entry* entry);
|
||||
|
||||
private:
|
||||
void recSetDatabase(Database* db);
|
||||
|
120
src/gui/EntryModel.cpp
Normal file
120
src/gui/EntryModel.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EntryModel.h"
|
||||
|
||||
#include "core/Entry.h"
|
||||
#include "core/Group.h"
|
||||
|
||||
EntryModel::EntryModel(QObject* parent)
|
||||
: QAbstractTableModel(parent)
|
||||
, m_group(0)
|
||||
{
|
||||
}
|
||||
|
||||
void EntryModel::setGroup(const Group* group)
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
if (m_group) {
|
||||
disconnect(m_group, 0, this, 0);
|
||||
}
|
||||
m_group = group;
|
||||
connect(group, SIGNAL(entryAboutToAdd(const Entry*)), SLOT(entryAboutToAdd(const Entry*)));
|
||||
connect(group, SIGNAL(entryAdded()), SLOT(entryAdded()));
|
||||
connect(group, SIGNAL(entryAboutToRemove(const Entry*)), SLOT(entryAboutToRemove(const Entry*)));
|
||||
connect(group, SIGNAL(entryRemoved()), SLOT(entryRemoved()));
|
||||
connect(group, SIGNAL(entryDataChanged(const Entry*)), SLOT(entryDataChanged(const Entry*)));
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
int EntryModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!m_group || parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return m_group->entries().size();
|
||||
}
|
||||
}
|
||||
|
||||
int EntryModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant EntryModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const Entry* entry = m_group->entries().at(index.row());
|
||||
|
||||
// TODO implement other columns
|
||||
if (role == Qt::DisplayRole) {
|
||||
return entry->title();
|
||||
}
|
||||
else if (role == Qt::DecorationRole) {
|
||||
return entry->icon();
|
||||
}
|
||||
else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
QVariant EntryModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
Q_UNUSED(section);
|
||||
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
return tr("Title");
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void EntryModel::entryAboutToAdd(const Entry* entry)
|
||||
{
|
||||
Q_UNUSED(entry);
|
||||
|
||||
beginInsertRows(QModelIndex(), m_group->entries().size(), m_group->entries().size());
|
||||
}
|
||||
|
||||
void EntryModel::entryAdded()
|
||||
{
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void EntryModel::entryAboutToRemove(const Entry* entry)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(), m_group->entries().indexOf(entry), m_group->entries().indexOf(entry));
|
||||
}
|
||||
|
||||
void EntryModel::entryRemoved()
|
||||
{
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void EntryModel::entryDataChanged(const Entry* entry)
|
||||
{
|
||||
int row = m_group->entries().indexOf(entry);
|
||||
qDebug("%d", index(row, 0).row());
|
||||
Q_EMIT dataChanged(index(row, 0), index(row, columnCount()-1));
|
||||
}
|
51
src/gui/EntryModel.h
Normal file
51
src/gui/EntryModel.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_ENTRYMODEL_H
|
||||
#define KEEPASSX_ENTRYMODEL_H
|
||||
|
||||
#include <QtCore/QAbstractTableModel>
|
||||
|
||||
class Entry;
|
||||
class Group;
|
||||
|
||||
class EntryModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EntryModel(QObject* parent = 0);
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setGroup(const Group* group);
|
||||
|
||||
private Q_SLOTS:
|
||||
void entryAboutToAdd(const Entry* entry);
|
||||
void entryAdded();
|
||||
void entryAboutToRemove(const Entry* entry);
|
||||
void entryRemoved();
|
||||
void entryDataChanged(const Entry* entry);
|
||||
|
||||
private:
|
||||
const Group* m_group;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_ENTRYMODEL_H
|
@ -35,7 +35,7 @@ public:
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex& index) const;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
private:
|
||||
QModelIndex createIndex(int row, int column, const Group* group) const;
|
||||
|
@ -71,3 +71,6 @@ target_link_libraries( testparser keepassx_core ${QT_QTCORE_LIBRARY} ${QT_QTGUI_
|
||||
|
||||
add_unit_test( testgroupmodel TestGroupModel.cpp modeltest.cpp )
|
||||
target_link_libraries( testgroupmodel keepassx_core ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTTEST_LIBRARY} )
|
||||
|
||||
add_unit_test( testentrymodel TestEntryModel.cpp modeltest.cpp )
|
||||
target_link_libraries( testentrymodel keepassx_core ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTTEST_LIBRARY} )
|
||||
|
99
tests/TestEntryModel.cpp
Normal file
99
tests/TestEntryModel.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QtTest/QSignalSpy>
|
||||
#include <QtTest/QTest>
|
||||
|
||||
#include "modeltest.h"
|
||||
#include "core/Entry.h"
|
||||
#include "core/Group.h"
|
||||
#include "gui/EntryModel.h"
|
||||
|
||||
class TestEntryModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void test();
|
||||
};
|
||||
|
||||
void TestEntryModel::test()
|
||||
{
|
||||
qRegisterMetaType<QModelIndex>("QModelIndex");
|
||||
|
||||
Group* group1 = new Group();
|
||||
Group* group2 = new Group();
|
||||
|
||||
Entry* entry1 = new Entry();
|
||||
entry1->setGroup(group1);
|
||||
entry1->setTitle("testTitle1");
|
||||
|
||||
Entry* entry2 = new Entry();
|
||||
entry2->setGroup(group1);
|
||||
entry2->setTitle("testTitle2");
|
||||
|
||||
EntryModel* model = new EntryModel(this);
|
||||
|
||||
new ModelTest(model, this);
|
||||
|
||||
model->setGroup(group1);
|
||||
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
|
||||
QSignalSpy spyDataChanged(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)));
|
||||
entry1->setTitle("changed");
|
||||
QCOMPARE(spyDataChanged.count(), 1);
|
||||
|
||||
QModelIndex index1 = model->index(0, 0);
|
||||
QModelIndex index2 = model->index(1, 0);
|
||||
|
||||
QCOMPARE(model->data(index1).toString(), entry1->title());
|
||||
QCOMPARE(model->data(index2).toString(), entry2->title());
|
||||
|
||||
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)));
|
||||
|
||||
Entry* entry3 = new Entry();
|
||||
entry3->setGroup(group1);
|
||||
|
||||
QCOMPARE(spyAboutToAdd.count(), 1);
|
||||
QCOMPARE(spyAdded.count(), 1);
|
||||
QCOMPARE(spyAboutToRemove.count(), 0);
|
||||
QCOMPARE(spyRemoved.count(), 0);
|
||||
|
||||
entry2->setGroup(group2);
|
||||
|
||||
QCOMPARE(spyAboutToAdd.count(), 1);
|
||||
QCOMPARE(spyAdded.count(), 1);
|
||||
QCOMPARE(spyAboutToRemove.count(), 1);
|
||||
QCOMPARE(spyRemoved.count(), 1);
|
||||
|
||||
QSignalSpy spyReset(model, SIGNAL(modelReset()));
|
||||
model->setGroup(group2);
|
||||
QCOMPARE(spyReset.count(), 1);
|
||||
|
||||
delete group1;
|
||||
delete group2;
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestEntryModel);
|
||||
|
||||
Q_DECLARE_METATYPE(QModelIndex);
|
||||
|
||||
#include "TestEntryModel.moc"
|
@ -27,6 +27,7 @@ class TestGroup : public QObject
|
||||
private Q_SLOTS:
|
||||
void testParenting();
|
||||
void testSignals();
|
||||
void testEntries();
|
||||
};
|
||||
|
||||
void TestGroup::testParenting()
|
||||
@ -100,6 +101,25 @@ void TestGroup::testSignals()
|
||||
QCOMPARE(spyAdded.count(), 1);
|
||||
QCOMPARE(spyAboutToRemove.count(), 1);
|
||||
QCOMPARE(spyRemoved.count(), 1);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestGroup::testEntries()
|
||||
{
|
||||
Group* group = new Group();
|
||||
|
||||
Entry* entry1 = new Entry();
|
||||
entry1->setGroup(group);
|
||||
|
||||
Entry* entry2 = new Entry();
|
||||
entry2->setGroup(group);
|
||||
|
||||
QCOMPARE(group->entries().size(), 2);
|
||||
QVERIFY(group->entries().at(0) == entry1);
|
||||
QVERIFY(group->entries().at(1) == entry2);
|
||||
|
||||
delete group;
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestGroup);
|
||||
|
Loading…
Reference in New Issue
Block a user