diff --git a/COPYING b/COPYING index a00aaf28c3..1fe3a06626 100644 --- a/COPYING +++ b/COPYING @@ -216,6 +216,7 @@ Files: share/icons/application/scalable/actions/application-exit.svg share/icons/application/scalable/actions/system-help.svg share/icons/application/scalable/actions/system-search.svg share/icons/application/scalable/actions/system-software-update.svg + share/icons/application/scalable/actions/sweep.svg share/icons/application/scalable/actions/tag.svg share/icons/application/scalable/actions/tag-multiple.svg share/icons/application/scalable/actions/tag-search.svg diff --git a/share/icons/application/scalable/actions/sweep.svg b/share/icons/application/scalable/actions/sweep.svg new file mode 100644 index 0000000000..e3c519562c --- /dev/null +++ b/share/icons/application/scalable/actions/sweep.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/share/icons/icons.qrc b/share/icons/icons.qrc index 3e82e172d5..72b3b2dc89 100644 --- a/share/icons/icons.qrc +++ b/share/icons/icons.qrc @@ -85,6 +85,7 @@ application/scalable/actions/system-help.svg application/scalable/actions/system-search.svg application/scalable/actions/system-software-update.svg + application/scalable/actions/sweep.svg application/scalable/actions/tag.svg application/scalable/actions/tag-multiple.svg application/scalable/actions/tag-search.svg diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index f974db170b..a46483df3a 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -6432,6 +6432,10 @@ Expect some bugs and minor issues, this version is meant for testing purposes. + + Clear the clipboard immediately + + ManageDatabase diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index d51588ac50..3ec0387c39 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -679,6 +679,7 @@ MainWindow::MainWindow() m_progressBarLabel = new QLabel(statusBar()); m_progressBarLabel->setVisible(false); statusBar()->addPermanentWidget(m_progressBarLabel); + m_progressBar = new QProgressBar(statusBar()); m_progressBar->setVisible(false); m_progressBar->setTextVisible(false); @@ -686,7 +687,17 @@ MainWindow::MainWindow() m_progressBar->setFixedHeight(15); m_progressBar->setMaximum(100); statusBar()->addPermanentWidget(m_progressBar); + + m_clearClipboardButton = new QToolButton(statusBar()); + m_clearClipboardButton->setIcon(icons()->icon("sweep")); + m_clearClipboardButton->setToolTip(tr("Clear the clipboard immediately")); + m_clearClipboardButton->setObjectName("clearClipboardButton"); + m_clearClipboardButton->setVisible(false); + m_clearClipboardButton->setStyleSheet("QToolButton { border: none; background-color: transparent; }"); + statusBar()->addPermanentWidget(m_clearClipboardButton); + connect(clipboard(), &Clipboard::updateCountdown, this, &MainWindow::updateProgressBar); + connect(m_clearClipboardButton.data(), &QToolButton::clicked, this, &MainWindow::clearClipboard); m_actionMultiplexer.connect(SIGNAL(updateSyncProgress(int, QString)), this, SLOT(updateProgressBar(int, QString))); m_actionMultiplexer.connect(SIGNAL(databaseSyncInProgress()), this, SLOT(disableMenuAndToolbar())); m_actionMultiplexer.connect(SIGNAL(databaseSyncCompleted(QString)), this, SLOT(enableMenuAndToolbar())); @@ -1535,6 +1546,11 @@ void MainWindow::clearSSHAgent() #endif } +void MainWindow::clearClipboard() +{ + clipboard()->clearCopiedText(); +} + void MainWindow::saveWindowInformation() { if (isVisible()) { @@ -1633,11 +1649,17 @@ void MainWindow::updateProgressBar(int percentage, QString message) if (percentage < 0) { m_progressBar->setVisible(false); m_progressBarLabel->setVisible(false); + m_clearClipboardButton->setVisible(false); } else { m_progressBar->setValue(percentage); m_progressBar->setVisible(true); m_progressBarLabel->setText(message); m_progressBarLabel->setVisible(true); + + Clipboard* cb = qobject_cast(sender()); + if (cb) { + m_clearClipboardButton->setVisible(true); + } } } diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 8effd06f43..2b38ea84ae 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "core/SignalMultiplexer.h" #include "gui/DatabaseWidget.h" @@ -155,6 +156,7 @@ private slots: void enableMenuAndToolbar(); void disableMenuAndToolbar(); void clearSSHAgent(); + void clearClipboard(); private: static const QString BaseWindowTitle; @@ -190,6 +192,7 @@ private slots: QPointer m_progressBar; QPointer m_progressBarLabel; QPointer m_statusBarLabel; + QPointer m_clearClipboardButton; Q_DISABLE_COPY(MainWindow) diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 96c8b0703d..da59fd01f6 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -2494,6 +2494,26 @@ void TestGui::addCannedEntries() QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); } +void TestGui::testClearClipboard() +{ + addCannedEntries(); + + EntryView* entryView = m_dbWidget->findChild("entryView"); + QVERIFY(entryView->isVisible()); + + QClipboard* clipboard = QApplication::clipboard(); + + clickIndex(entryView->model()->index(1, 1), entryView, Qt::LeftButton); + QTRY_VERIFY(entryView->hasFocus()); + QTest::keyClick(entryView, Qt::Key_C, Qt::ControlModifier); + QTRY_COMPARE(clipboard->text(), entryView->currentEntry()->password()); + + QToolButton* clearClipboardButton = m_mainWindow->findChild("clearClipboardButton"); + QTRY_VERIFY(clearClipboardButton->isVisible()); + clearClipboardButton->click(); + QCOMPARE(clipboard->text(), QString()); +} + void TestGui::checkDatabase(const QString& filePath, const QString& expectedDbName) { auto key = QSharedPointer::create(); diff --git a/tests/gui/TestGui.h b/tests/gui/TestGui.h index 514f7ce95b..f052bfa56f 100644 --- a/tests/gui/TestGui.h +++ b/tests/gui/TestGui.h @@ -71,6 +71,7 @@ private slots: void testTrayRestoreHide(); void testShortcutConfig(); void testMenuActionStates(); + void testClearClipboard(); private: void addCannedEntries();