mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Update state syncer to account for new features
Update state syncer (class DatabaseWidgetStateSync) to account for new features: - properly sync view state when switching tabs - properly read/write view state from/to config Update classes EntryModel and EntryView to consistenly name list/search modes. Before, both classes defined list mode as 'group mode' and search mode as 'entry list mode', which differed from naming in other classes such as DatabaseWidget.
This commit is contained in:
parent
18be1a0254
commit
e3a5a22b84
@ -138,6 +138,13 @@ void Config::init(const QString& fileName)
|
||||
m_defaults.insert("GUI/DarkTrayIcon", false);
|
||||
m_defaults.insert("GUI/MinimizeToTray", false);
|
||||
m_defaults.insert("GUI/MinimizeOnClose", false);
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set defaults for state of 'Hide Usernames'/'Hide Passwords' settings
|
||||
* of entry view
|
||||
*/
|
||||
m_defaults.insert("GUI/EntryHideUsernames", false);
|
||||
m_defaults.insert("GUI/EntryHidePasswords", true);
|
||||
}
|
||||
|
||||
Config* Config::instance()
|
||||
|
@ -181,7 +181,13 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
||||
|
||||
connect(m_mainSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(mainSplitterSizesChanged()));
|
||||
connect(m_detailSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(detailSplitterSizesChanged()));
|
||||
connect(m_entryView->header(), SIGNAL(sectionResized(int,int,int)), SIGNAL(entryColumnSizesChanged()));
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Connect signal to pass through state changes of entry view view
|
||||
*/
|
||||
connect(m_entryView, SIGNAL(viewStateChanged()), SIGNAL(entryViewStateChanged()));
|
||||
|
||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(onGroupChanged(Group*)));
|
||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
|
||||
connect(m_entryView, SIGNAL(entryActivated(Entry*, EntryModel::ModelColumn)),
|
||||
@ -290,28 +296,58 @@ void DatabaseWidget::setDetailSplitterSizes(const QList<int> &sizes)
|
||||
m_detailSplitter->setSizes(sizes);
|
||||
}
|
||||
|
||||
QList<int> DatabaseWidget::entryHeaderViewSizes() const
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Get current state of entry view 'Hide Usernames' setting
|
||||
*/
|
||||
bool DatabaseWidget::entryViewHideUsernames() const
|
||||
{
|
||||
QList<int> sizes;
|
||||
|
||||
for (int i = 0; i < m_entryView->header()->count(); i++) {
|
||||
sizes.append(m_entryView->header()->sectionSize(i));
|
||||
}
|
||||
|
||||
return sizes;
|
||||
return m_entryView->hideUsernames();
|
||||
}
|
||||
|
||||
void DatabaseWidget::setEntryViewHeaderSizes(const QList<int>& sizes)
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set state of entry view 'Hide Usernames' setting
|
||||
*/
|
||||
void DatabaseWidget::setEntryViewHideUsernames(const bool hide)
|
||||
{
|
||||
const bool enoughSizes = sizes.size() == m_entryView->header()->count();
|
||||
Q_ASSERT(enoughSizes);
|
||||
if (!enoughSizes) {
|
||||
return;
|
||||
}
|
||||
m_entryView->setHideUsernames(hide);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizes.size(); i++) {
|
||||
m_entryView->header()->resizeSection(i, sizes[i]);
|
||||
}
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Get current state of entry view 'Hide Passwords' setting
|
||||
*/
|
||||
bool DatabaseWidget::entryViewHidePasswords() const
|
||||
{
|
||||
return m_entryView->hidePasswords();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set state of entry view 'Hide Passwords' setting
|
||||
*/
|
||||
void DatabaseWidget::setEntryViewHidePasswords(const bool hide)
|
||||
{
|
||||
m_entryView->setHidePasswords(hide);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Get current state of entry view view
|
||||
*/
|
||||
QByteArray DatabaseWidget::entryViewViewState() const
|
||||
{
|
||||
return m_entryView->viewState();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set state of entry view view
|
||||
*/
|
||||
bool DatabaseWidget::setEntryViewViewState(const QByteArray& state) const
|
||||
{
|
||||
return m_entryView->setViewState(state);
|
||||
}
|
||||
|
||||
void DatabaseWidget::clearAllWidgets()
|
||||
@ -1178,7 +1214,7 @@ bool DatabaseWidget::canDeleteCurrentGroup() const
|
||||
|
||||
bool DatabaseWidget::isInSearchMode() const
|
||||
{
|
||||
return m_entryView->inEntryListMode();
|
||||
return m_entryView->inSearchMode();
|
||||
}
|
||||
|
||||
Group* DatabaseWidget::currentGroup() const
|
||||
|
@ -92,8 +92,23 @@ public:
|
||||
void setMainSplitterSizes(const QList<int>& sizes);
|
||||
QList<int> detailSplitterSizes() const;
|
||||
void setDetailSplitterSizes(const QList<int>& sizes);
|
||||
QList<int> entryHeaderViewSizes() const;
|
||||
void setEntryViewHeaderSizes(const QList<int>& sizes);
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Methods to get/set state of entry view 'Hide Usernames'/'Hide
|
||||
* Passwords' settings
|
||||
*/
|
||||
bool entryViewHideUsernames() const;
|
||||
void setEntryViewHideUsernames(const bool hide);
|
||||
bool entryViewHidePasswords() const;
|
||||
void setEntryViewHidePasswords(const bool hide);
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Methods to get/set state of entry view view state
|
||||
*/
|
||||
QByteArray entryViewViewState() const;
|
||||
bool setEntryViewViewState(const QByteArray& state) const;
|
||||
|
||||
void clearAllWidgets();
|
||||
bool currentEntryHasTitle();
|
||||
bool currentEntryHasUsername();
|
||||
@ -127,7 +142,13 @@ signals:
|
||||
void searchModeActivated();
|
||||
void mainSplitterSizesChanged();
|
||||
void detailSplitterSizesChanged();
|
||||
void entryColumnSizesChanged();
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Signal to notify about state changes entry view view
|
||||
*/
|
||||
void entryViewStateChanged();
|
||||
|
||||
void updateSearch(QString text);
|
||||
|
||||
public slots:
|
||||
|
@ -27,16 +27,40 @@ DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
|
||||
{
|
||||
m_mainSplitterSizes = variantToIntList(config()->get("GUI/SplitterState"));
|
||||
m_detailSplitterSizes = variantToIntList(config()->get("GUI/DetailSplitterState"));
|
||||
m_columnSizesList = variantToIntList(config()->get("GUI/EntryListColumnSizes"));
|
||||
m_columnSizesSearch = variantToIntList(config()->get("GUI/EntrySearchColumnSizes"));
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Load state of entry view 'Hide Usernames'/'Hide Passwords' settings
|
||||
*/
|
||||
m_entryHideUsernames = config()->get("GUI/EntryHideUsernames").toBool();
|
||||
m_entryHidePasswords = config()->get("GUI/EntryHidePasswords").toBool();
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Load states of entry view list/search view
|
||||
*/
|
||||
m_entryListViewState = config()->get("GUI/EntryListViewState").toByteArray();
|
||||
m_entrySearchViewState = config()->get("GUI/EntrySearchViewState").toByteArray();
|
||||
}
|
||||
|
||||
DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
|
||||
{
|
||||
config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes));
|
||||
config()->set("GUI/DetailSplitterState", intListToVariant(m_detailSplitterSizes));
|
||||
config()->set("GUI/EntryListColumnSizes", intListToVariant(m_columnSizesList));
|
||||
config()->set("GUI/EntrySearchColumnSizes", intListToVariant(m_columnSizesSearch));
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Save state of entry view 'Hide Usernames'/'Hide Passwords' settings
|
||||
*/
|
||||
config()->set("GUI/EntryHideUsernames", m_entryHideUsernames);
|
||||
config()->set("GUI/EntryHidePasswords", m_entryHidePasswords);
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Save states of entry view list/search view
|
||||
*/
|
||||
config()->set("GUI/EntryListViewState", m_entryListViewState);
|
||||
config()->set("GUI/EntrySearchViewState", m_entrySearchViewState);
|
||||
}
|
||||
|
||||
void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
||||
@ -70,8 +94,14 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
||||
SLOT(updateSplitterSizes()));
|
||||
connect(m_activeDbWidget, SIGNAL(detailSplitterSizesChanged()),
|
||||
SLOT(updateSplitterSizes()));
|
||||
connect(m_activeDbWidget, SIGNAL(entryColumnSizesChanged()),
|
||||
SLOT(updateColumnSizes()));
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Connect signal to receive state changes of entry view view
|
||||
*/
|
||||
connect(m_activeDbWidget, SIGNAL(entryViewStateChanged()),
|
||||
SLOT(updateViewState()));
|
||||
|
||||
connect(m_activeDbWidget, SIGNAL(listModeActivated()),
|
||||
SLOT(restoreListView()));
|
||||
connect(m_activeDbWidget, SIGNAL(searchModeActivated()),
|
||||
@ -83,19 +113,59 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Restore entry view list view state
|
||||
*
|
||||
* NOTE:
|
||||
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are considered
|
||||
* 'global', i.e. they are the same for both list and search mode
|
||||
*
|
||||
* NOTE:
|
||||
* If m_entryListViewState is empty, it is the first time after clean/invalid
|
||||
* config that list view is activated. Thus, save its current state. Without
|
||||
* this, m_entryListViewState would remain empty until there is an actual view
|
||||
* state change (e.g. column is resized)
|
||||
*/
|
||||
void DatabaseWidgetStateSync::restoreListView()
|
||||
{
|
||||
if (!m_columnSizesList.isEmpty()) {
|
||||
m_activeDbWidget->setEntryViewHeaderSizes(m_columnSizesList);
|
||||
m_activeDbWidget->setEntryViewHideUsernames(m_entryHideUsernames);
|
||||
m_activeDbWidget->setEntryViewHidePasswords(m_entryHidePasswords);
|
||||
|
||||
if (!m_entryListViewState.isEmpty()) {
|
||||
m_activeDbWidget->setEntryViewViewState(m_entryListViewState);
|
||||
}
|
||||
else {
|
||||
m_entryListViewState = m_activeDbWidget->entryViewViewState();
|
||||
}
|
||||
|
||||
m_blockUpdates = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Restore entry view search view state
|
||||
*
|
||||
* NOTE:
|
||||
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are considered
|
||||
* 'global', i.e. they are the same for both list and search mode
|
||||
*
|
||||
* NOTE:
|
||||
* If m_entrySearchViewState is empty, it is the first time after clean/invalid
|
||||
* config that search view is activated. Thus, save its current state. Without
|
||||
* this, m_entrySearchViewState would remain empty until there is an actual view
|
||||
* state change (e.g. column is resized)
|
||||
*/
|
||||
void DatabaseWidgetStateSync::restoreSearchView()
|
||||
{
|
||||
if (!m_columnSizesSearch.isEmpty()) {
|
||||
m_activeDbWidget->setEntryViewHeaderSizes(m_columnSizesSearch);
|
||||
m_activeDbWidget->setEntryViewHideUsernames(m_entryHideUsernames);
|
||||
m_activeDbWidget->setEntryViewHidePasswords(m_entryHidePasswords);
|
||||
|
||||
if (!m_entrySearchViewState.isEmpty()) {
|
||||
m_activeDbWidget->setEntryViewViewState(m_entrySearchViewState);
|
||||
}
|
||||
else {
|
||||
m_entrySearchViewState = m_activeDbWidget->entryViewViewState();
|
||||
}
|
||||
|
||||
m_blockUpdates = false;
|
||||
@ -116,17 +186,26 @@ void DatabaseWidgetStateSync::updateSplitterSizes()
|
||||
m_detailSplitterSizes = m_activeDbWidget->detailSplitterSizes();
|
||||
}
|
||||
|
||||
void DatabaseWidgetStateSync::updateColumnSizes()
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Update entry view list/search view state (NOTE: states of entry view
|
||||
* 'Hide Usernames'/'Hide Passwords' settings are considered 'global',
|
||||
* i.e. they are the same for both list and search mode)
|
||||
*/
|
||||
void DatabaseWidgetStateSync::updateViewState()
|
||||
{
|
||||
if (m_blockUpdates) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_activeDbWidget->isGroupSelected()) {
|
||||
m_columnSizesList = m_activeDbWidget->entryHeaderViewSizes();
|
||||
m_entryHideUsernames = m_activeDbWidget->entryViewHideUsernames();
|
||||
m_entryHidePasswords = m_activeDbWidget->entryViewHidePasswords();
|
||||
|
||||
if (m_activeDbWidget->isInSearchMode()) {
|
||||
m_entrySearchViewState = m_activeDbWidget->entryViewViewState();
|
||||
}
|
||||
else {
|
||||
m_columnSizesSearch = m_activeDbWidget->entryHeaderViewSizes();
|
||||
m_entryListViewState = m_activeDbWidget->entryViewViewState();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,12 @@ public slots:
|
||||
private slots:
|
||||
void blockUpdates();
|
||||
void updateSplitterSizes();
|
||||
void updateColumnSizes();
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Slot to update entry view view state
|
||||
*/
|
||||
void updateViewState();
|
||||
|
||||
private:
|
||||
static QList<int> variantToIntList(const QVariant& variant);
|
||||
@ -48,8 +53,22 @@ private:
|
||||
bool m_blockUpdates;
|
||||
QList<int> m_mainSplitterSizes;
|
||||
QList<int> m_detailSplitterSizes;
|
||||
QList<int> m_columnSizesList;
|
||||
QList<int> m_columnSizesSearch;
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Properties to store state of entry view 'Hide Usernames'/'Hide
|
||||
* Passwords' settings
|
||||
*/
|
||||
bool m_entryHideUsernames;
|
||||
bool m_entryHidePasswords;
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Properties to store states of entry view list/search view (replaces
|
||||
* m_columnSizesList/m_columnSizesSearch)
|
||||
*/
|
||||
QByteArray m_entryListViewState;
|
||||
QByteArray m_entrySearchViewState;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_DATABASEWIDGETSTATESYNC_H
|
||||
|
@ -97,7 +97,7 @@ void EntryModel::setGroup(Group* group)
|
||||
makeConnections(group);
|
||||
|
||||
endResetModel();
|
||||
emit switchedToGroupMode();
|
||||
emit switchedToListMode();
|
||||
}
|
||||
|
||||
void EntryModel::setEntryList(const QList<Entry*>& entries)
|
||||
@ -134,7 +134,7 @@ void EntryModel::setEntryList(const QList<Entry*>& entries)
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
emit switchedToEntryListMode();
|
||||
emit switchedToSearchMode();
|
||||
}
|
||||
|
||||
int EntryModel::rowCount(const QModelIndex& parent) const
|
||||
|
@ -75,8 +75,13 @@ public:
|
||||
void setHidePasswords(const bool hide);
|
||||
|
||||
signals:
|
||||
void switchedToEntryListMode();
|
||||
void switchedToGroupMode();
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Signals to notify about list/search mode switches (NOTE: previously
|
||||
* named 'switchedToGroupMode'/'switchedToEntryListMode')
|
||||
*/
|
||||
void switchedToListMode();
|
||||
void switchedToSearchMode();
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
|
@ -43,7 +43,7 @@ EntryView::EntryView(QWidget* parent)
|
||||
: QTreeView(parent)
|
||||
, m_model(new EntryModel(this))
|
||||
, m_sortModel(new SortFilterHideProxyModel(this))
|
||||
, m_inEntryListMode(false)
|
||||
, m_inSearchMode(false)
|
||||
{
|
||||
m_sortModel->setSourceModel(m_model);
|
||||
m_sortModel->setDynamicSortFilter(true);
|
||||
@ -70,8 +70,20 @@ EntryView::EntryView(QWidget* parent)
|
||||
|
||||
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(emitEntryActivated(QModelIndex)));
|
||||
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SIGNAL(entrySelectionChanged()));
|
||||
connect(m_model, SIGNAL(switchedToEntryListMode()), SLOT(switchToEntryListMode()));
|
||||
connect(m_model, SIGNAL(switchedToGroupMode()), SLOT(switchToGroupMode()));
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Connect signals to get notified about list/search mode switches (NOTE:
|
||||
* previously named 'switch[ed]ToGroupMode'/'switch[ed]ToEntryListMode')
|
||||
*/
|
||||
connect(m_model, SIGNAL(switchedToListMode()), SLOT(switchToListMode()));
|
||||
connect(m_model, SIGNAL(switchedToSearchMode()), SLOT(switchToSearchMode()));
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Connect signals to notify about changes of view state when state of
|
||||
* 'Hide Usernames'/'Hide Passwords' settings changes in model
|
||||
*/
|
||||
connect(m_model, SIGNAL(hideUsernamesChanged()), SIGNAL(viewStateChanged()));
|
||||
connect(m_model, SIGNAL(hidePasswordsChanged()), SIGNAL(viewStateChanged()));
|
||||
|
||||
connect(this, SIGNAL(clicked(QModelIndex)), SLOT(emitEntryPressed(QModelIndex)));
|
||||
|
||||
@ -118,25 +130,51 @@ EntryView::EntryView(QWidget* parent)
|
||||
* - Disable stretching of last section (interferes with fitting columns
|
||||
* to window)
|
||||
* - Associate with context menu
|
||||
* - Connect signals to notify about changes of view state when state
|
||||
* of header changes
|
||||
*/
|
||||
header()->setDefaultSectionSize(100);
|
||||
header()->setStretchLastSection(false);
|
||||
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(header(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showHeaderMenu(QPoint)));
|
||||
connect(header(), SIGNAL(sectionCountChanged(int, int)), this, SIGNAL(viewStateChanged()));
|
||||
connect(header(), SIGNAL(sectionMoved(int, int, int)), this, SIGNAL(viewStateChanged()));
|
||||
connect(header(), SIGNAL(sectionResized(int, int, int)), this, SIGNAL(viewStateChanged()));
|
||||
connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SIGNAL(viewStateChanged()));
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Finalize setup by resetting view to defaults. Although not really
|
||||
* necessary at this point, it makes sense in order to avoid duplicating
|
||||
* code (sorting order, visibility of first column etc.)
|
||||
* Fit columns to window
|
||||
*
|
||||
* TODO:
|
||||
* Not working as expected, columns will end up being very small, most
|
||||
* likely due to EntryView not being sized properly at this time. Either
|
||||
* find a way to make this work by analizing when/where EntryView is
|
||||
* created or remove
|
||||
* likely due to EntryView not being sized properly at this time. Find
|
||||
* a way to make this work by analizing when/where EntryView is created
|
||||
*/
|
||||
//resetViewToDefaults();
|
||||
//fitColumnsToWindow();
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Configure default search view state and save for later use
|
||||
*/
|
||||
header()->showSection(EntryModel::ParentGroup);
|
||||
m_sortModel->sort(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||
sortByColumn(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||
m_defaultSearchViewState = header()->saveState();
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Configure default list view state and save for later use
|
||||
*
|
||||
* NOTE:
|
||||
* Default list view is intentionally configured last since this is the
|
||||
* view that's supposed to be active after initialization as m_inSearchMode
|
||||
* is initialized with 'false'
|
||||
*/
|
||||
header()->hideSection(EntryModel::ParentGroup);
|
||||
m_sortModel->sort(EntryModel::Title, Qt::AscendingOrder);
|
||||
sortByColumn(EntryModel::Title, Qt::AscendingOrder);
|
||||
m_defaultListViewState = header()->saveState();
|
||||
}
|
||||
|
||||
void EntryView::keyPressEvent(QKeyEvent* event)
|
||||
@ -175,9 +213,9 @@ void EntryView::setFirstEntryActive()
|
||||
}
|
||||
}
|
||||
|
||||
bool EntryView::inEntryListMode()
|
||||
bool EntryView::inSearchMode()
|
||||
{
|
||||
return m_inEntryListMode;
|
||||
return m_inSearchMode;
|
||||
}
|
||||
|
||||
void EntryView::emitEntryActivated(const QModelIndex& index)
|
||||
@ -230,53 +268,112 @@ Entry* EntryView::entryFromIndex(const QModelIndex& index)
|
||||
}
|
||||
}
|
||||
|
||||
void EntryView::switchToEntryListMode()
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Switch to list mode, i.e. list entries of group (NOTE: previously named
|
||||
* 'switchToGroupMode')
|
||||
*/
|
||||
void EntryView::switchToListMode()
|
||||
{
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Use header()->showSection() instead of m_sortModel->hideColumn() as
|
||||
* the latter messes up column indices, interfering with code relying on
|
||||
* proper indices
|
||||
*/
|
||||
header()->showSection(EntryModel::ParentGroup);
|
||||
if (header()->sectionSize(EntryModel::ParentGroup) == 0) {
|
||||
header()->resizeSection(EntryModel::ParentGroup, header()->defaultSectionSize());
|
||||
/* Check if already in this mode */
|
||||
if (!m_inSearchMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set sorting column and order (TODO: check what first two lines do, if
|
||||
* they are actually necessary, if indices are still correct and if indices
|
||||
* may be replaced by EntryModel::<column>)
|
||||
*/
|
||||
m_sortModel->sort(1, Qt::AscendingOrder);
|
||||
m_sortModel->sort(0, Qt::AscendingOrder);
|
||||
sortByColumn(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||
|
||||
m_inEntryListMode = true;
|
||||
}
|
||||
|
||||
void EntryView::switchToGroupMode()
|
||||
{
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Use header()->hideSection() instead of m_sortModel->hideColumn() as
|
||||
* the latter messes up column indices, interfering with code relying on
|
||||
* proper indices
|
||||
*/
|
||||
header()->hideSection(EntryModel::ParentGroup);
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set sorting column and order (TODO: check what first two lines do, if
|
||||
* they are actually necessary, if indices are still correct and if indices
|
||||
* may be replaced by EntryModel::<column>)
|
||||
*/
|
||||
m_sortModel->sort(-1, Qt::AscendingOrder);
|
||||
m_sortModel->sort(0, Qt::AscendingOrder);
|
||||
sortByColumn(EntryModel::Title, Qt::AscendingOrder);
|
||||
m_inSearchMode = false;
|
||||
}
|
||||
|
||||
m_inEntryListMode = false;
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Switch to search mode, i.e. list search results (NOTE: previously named
|
||||
* 'switchToEntryListMode')
|
||||
*/
|
||||
void EntryView::switchToSearchMode()
|
||||
{
|
||||
/* Check if already in this mode */
|
||||
if (m_inSearchMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use header()->showSection() instead of m_sortModel->hideColumn() as
|
||||
* the latter messes up column indices, interfering with code relying on
|
||||
* proper indices
|
||||
*/
|
||||
header()->showSection(EntryModel::ParentGroup);
|
||||
|
||||
/*
|
||||
* Always set sorting to column 'Group', as it does not feel right to have
|
||||
* the last known sort configuration of search view restored by 'Database
|
||||
* WidgetStateSync', which is what happens without this
|
||||
*/
|
||||
m_sortModel->sort(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||
sortByColumn(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||
|
||||
m_inSearchMode = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Get current state of 'Hide Usernames' setting (NOTE: just pass-through for
|
||||
* m_model)
|
||||
*/
|
||||
bool EntryView::hideUsernames() const
|
||||
{
|
||||
return m_model->hideUsernames();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set state of 'Hide Usernames' setting (NOTE: just pass-through for m_model)
|
||||
*/
|
||||
void EntryView::setHideUsernames(const bool hide)
|
||||
{
|
||||
m_model->setHideUsernames(hide);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Get current state of 'Hide Passwords' setting (NOTE: just pass-through for
|
||||
* m_model)
|
||||
*/
|
||||
bool EntryView::hidePasswords() const
|
||||
{
|
||||
return m_model->hidePasswords();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set state of 'Hide Passwords' setting (NOTE: just pass-through for m_model)
|
||||
*/
|
||||
void EntryView::setHidePasswords(const bool hide)
|
||||
{
|
||||
m_model->setHidePasswords(hide);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Get current state of view
|
||||
*/
|
||||
QByteArray EntryView::viewState() const
|
||||
{
|
||||
return header()->saveState();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Set state of entry view view
|
||||
*/
|
||||
bool EntryView::setViewState(const QByteArray& state) const
|
||||
{
|
||||
return header()->restoreState(state);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,10 +448,16 @@ void EntryView::toggleColumnVisibility(QAction *action)
|
||||
* its implementation MUST call the corresponding parent method using
|
||||
* 'QTreeView::resizeEvent(event)'. Without this, fitting to window will
|
||||
* be broken and/or work unreliably (stumbled upon during testing)
|
||||
*
|
||||
* NOTE:
|
||||
* Testing showed that it is absolutely necessary to emit signal 'viewState
|
||||
* Changed' here. Without this, an incomplete view state might get saved by
|
||||
* 'DatabaseWidgetStateSync' (e.g. only some columns resized)
|
||||
*/
|
||||
void EntryView::fitColumnsToWindow()
|
||||
{
|
||||
header()->resizeSections(QHeaderView::Stretch);
|
||||
emit viewStateChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -395,16 +498,17 @@ void EntryView::fitColumnsToContents()
|
||||
}
|
||||
header()->resizeSection(header()->logicalIndex(last), header()->sectionSize(last) + (header()->width() - width));
|
||||
}
|
||||
|
||||
/*
|
||||
* This should not be necessary due to use of header()->resizeSection,
|
||||
* but lets do it anyway for the sake of completeness
|
||||
*/
|
||||
emit viewStateChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Reset view to defaults
|
||||
*
|
||||
* NOTE:
|
||||
* header()->saveState()/restoreState() could also be used for this, but
|
||||
* testing showed that it complicates things more than it helps when trying
|
||||
* to account for current list mode
|
||||
*/
|
||||
void EntryView::resetViewToDefaults()
|
||||
{
|
||||
@ -412,19 +516,12 @@ void EntryView::resetViewToDefaults()
|
||||
m_model->setHideUsernames(false);
|
||||
m_model->setHidePasswords(true);
|
||||
|
||||
/* Reset visibility, size and position of all columns */
|
||||
for (int colidx = 0; colidx < header()->count(); colidx++) {
|
||||
header()->showSection(colidx);
|
||||
header()->resizeSection(colidx, header()->defaultSectionSize());
|
||||
header()->moveSection(header()->visualIndex(colidx), colidx);
|
||||
}
|
||||
|
||||
/* Reenter current list mode (affects first column and sorting) */
|
||||
if (m_inEntryListMode) {
|
||||
switchToEntryListMode();
|
||||
/* Reset columns (size, order, sorting etc.) */
|
||||
if (m_inSearchMode) {
|
||||
header()->restoreState(m_defaultSearchViewState);
|
||||
}
|
||||
else {
|
||||
switchToGroupMode();
|
||||
header()->restoreState(m_defaultListViewState);
|
||||
}
|
||||
|
||||
/* Nicely fitting columns to window feels like a sane default */
|
||||
|
@ -43,10 +43,27 @@ public:
|
||||
void setCurrentEntry(Entry* entry);
|
||||
Entry* entryFromIndex(const QModelIndex& index);
|
||||
void setEntryList(const QList<Entry*>& entries);
|
||||
bool inEntryListMode();
|
||||
bool inSearchMode();
|
||||
int numberOfSelectedEntries();
|
||||
void setFirstEntryActive();
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Methods to get/set state of 'Hide Usernames'/'Hide Passwords' settings
|
||||
* (NOTE: these are just pass-through methods to avoid exposing entry model)
|
||||
*/
|
||||
bool hideUsernames() const;
|
||||
void setHideUsernames(const bool hide);
|
||||
bool hidePasswords() const;
|
||||
void setHidePasswords(const bool hide);
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Methods to get/set state of view
|
||||
*/
|
||||
QByteArray viewState() const;
|
||||
bool setViewState(const QByteArray& state) const;
|
||||
|
||||
public slots:
|
||||
void setGroup(Group* group);
|
||||
|
||||
@ -54,6 +71,11 @@ signals:
|
||||
void entryActivated(Entry* entry, EntryModel::ModelColumn column);
|
||||
void entryPressed(Entry* entry);
|
||||
void entrySelectionChanged();
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Signal to notify about changes of view state
|
||||
*/
|
||||
void viewStateChanged();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
@ -61,8 +83,13 @@ protected:
|
||||
private slots:
|
||||
void emitEntryActivated(const QModelIndex& index);
|
||||
void emitEntryPressed(const QModelIndex& index);
|
||||
void switchToEntryListMode();
|
||||
void switchToGroupMode();
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Methods to switch to list/search mode (NOTE: previously named 'switch
|
||||
* ToGroupMode'/'switchToEntryListMode')
|
||||
*/
|
||||
void switchToListMode();
|
||||
void switchToSearchMode();
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
@ -77,8 +104,14 @@ private slots:
|
||||
private:
|
||||
EntryModel* const m_model;
|
||||
SortFilterHideProxyModel* const m_sortModel;
|
||||
bool m_inEntryListMode;
|
||||
bool m_inSearchMode;
|
||||
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Properties to store default view states used by resetViewToDefaults()
|
||||
*/
|
||||
QByteArray m_defaultListViewState;
|
||||
QByteArray m_defaultSearchViewState;
|
||||
/**
|
||||
* @author Fonic <https://github.com/fonic>
|
||||
* Properties to store header context menu and actions
|
||||
|
Loading…
Reference in New Issue
Block a user