diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c6625ae..67accc94 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,6 +79,7 @@ set(keepassx_SOURCES gui/LineEdit.cpp gui/MainWindow.cpp gui/SettingsWidget.cpp + gui/SortFilterHideProxyModel.cpp gui/WelcomeWidget.cpp gui/entry/AutoTypeAssociationsModel.cpp gui/entry/EditEntryWidget.cpp @@ -133,6 +134,7 @@ set(keepassx_MOC gui/LineEdit.h gui/MainWindow.h gui/SettingsWidget.h + gui/SortFilterHideProxyModel.h gui/WelcomeWidget.h gui/entry/AutoTypeAssociationsModel.h gui/entry/EditEntryWidget.h diff --git a/src/gui/SortFilterHideProxyModel.cpp b/src/gui/SortFilterHideProxyModel.cpp new file mode 100644 index 00000000..09023610 --- /dev/null +++ b/src/gui/SortFilterHideProxyModel.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Felix Geyer + * + * 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 . + */ + +#include "SortFilterHideProxyModel.h" + +SortFilterHideProxyModel::SortFilterHideProxyModel(QObject* parent) + : QSortFilterProxyModel(parent) +{ +} + +void SortFilterHideProxyModel::hideColumn(int column, bool hide) +{ + m_hiddenColumns.resize(column + 1); + m_hiddenColumns[column] = hide; + + invalidateFilter(); +} + +bool SortFilterHideProxyModel::filterAcceptsColumn(int sourceColumn, const QModelIndex& sourceParent) const +{ + Q_UNUSED(sourceParent); + + return sourceColumn >= m_hiddenColumns.size() || !m_hiddenColumns.at(sourceColumn); +} diff --git a/src/gui/SortFilterHideProxyModel.h b/src/gui/SortFilterHideProxyModel.h new file mode 100644 index 00000000..0b212dec --- /dev/null +++ b/src/gui/SortFilterHideProxyModel.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 Felix Geyer + * + * 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 . + */ + +#ifndef KEEPASSX_SORTFILTERHIDEPROXYMODEL_H +#define KEEPASSX_SORTFILTERHIDEPROXYMODEL_H + +#include +#include + +#include "core/Global.h" + +class SortFilterHideProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + explicit SortFilterHideProxyModel(QObject* parent = Q_NULLPTR); + void hideColumn(int column, bool hide); + +protected: + bool filterAcceptsColumn(int sourceColumn, const QModelIndex& sourceParent) const Q_DECL_OVERRIDE; + +private: + QBitArray m_hiddenColumns; +}; + +#endif // KEEPASSX_SORTFILTERHIDEPROXYMODEL_H diff --git a/src/gui/entry/EntryModel.cpp b/src/gui/entry/EntryModel.cpp index 3e1e4939..63a77ce0 100644 --- a/src/gui/entry/EntryModel.cpp +++ b/src/gui/entry/EntryModel.cpp @@ -41,7 +41,7 @@ QModelIndex EntryModel::indexFromEntry(Entry* entry) const { int row = m_entries.indexOf(entry); Q_ASSERT(row != -1); - return index(row, 0); + return index(row, 1); } void EntryModel::setGroup(Group* group) @@ -83,6 +83,7 @@ void EntryModel::setEntryList(const QList& entries) } Q_FOREACH (Database* db, databases) { + Q_ASSERT(db); m_allGroups.append(db->rootGroup()->groupsRecursive(true)); } diff --git a/src/gui/entry/EntryView.cpp b/src/gui/entry/EntryView.cpp index 5d21ed7e..2ce11486 100644 --- a/src/gui/entry/EntryView.cpp +++ b/src/gui/entry/EntryView.cpp @@ -17,14 +17,13 @@ #include "EntryView.h" -#include - +#include "gui/SortFilterHideProxyModel.h" #include "gui/entry/EntryModel.h" EntryView::EntryView(QWidget* parent) : QTreeView(parent) , m_model(new EntryModel(this)) - , m_sortModel(new QSortFilterProxyModel(this)) + , m_sortModel(new SortFilterHideProxyModel(this)) , m_inEntryListMode(false) { m_sortModel->setSourceModel(m_model); @@ -45,8 +44,6 @@ EntryView::EntryView(QWidget* parent) connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SIGNAL(entrySelectionChanged())); connect(m_model, SIGNAL(switchedToEntryListMode()), SLOT(switchToEntryListMode())); connect(m_model, SIGNAL(switchedToGroupMode()), SLOT(switchToGroupMode())); - - sortByColumn(0, Qt::AscendingOrder); } void EntryView::setGroup(Group* group) @@ -110,15 +107,15 @@ Entry* EntryView::entryFromIndex(const QModelIndex& index) void EntryView::switchToEntryListMode() { + m_sortModel->hideColumn(0, false); sortByColumn(1, Qt::AscendingOrder); // TODO: should probably be improved sortByColumn(0, Qt::AscendingOrder); - showColumn(0); m_inEntryListMode = true; } void EntryView::switchToGroupMode() { - sortByColumn(1, Qt::AscendingOrder); - hideColumn(0); + m_sortModel->hideColumn(0, true); + sortByColumn(0, Qt::AscendingOrder); m_inEntryListMode = false; } diff --git a/src/gui/entry/EntryView.h b/src/gui/entry/EntryView.h index 5096b1fa..125a4b85 100644 --- a/src/gui/entry/EntryView.h +++ b/src/gui/entry/EntryView.h @@ -25,7 +25,7 @@ class Entry; class EntryModel; class Group; -class QSortFilterProxyModel; +class SortFilterHideProxyModel; class EntryView : public QTreeView { @@ -55,7 +55,7 @@ private Q_SLOTS: private: EntryModel* const m_model; - QSortFilterProxyModel* const m_sortModel; + SortFilterHideProxyModel* const m_sortModel; bool m_inEntryListMode; }; diff --git a/tests/TestEntryModel.cpp b/tests/TestEntryModel.cpp index 3791e993..32cd7a69 100644 --- a/tests/TestEntryModel.cpp +++ b/tests/TestEntryModel.cpp @@ -27,6 +27,7 @@ #include "core/Group.h" #include "crypto/Crypto.h" #include "gui/IconModels.h" +#include "gui/SortFilterHideProxyModel.h" #include "gui/entry/AutoTypeAssociationsModel.h" #include "gui/entry/EntryModel.h" #include "gui/entry/EntryAttachmentsModel.h" @@ -264,4 +265,50 @@ void TestEntryModel::testAutoTypeAssociationsModel() delete assocications; } +void TestEntryModel::testProxyModel() +{ + EntryModel* modelSource = new EntryModel(this); + SortFilterHideProxyModel* modelProxy = new SortFilterHideProxyModel(this); + modelProxy->setSourceModel(modelSource); + + ModelTest* modelTest = new ModelTest(modelProxy, this); + + Database* db = new Database(); + Entry* entry = new Entry(); + entry->setTitle("Test Title"); + entry->setGroup(db->rootGroup()); + + modelSource->setGroup(db->rootGroup()); + + QSignalSpy spyColumnRemove(modelProxy, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int))); + modelProxy->hideColumn(0, true); + QCOMPARE(modelProxy->columnCount(), 3); + QVERIFY(spyColumnRemove.size() >= 1); + + int oldSpyColumnRemoveSize = spyColumnRemove.size(); + modelProxy->hideColumn(0, true); + QCOMPARE(spyColumnRemove.size(), oldSpyColumnRemoveSize); + + modelProxy->hideColumn(100, true); + QCOMPARE(spyColumnRemove.size(), oldSpyColumnRemoveSize); + + QList entryList; + entryList << entry; + modelSource->setEntryList(entryList); + + QSignalSpy spyColumnInsert(modelProxy, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int))); + modelProxy->hideColumn(0, false); + QCOMPARE(modelProxy->columnCount(), 4); + QVERIFY(spyColumnInsert.size() >= 1); + + int oldSpyColumnInsertSize = spyColumnInsert.size(); + modelProxy->hideColumn(0, false); + QCOMPARE(spyColumnInsert.size(), oldSpyColumnInsertSize); + + delete modelTest; + delete modelProxy; + delete modelSource; + delete db; +} + KEEPASSX_QTEST_CORE_MAIN(TestEntryModel) diff --git a/tests/TestEntryModel.h b/tests/TestEntryModel.h index 0cac18c3..3d37f6b6 100644 --- a/tests/TestEntryModel.h +++ b/tests/TestEntryModel.h @@ -32,6 +32,7 @@ private Q_SLOTS: void testDefaultIconModel(); void testCustomIconModel(); void testAutoTypeAssociationsModel(); + void testProxyModel(); }; #endif // KEEPASSX_TESTENTRYMODEL_H