From 4b1258f5851c12e2fbe7991fff794a8e78237656 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 7 Apr 2019 09:56:25 -0400 Subject: [PATCH] Correct issues with apply button * Don't show apply button when creating new entries or groups (Fix #2191) * Don't mark entry/group as dirty when first creating a new one (prevents unnecessary discard dialog on cancel) * Properly enable/disable apply button when changes are made to entries and groups * Don't show discard change warning when locking database unless their are actual changes made NOTE: Extra pages in the group edit widget are not watched for changes yet. Requires a major refactor. --- src/gui/DatabaseWidget.cpp | 11 ++- src/gui/EditWidget.cpp | 37 ++++++++- src/gui/EditWidget.h | 5 ++ src/gui/entry/EditEntryWidget.cpp | 121 ++++++++++++------------------ src/gui/entry/EditEntryWidget.h | 3 - src/gui/group/EditGroupWidget.cpp | 45 +++++++++++ src/gui/group/EditGroupWidget.h | 1 + tests/gui/TestGui.cpp | 21 ++++-- 8 files changed, 155 insertions(+), 89 deletions(-) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index abf8fcf73..97fdeb0f9 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -261,12 +261,11 @@ bool DatabaseWidget::isSearchActive() const bool DatabaseWidget::isEditWidgetModified() const { if (currentWidget() == m_editEntryWidget) { - return m_editEntryWidget->hasBeenModified(); - } else { - // other edit widget don't have a hasBeenModified() method yet - // assume that they already have been modified - return true; + return m_editEntryWidget->isModified(); + } else if (currentWidget() == m_editGroupWidget) { + return m_editGroupWidget->isModified(); } + return false; } QList DatabaseWidget::mainSplitterSizes() const @@ -1249,7 +1248,7 @@ bool DatabaseWidget::lock() clipboard()->clearCopiedText(); - if (currentMode() == DatabaseWidget::Mode::EditMode) { + if (isEditWidgetModified()) { auto result = MessageBox::question(this, tr("Lock Database?"), tr("You are editing an entry. Discard changes and lock anyway?"), diff --git a/src/gui/EditWidget.cpp b/src/gui/EditWidget.cpp index be7ea01df..f7030c9d7 100644 --- a/src/gui/EditWidget.cpp +++ b/src/gui/EditWidget.cpp @@ -30,6 +30,7 @@ EditWidget::EditWidget(QWidget* parent) { m_ui->setupUi(this); setReadOnly(false); + setModified(false); m_ui->messageWidget->setHidden(true); @@ -43,6 +44,7 @@ EditWidget::EditWidget(QWidget* parent) connect(m_ui->buttonBox, SIGNAL(accepted()), SIGNAL(accepted())); connect(m_ui->buttonBox, SIGNAL(rejected()), SIGNAL(rejected())); + connect(m_ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), SLOT(buttonClicked(QAbstractButton*))); } EditWidget::~EditWidget() @@ -106,9 +108,6 @@ void EditWidget::setReadOnly(bool readOnly) m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Close); } else { m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply); - // Find and connect the apply button - QPushButton* applyButton = m_ui->buttonBox->button(QDialogButtonBox::Apply); - connect(applyButton, SIGNAL(clicked()), SIGNAL(apply())); } } @@ -117,6 +116,17 @@ bool EditWidget::readOnly() const return m_readOnly; } +void EditWidget::setModified(bool state) +{ + m_modified = state; + enableApplyButton(state); +} + +bool EditWidget::isModified() const +{ + return m_modified; +} + void EditWidget::enableApplyButton(bool enabled) { QPushButton* applyButton = m_ui->buttonBox->button(QDialogButtonBox::Apply); @@ -125,6 +135,27 @@ void EditWidget::enableApplyButton(bool enabled) } } +void EditWidget::showApplyButton(bool state) +{ + if (!m_readOnly) { + auto buttons = m_ui->buttonBox->standardButtons(); + if (state) { + buttons |= QDialogButtonBox::Apply; + } else { + buttons &= ~QDialogButtonBox::Apply; + } + m_ui->buttonBox->setStandardButtons(buttons); + } +} + +void EditWidget::buttonClicked(QAbstractButton* button) +{ + auto stdButton = m_ui->buttonBox->standardButton(button); + if (stdButton == QDialogButtonBox::Apply) { + emit apply(); + } +} + void EditWidget::showMessage(const QString& text, MessageWidget::MessageType type) { // Show error messages for a longer time to make sure the user can read them diff --git a/src/gui/EditWidget.h b/src/gui/EditWidget.h index f0d157c49..361961f76 100644 --- a/src/gui/EditWidget.h +++ b/src/gui/EditWidget.h @@ -49,6 +49,8 @@ public: void setReadOnly(bool readOnly); bool readOnly() const; void enableApplyButton(bool enabled); + void showApplyButton(bool state); + virtual bool isModified() const; signals: void apply(); @@ -58,10 +60,13 @@ signals: protected slots: void showMessage(const QString& text, MessageWidget::MessageType type); void hideMessage(); + void setModified(bool state = true); + void buttonClicked(QAbstractButton* button); private: const QScopedPointer m_ui; bool m_readOnly; + bool m_modified; Q_DISABLE_COPY(EditWidget) }; diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 74a1fcd36..508f3c68c 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -276,55 +276,54 @@ void EditEntryWidget::setupHistory() void EditEntryWidget::setupEntryUpdate() { // Entry tab - connect(m_mainUi->titleEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->usernameEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->passwordEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->passwordRepeatEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); + connect(m_mainUi->titleEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_mainUi->usernameEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_mainUi->passwordEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_mainUi->passwordRepeatEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); #ifdef WITH_XC_NETWORKING connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), this, SLOT(updateFaviconButtonEnable(QString))); #endif - connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->notesEnabled, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->expireDatePicker, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->notesEdit, SIGNAL(textChanged()), this, SLOT(setUnsavedChanges())); + connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_mainUi->notesEnabled, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_mainUi->expireDatePicker, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(setModified())); + connect(m_mainUi->notesEdit, SIGNAL(textChanged()), this, SLOT(setModified())); // Advanced tab - connect(m_advancedUi->attributesEdit, SIGNAL(textChanged()), this, SLOT(setUnsavedChanges())); - connect(m_advancedUi->protectAttributeButton, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_advancedUi->fgColorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_advancedUi->bgColorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_advancedUi->attachmentsWidget, SIGNAL(widgetUpdated()), this, SLOT(setUnsavedChanges())); + connect(m_advancedUi->attributesEdit, SIGNAL(textChanged()), this, SLOT(setModified())); + connect(m_advancedUi->protectAttributeButton, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_advancedUi->fgColorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_advancedUi->bgColorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_advancedUi->attachmentsWidget, SIGNAL(widgetUpdated()), this, SLOT(setModified())); // Icon tab - connect(m_iconsWidget, SIGNAL(widgetUpdated()), this, SLOT(setUnsavedChanges())); + connect(m_iconsWidget, SIGNAL(widgetUpdated()), this, SLOT(setModified())); // Auto-Type tab - connect(m_autoTypeUi->enableButton, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->customWindowSequenceButton, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->inheritSequenceButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->customSequenceButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->windowSequenceEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->sequenceEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->windowTitleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->windowTitleCombo, SIGNAL(editTextChanged(QString)), this, SLOT(setUnsavedChanges())); + connect(m_autoTypeUi->enableButton, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_autoTypeUi->customWindowSequenceButton, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_autoTypeUi->inheritSequenceButton, SIGNAL(toggled(bool)), this, SLOT(setModified())); + connect(m_autoTypeUi->customSequenceButton, SIGNAL(toggled(bool)), this, SLOT(setModified())); + connect(m_autoTypeUi->windowSequenceEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_autoTypeUi->sequenceEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_autoTypeUi->windowTitleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setModified())); + connect(m_autoTypeUi->windowTitleCombo, SIGNAL(editTextChanged(QString)), this, SLOT(setModified())); // Properties and History tabs don't need extra connections #ifdef WITH_XC_SSHAGENT // SSH Agent tab if (config()->get("SSHAgent", false).toBool()) { - connect(m_sshAgentUi->attachmentRadioButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->externalFileRadioButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->attachmentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->attachmentComboBox, SIGNAL(editTextChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->externalFileEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->addKeyToAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->removeKeyFromAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect( - m_sshAgentUi->requireUserConfirmationCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->lifetimeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->lifetimeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setUnsavedChanges())); + connect(m_sshAgentUi->attachmentRadioButton, SIGNAL(toggled(bool)), this, SLOT(setModified())); + connect(m_sshAgentUi->externalFileRadioButton, SIGNAL(toggled(bool)), this, SLOT(setModified())); + connect(m_sshAgentUi->attachmentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->attachmentComboBox, SIGNAL(editTextChanged(QString)), this, SLOT(setModified())); + connect(m_sshAgentUi->externalFileEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_sshAgentUi->addKeyToAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->removeKeyFromAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->requireUserConfirmationCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->lifetimeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->lifetimeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setModified())); } #endif } @@ -703,8 +702,10 @@ void EditEntryWidget::loadEntry(Entry* entry, setCurrentPage(0); setPageHidden(m_historyWidget, m_history || m_entry->historyItems().count() < 1); - // Force the user to Save/Apply/Discard new entries - setUnsavedChanges(m_create); + // Force the user to Save/Discard new entries + showApplyButton(!m_create); + + setModified(false); } void EditEntryWidget::setForms(Entry* entry, bool restore) @@ -881,7 +882,6 @@ bool EditEntryWidget::commitEntry() } updateEntryData(m_entry); - setUnsavedChanges(false); if (!m_create) { m_entry->endUpdate(); @@ -896,6 +896,7 @@ bool EditEntryWidget::commitEntry() m_historyModel->setEntries(m_entry->historyItems()); showMessage(tr("Entry updated successfully."), MessageWidget::Positive); + setModified(false); return true; } @@ -968,7 +969,7 @@ void EditEntryWidget::cancel() m_entry->setIcon(Entry::DefaultIconNumber); } - if (!m_saved) { + if (isModified()) { auto result = MessageBox::question(this, QString(), tr("Entry has unsaved changes"), @@ -980,13 +981,13 @@ void EditEntryWidget::cancel() } if (result == MessageBox::Save) { commitEntry(); - m_saved = true; + setModified(false); } } clear(); - emit editFinished(m_saved); + emit editFinished(!isModified()); } void EditEntryWidget::clear() @@ -1008,22 +1009,6 @@ void EditEntryWidget::clear() hideMessage(); } -bool EditEntryWidget::hasBeenModified() const -{ - // entry has been modified if a history item is to be deleted - if (!m_historyModel->deletedEntries().isEmpty()) { - return true; - } - - // check if updating the entry would modify it - auto* entry = new Entry(); - entry->copyDataFrom(m_entry.data()); - - entry->beginUpdate(); - updateEntryData(entry); - return entry->endUpdate(); -} - void EditEntryWidget::togglePasswordGeneratorButton(bool checked) { if (checked) { @@ -1070,7 +1055,7 @@ void EditEntryWidget::insertAttribute() m_advancedUi->attributesView->setCurrentIndex(index); m_advancedUi->attributesView->edit(index); - setUnsavedChanges(true); + setModified(true); } void EditEntryWidget::editCurrentAttribute() @@ -1081,7 +1066,7 @@ void EditEntryWidget::editCurrentAttribute() if (index.isValid()) { m_advancedUi->attributesView->edit(index); - setUnsavedChanges(true); + setModified(true); } } @@ -1101,7 +1086,7 @@ void EditEntryWidget::removeCurrentAttribute() if (result == MessageBox::Remove) { m_entryAttributes->remove(m_attributesModel->keyByIndex(index)); - setUnsavedChanges(true); + setModified(true); } } } @@ -1223,7 +1208,7 @@ void EditEntryWidget::insertAutoTypeAssoc() m_autoTypeUi->assocView->setCurrentIndex(newIndex); loadCurrentAssoc(newIndex); m_autoTypeUi->windowTitleCombo->setFocus(); - setUnsavedChanges(true); + setModified(true); } void EditEntryWidget::removeAutoTypeAssoc() @@ -1232,7 +1217,7 @@ void EditEntryWidget::removeAutoTypeAssoc() if (currentIndex.isValid()) { m_autoTypeAssoc->remove(currentIndex.row()); - setUnsavedChanges(true); + setModified(true); } } @@ -1295,7 +1280,7 @@ void EditEntryWidget::restoreHistoryEntry() QModelIndex index = m_sortModel->mapToSource(m_historyUi->historyView->currentIndex()); if (index.isValid()) { setForms(m_historyModel->entryFromIndex(index), true); - setUnsavedChanges(true); + setModified(true); } } @@ -1309,7 +1294,7 @@ void EditEntryWidget::deleteHistoryEntry() } else { m_historyUi->deleteAllButton->setEnabled(false); } - setUnsavedChanges(true); + setModified(true); } } @@ -1317,7 +1302,7 @@ void EditEntryWidget::deleteAllHistoryEntries() { m_historyModel->deleteAll(); m_historyUi->deleteAllButton->setEnabled(m_historyModel->rowCount() > 0); - setUnsavedChanges(true); + setModified(true); } QMenu* EditEntryWidget::createPresetsMenu() @@ -1370,12 +1355,6 @@ void EditEntryWidget::pickColor() QColor newColor = QColorDialog::getColor(oldColor); if (newColor.isValid()) { setupColorButton(isForeground, newColor); - setUnsavedChanges(true); + setModified(true); } } - -void EditEntryWidget::setUnsavedChanges(bool hasUnsaved) -{ - m_saved = !hasUnsaved; - enableApplyButton(hasUnsaved); -} diff --git a/src/gui/entry/EditEntryWidget.h b/src/gui/entry/EditEntryWidget.h index 4c6870594..aea3c894b 100644 --- a/src/gui/entry/EditEntryWidget.h +++ b/src/gui/entry/EditEntryWidget.h @@ -68,7 +68,6 @@ public: QString entryTitle() const; void clear(); - bool hasBeenModified() const; signals: void editFinished(bool accepted); @@ -106,7 +105,6 @@ private slots: void useExpiryPreset(QAction* action); void toggleHideNotes(bool visible); void pickColor(); - void setUnsavedChanges(bool hasUnsaved = true); #ifdef WITH_XC_SSHAGENT void updateSSHAgent(); void updateSSHAgentAttachment(); @@ -148,7 +146,6 @@ private: bool m_create; bool m_history; - bool m_saved; #ifdef WITH_XC_SSHAGENT bool m_sshAgentEnabled; KeeAgentSettings m_sshAgentSettings; diff --git a/src/gui/group/EditGroupWidget.cpp b/src/gui/group/EditGroupWidget.cpp index 6c869cf28..fe83a943e 100644 --- a/src/gui/group/EditGroupWidget.cpp +++ b/src/gui/group/EditGroupWidget.cpp @@ -22,6 +22,7 @@ #include "core/Metadata.h" #include "gui/EditWidgetIcons.h" #include "gui/EditWidgetProperties.h" +#include "gui/MessageBox.h" #if defined(WITH_XC_KEESHARE) #include "keeshare/group/EditGroupPageKeeShare.h" @@ -46,6 +47,11 @@ public: editPage->assign(widget); } + QWidget* getWidget() + { + return widget; + } + private: QSharedPointer editPage; QWidget* widget; @@ -85,18 +91,38 @@ EditGroupWidget::EditGroupWidget(QWidget* parent) // clang-format on connect(m_editGroupWidgetIcons, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage())); + + setupModifiedTracking(); } EditGroupWidget::~EditGroupWidget() { } +void EditGroupWidget::setupModifiedTracking() +{ + // Group tab + connect(m_mainUi->editName, SIGNAL(textChanged(QString)), SLOT(setModified())); + connect(m_mainUi->editNotes, SIGNAL(textChanged()), SLOT(setModified())); + connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), SLOT(setModified())); + connect(m_mainUi->expireDatePicker, SIGNAL(dateTimeChanged(QDateTime)), SLOT(setModified())); + connect(m_mainUi->searchComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setModified())); + connect(m_mainUi->autotypeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setModified())); + connect(m_mainUi->autoTypeSequenceInherit, SIGNAL(toggled(bool)), SLOT(setModified())); + connect(m_mainUi->autoTypeSequenceCustomRadio, SIGNAL(toggled(bool)), SLOT(setModified())); + connect(m_mainUi->autoTypeSequenceCustomEdit, SIGNAL(textChanged(QString)), SLOT(setModified())); + + // Icon tab + connect(m_editGroupWidgetIcons, SIGNAL(widgetUpdated()), SLOT(setModified())); +} + void EditGroupWidget::loadGroup(Group* group, bool create, const QSharedPointer& database) { m_group = group; m_db = database; m_temporaryGroup.reset(group->clone(Entry::CloneNoFlags, Group::CloneNoFlags)); + connect(m_temporaryGroup->customData(), SIGNAL(customDataModified()), SLOT(setModified())); if (create) { setHeadline(tr("Add group")); @@ -139,6 +165,11 @@ void EditGroupWidget::loadGroup(Group* group, bool create, const QSharedPointer< setCurrentPage(0); m_mainUi->editName->setFocus(); + + // Force the user to Save/Discard new groups + showApplyButton(!create); + + setModified(false); } void EditGroupWidget::save() @@ -180,6 +211,8 @@ void EditGroupWidget::apply() // Icons add/remove are applied globally outside the transaction! m_group->copyDataFrom(m_temporaryGroup.data()); + + setModified(false); } void EditGroupWidget::cancel() @@ -188,6 +221,18 @@ void EditGroupWidget::cancel() m_group->setIcon(Entry::DefaultIconNumber); } + if (isModified()) { + auto result = MessageBox::question(this, + QString(), + tr("Entry has unsaved changes"), + MessageBox::Cancel | MessageBox::Save | MessageBox::Discard, + MessageBox::Cancel); + if (result == MessageBox::Save) { + apply(); + setModified(false); + } + } + clear(); emit editFinished(false); } diff --git a/src/gui/group/EditGroupWidget.h b/src/gui/group/EditGroupWidget.h index fd744503c..cc8738d8c 100644 --- a/src/gui/group/EditGroupWidget.h +++ b/src/gui/group/EditGroupWidget.h @@ -74,6 +74,7 @@ private: void addTriStateItems(QComboBox* comboBox, bool inheritValue); int indexFromTriState(Group::TriState triState); Group::TriState triStateFromIndex(int index); + void setupModifiedTracking(); const QScopedPointer m_mainUi; diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 7d907dc95..63e36fbaa 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -429,13 +429,20 @@ void TestGui::testEditEntry() auto* titleEdit = editEntryWidget->findChild("titleEdit"); QTest::keyClicks(titleEdit, "_test"); - // Apply the edit auto* editEntryWidgetButtonBox = editEntryWidget->findChild("buttonBox"); QVERIFY(editEntryWidgetButtonBox); - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton); + auto* okButton = editEntryWidgetButtonBox->button(QDialogButtonBox::Ok); + QVERIFY(okButton); + auto* applyButton = editEntryWidgetButtonBox->button(QDialogButtonBox::Apply); + QVERIFY(applyButton); + + // Apply the edit + QTRY_VERIFY(applyButton->isEnabled()); + QTest::mouseClick(applyButton, Qt::LeftButton); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); QCOMPARE(entry->title(), QString("Sample Entry_test")); QCOMPARE(entry->historyItems().size(), ++editCount); + QVERIFY(!applyButton->isEnabled()); // Test entry colors (simulate choosing a color) editEntryWidget->setCurrentPage(1); @@ -451,7 +458,7 @@ void TestGui::testEditEntry() colorCheckBox = editEntryWidget->findChild("bgColorCheckBox"); colorButton->setProperty("color", bgColor); colorCheckBox->setChecked(true); - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton); + QTest::mouseClick(applyButton, Qt::LeftButton); QCOMPARE(entry->historyItems().size(), ++editCount); // Test protected attributes @@ -471,7 +478,7 @@ void TestGui::testEditEntry() auto* passwordEdit = editEntryWidget->findChild("passwordEdit"); QString originalPassword = passwordEdit->text(); passwordEdit->setText("newpass"); - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + QTest::mouseClick(okButton, Qt::LeftButton); auto* messageWiget = editEntryWidget->findChild("messageWidget"); QTRY_VERIFY(messageWiget->isVisible()); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); @@ -479,7 +486,7 @@ void TestGui::testEditEntry() passwordEdit->setText(originalPassword); // Save the edit (press OK) - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + QTest::mouseClick(okButton, Qt::LeftButton); QApplication::processEvents(); // Confirm edit was made @@ -496,13 +503,15 @@ void TestGui::testEditEntry() // Test copy & paste newline sanitization QTest::mouseClick(entryEditWidget, Qt::LeftButton); + okButton = editEntryWidgetButtonBox->button(QDialogButtonBox::Ok); + QVERIFY(okButton); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); titleEdit->setText("multiline\ntitle"); editEntryWidget->findChild("usernameEdit")->setText("multiline\nusername"); editEntryWidget->findChild("passwordEdit")->setText("multiline\npassword"); editEntryWidget->findChild("passwordRepeatEdit")->setText("multiline\npassword"); editEntryWidget->findChild("urlEdit")->setText("multiline\nurl"); - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + QTest::mouseClick(okButton, Qt::LeftButton); QCOMPARE(entry->title(), QString("multiline title")); QCOMPARE(entry->username(), QString("multiline username"));