Skip to content

Commit

Permalink
Reset splitter sizes on database unlock
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
droidmonkey committed Jul 28, 2024
1 parent e48ef80 commit b5f5106
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 55 deletions.
2 changes: 2 additions & 0 deletions src/gui/DatabaseWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,7 @@ void DatabaseWidget::loadDatabase(bool accepted)
}

if (accepted) {
emit databaseAboutToUnlock();
replaceDatabase(openWidget->database());
switchToMainView();
processAutoOpen();
Expand Down Expand Up @@ -1429,6 +1430,7 @@ void DatabaseWidget::unlockDatabase(bool accepted)
}
}

emit databaseAboutToUnlock();
QSharedPointer<Database> db;
if (senderDialog) {
db = senderDialog->database();
Expand Down
1 change: 1 addition & 0 deletions src/gui/DatabaseWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class DatabaseWidget : public QStackedWidget
void databaseModified();
void databaseNonDataChanged();
void databaseSaved();
void databaseAboutToUnlock();
void databaseUnlocked();
void databaseLockRequested();
void databaseLocked();
Expand Down
108 changes: 55 additions & 53 deletions src/gui/DatabaseWidgetStateSync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)));
Expand All @@ -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;
Expand All @@ -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()
{
Expand All @@ -165,7 +167,7 @@ void DatabaseWidgetStateSync::updateViewState()
m_listViewState = m_activeDbWidget->entryViewState();
}

sync();
m_syncTimer.start();
}

QList<int> DatabaseWidgetStateSync::variantToIntList(const QVariant& variant)
Expand Down
7 changes: 5 additions & 2 deletions src/gui/DatabaseWidgetStateSync.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -48,6 +49,8 @@ private slots:
QPointer<DatabaseWidget> m_activeDbWidget;

bool m_blockUpdates;
QTimer m_syncTimer;

QHash<Config::ConfigKey, QList<int>> m_splitterSizes;

QByteArray m_listViewState;
Expand Down

0 comments on commit b5f5106

Please sign in to comment.