From b5f5106fd008fc6ec27ca17d3c8d268e3e1c1143 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 30 Jun 2024 23:26:55 -0400 Subject: [PATCH] Reset splitter sizes on database unlock * Attempt to avoid issue with splitters not being appropriately calculated because the main window isn't sized yet. This can happen if the main window is hidden when the database is loaded and the splitter sizes are not recorded in the config file. --- src/gui/DatabaseWidget.cpp | 2 + src/gui/DatabaseWidget.h | 1 + src/gui/DatabaseWidgetStateSync.cpp | 108 ++++++++++++++-------------- src/gui/DatabaseWidgetStateSync.h | 7 +- 4 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index b497420b65..f49ed26e58 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -1273,6 +1273,7 @@ void DatabaseWidget::loadDatabase(bool accepted) } if (accepted) { + emit databaseAboutToUnlock(); replaceDatabase(openWidget->database()); switchToMainView(); processAutoOpen(); @@ -1429,6 +1430,7 @@ void DatabaseWidget::unlockDatabase(bool accepted) } } + emit databaseAboutToUnlock(); QSharedPointer db; if (senderDialog) { db = senderDialog->database(); diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 6622394e1a..c370e94c2c 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -134,6 +134,7 @@ class DatabaseWidget : public QStackedWidget void databaseModified(); void databaseNonDataChanged(); void databaseSaved(); + void databaseAboutToUnlock(); void databaseUnlocked(); void databaseLockRequested(); void databaseLocked(); diff --git a/src/gui/DatabaseWidgetStateSync.cpp b/src/gui/DatabaseWidgetStateSync.cpp index 44682469e0..31b71156c6 100644 --- a/src/gui/DatabaseWidgetStateSync.cpp +++ b/src/gui/DatabaseWidgetStateSync.cpp @@ -33,7 +33,9 @@ DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent) m_listViewState = config()->get(Config::GUI_ListViewState).toByteArray(); m_searchViewState = config()->get(Config::GUI_SearchViewState).toByteArray(); - connect(qApp, &QCoreApplication::aboutToQuit, this, &DatabaseWidgetStateSync::sync); + m_syncTimer.setSingleShot(true); + m_syncTimer.setInterval(100); + connect(&m_syncTimer, &QTimer::timeout, this, &DatabaseWidgetStateSync::sync); } DatabaseWidgetStateSync::~DatabaseWidgetStateSync() = default; @@ -43,6 +45,7 @@ DatabaseWidgetStateSync::~DatabaseWidgetStateSync() = default; */ void DatabaseWidgetStateSync::sync() { + m_syncTimer.stop(); config()->set(Config::GUI_SplitterState, intListToVariant(m_splitterSizes.value(Config::GUI_SplitterState))); config()->set(Config::GUI_PreviewSplitterState, intListToVariant(m_splitterSizes.value(Config::GUI_PreviewSplitterState))); @@ -56,79 +59,71 @@ void DatabaseWidgetStateSync::sync() void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget) { if (m_activeDbWidget) { + if (m_activeDbWidget->currentMode() != DatabaseWidget::Mode::LockedMode) { + // Update settings from previously active database if unlocked + updateAll(); + } disconnect(m_activeDbWidget, nullptr, this, nullptr); } m_activeDbWidget = dbWidget; if (m_activeDbWidget) { - // Give the database widget a chance to render itself before restoring the state - QTimer::singleShot(0, this, [this] { - if (!m_activeDbWidget) { - return; - } - - m_blockUpdates = true; - - m_activeDbWidget->setSplitterSizes(m_splitterSizes); - - if (m_activeDbWidget->isSearchActive()) { - restoreSearchView(); - } else { - restoreListView(); - } - - m_blockUpdates = false; - }); + if (m_activeDbWidget->currentMode() != DatabaseWidget::Mode::LockedMode) { + // Immediately apply settings to active database if already unlocked + applySplitterSizes(); + applyViewState(); + } + connect(m_activeDbWidget, SIGNAL(databaseAboutToUnlock()), SLOT(blockUpdates())); + connect(m_activeDbWidget, SIGNAL(databaseUnlocked()), SLOT(applySplitterSizes())); + connect(m_activeDbWidget, SIGNAL(databaseUnlocked()), SLOT(applyViewState())); + connect(m_activeDbWidget, &DatabaseWidget::databaseLocked, this, [this] { updateAll(true); }); connect(m_activeDbWidget, SIGNAL(splitterSizesChanged()), SLOT(updateSplitterSizes())); connect(m_activeDbWidget, SIGNAL(entryViewStateChanged()), SLOT(updateViewState())); - connect(m_activeDbWidget, SIGNAL(listModeActivated()), SLOT(restoreListView())); - connect(m_activeDbWidget, SIGNAL(searchModeActivated()), SLOT(restoreSearchView())); + connect(m_activeDbWidget, SIGNAL(listModeActivated()), SLOT(applyViewState())); + connect(m_activeDbWidget, SIGNAL(searchModeActivated()), SLOT(applyViewState())); connect(m_activeDbWidget, SIGNAL(listModeAboutToActivate()), SLOT(blockUpdates())); connect(m_activeDbWidget, SIGNAL(searchModeAboutToActivate()), SLOT(blockUpdates())); } } -/** - * Restore entry view list view state - * - * NOTE: - * States of entry view 'Hide Usernames'/'Hide Passwords' settings are global, - * i.e. they are the same for both list and search mode - * - * NOTE: - * If m_listViewState is empty, the list view has been activated for the first - * time after starting with a clean (or invalid) config. - */ -void DatabaseWidgetStateSync::restoreListView() +void DatabaseWidgetStateSync::applySplitterSizes() { - if (!m_listViewState.isEmpty()) { - m_activeDbWidget->setEntryViewState(m_listViewState); + if (!m_activeDbWidget) { + return; } + m_blockUpdates = true; + + m_activeDbWidget->setSplitterSizes(m_splitterSizes); + m_blockUpdates = false; } /** - * Restore entry view search view state - * - * NOTE: - * States of entry view 'Hide Usernames'/'Hide Passwords' settings are global, - * i.e. they are the same for both list and search mode + * Restore entry view list view state * * NOTE: - * If m_searchViewState is empty, the search view has been activated for the - * first time after starting with a clean (or invalid) config. Thus, save the - * current state. Without this, m_searchViewState would remain empty until - * there is an actual view state change (e.g. column is resized) + * If m_listViewState is empty, the list view has been activated for the first + * time after starting with a clean (or invalid) config. */ -void DatabaseWidgetStateSync::restoreSearchView() +void DatabaseWidgetStateSync::applyViewState() { - if (!m_searchViewState.isEmpty()) { - m_activeDbWidget->setEntryViewState(m_searchViewState); + if (!m_activeDbWidget) { + return; + } + + m_blockUpdates = true; + + if (m_activeDbWidget->isSearchActive()) { + if (!m_searchViewState.isEmpty()) { + m_activeDbWidget->setEntryViewState(m_searchViewState); + } } else { - m_searchViewState = m_activeDbWidget->entryViewState(); + if (!m_listViewState.isEmpty()) { + m_activeDbWidget->setEntryViewState(m_listViewState); + } } m_blockUpdates = false; @@ -139,19 +134,26 @@ void DatabaseWidgetStateSync::blockUpdates() m_blockUpdates = true; } +void DatabaseWidgetStateSync::updateAll(bool forceSync) +{ + updateSplitterSizes(); + updateViewState(); + if (forceSync) { + sync(); + } +} + + void DatabaseWidgetStateSync::updateSplitterSizes() { if (!m_blockUpdates) { m_splitterSizes = m_activeDbWidget->splitterSizes(); + m_syncTimer.start(); } } /** * Update entry view list/search view state - * - * NOTE: - * States of entry view 'Hide Usernames'/'Hide Passwords' settings are global, - * i.e. they are the same for both list and search mode */ void DatabaseWidgetStateSync::updateViewState() { @@ -165,7 +167,7 @@ void DatabaseWidgetStateSync::updateViewState() m_listViewState = m_activeDbWidget->entryViewState(); } - sync(); + m_syncTimer.start(); } QList DatabaseWidgetStateSync::variantToIntList(const QVariant& variant) diff --git a/src/gui/DatabaseWidgetStateSync.h b/src/gui/DatabaseWidgetStateSync.h index 8f8aef6dc8..b9e53fdc6b 100644 --- a/src/gui/DatabaseWidgetStateSync.h +++ b/src/gui/DatabaseWidgetStateSync.h @@ -32,13 +32,14 @@ class DatabaseWidgetStateSync : public QObject public slots: void setActive(DatabaseWidget* dbWidget); - void restoreListView(); - void restoreSearchView(); + void applySplitterSizes(); + void applyViewState(); private slots: void blockUpdates(); void updateSplitterSizes(); void updateViewState(); + void updateAll(bool forceSync = false); void sync(); private: @@ -48,6 +49,8 @@ private slots: QPointer m_activeDbWidget; bool m_blockUpdates; + QTimer m_syncTimer; + QHash> m_splitterSizes; QByteArray m_listViewState;