Show countdown for clipboard clearing (#6333)

* Closes #1843

Co-authored-by: Jonathan White <support@dmapps.us>
This commit is contained in:
ByteHamster 2021-04-01 05:12:59 +02:00 committed by GitHub
parent 8c9530e3ec
commit 439c155552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 67 additions and 14 deletions

View File

@ -39,8 +39,7 @@ Clipboard::Clipboard(QObject* parent)
m_pasteboard = new MacPasteboard(); m_pasteboard = new MacPasteboard();
} }
#endif #endif
m_timer->setSingleShot(true); connect(m_timer, SIGNAL(timeout()), SLOT(countdownTick()));
connect(m_timer, SIGNAL(timeout()), SLOT(clearClipboard()));
connect(qApp, SIGNAL(aboutToQuit()), SLOT(clearCopiedText())); connect(qApp, SIGNAL(aboutToQuit()), SLOT(clearCopiedText()));
} }
@ -77,7 +76,9 @@ void Clipboard::setText(const QString& text, bool clear)
if (config()->get(Config::Security_ClearClipboard).toBool()) { if (config()->get(Config::Security_ClearClipboard).toBool()) {
int timeout = config()->get(Config::Security_ClearClipboardTimeout).toInt(); int timeout = config()->get(Config::Security_ClearClipboardTimeout).toInt();
if (timeout > 0) { if (timeout > 0) {
m_timer->start(timeout * 1000); m_secondsElapsed = -1;
countdownTick();
m_timer->start(1000);
} }
} }
} }
@ -85,15 +86,9 @@ void Clipboard::setText(const QString& text, bool clear)
void Clipboard::clearCopiedText() void Clipboard::clearCopiedText()
{ {
if (m_timer->isActive()) { m_timer->stop();
m_timer->stop(); emit updateCountdown(-1, "");
}
clearClipboard();
}
void Clipboard::clearClipboard()
{
auto* clipboard = QApplication::clipboard(); auto* clipboard = QApplication::clipboard();
if (!clipboard) { if (!clipboard) {
qWarning("Unable to access the clipboard."); qWarning("Unable to access the clipboard.");
@ -108,6 +103,19 @@ void Clipboard::clearClipboard()
m_lastCopied.clear(); m_lastCopied.clear();
} }
void Clipboard::countdownTick()
{
m_secondsElapsed++;
int timeout = config()->get(Config::Security_ClearClipboardTimeout).toInt();
int timeLeft = timeout - m_secondsElapsed;
if (timeLeft <= 0) {
clearCopiedText();
} else {
emit updateCountdown(100 * timeLeft / timeout,
QObject::tr("Clearing the clipboard in %1 second(s)…", "", timeLeft).arg(timeLeft));
}
}
Clipboard* Clipboard::instance() Clipboard* Clipboard::instance()
{ {
if (!m_instance) { if (!m_instance) {

View File

@ -19,6 +19,7 @@
#ifndef KEEPASSX_CLIPBOARD_H #ifndef KEEPASSX_CLIPBOARD_H
#define KEEPASSX_CLIPBOARD_H #define KEEPASSX_CLIPBOARD_H
#include <QElapsedTimer>
#include <QObject> #include <QObject>
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
#include "core/MacPasteboard.h" #include "core/MacPasteboard.h"
@ -39,8 +40,11 @@ public:
public slots: public slots:
void clearCopiedText(); void clearCopiedText();
signals:
void updateCountdown(int percentage, QString message);
private slots: private slots:
void clearClipboard(); void countdownTick();
private: private:
explicit Clipboard(QObject* parent = nullptr); explicit Clipboard(QObject* parent = nullptr);
@ -48,6 +52,8 @@ private:
static Clipboard* m_instance; static Clipboard* m_instance;
QTimer* m_timer; QTimer* m_timer;
int m_secondsElapsed = 0;
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
// This object lives for the whole program lifetime and we cannot delete it on exit, // This object lives for the whole program lifetime and we cannot delete it on exit,
// so ignore leak warnings. See https://bugreports.qt.io/browse/QTBUG-54832 // so ignore leak warnings. See https://bugreports.qt.io/browse/QTBUG-54832

View File

@ -623,6 +623,19 @@ MainWindow::MainWindow()
connect(qApp, SIGNAL(openFile(QString)), this, SLOT(openDatabase(QString))); connect(qApp, SIGNAL(openFile(QString)), this, SLOT(openDatabase(QString)));
connect(qApp, SIGNAL(quitSignalReceived()), this, SLOT(appExit()), Qt::DirectConnection); connect(qApp, SIGNAL(quitSignalReceived()), this, SLOT(appExit()), Qt::DirectConnection);
statusBar()->setFixedHeight(24);
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);
m_progressBar->setMaximumWidth(100);
m_progressBar->setFixedHeight(15);
m_progressBar->setMaximum(100);
statusBar()->addPermanentWidget(m_progressBar);
connect(clipboard(), SIGNAL(updateCountdown(int, QString)), this, SLOT(updateProgressBar(int, QString)));
restoreConfigState(); restoreConfigState();
} }
@ -1388,6 +1401,19 @@ void MainWindow::updateTrayIcon()
QApplication::setQuitOnLastWindowClosed(!isTrayIconEnabled()); QApplication::setQuitOnLastWindowClosed(!isTrayIconEnabled());
} }
void MainWindow::updateProgressBar(int percentage, QString message)
{
if (percentage < 0) {
m_progressBar->setVisible(false);
m_progressBarLabel->setVisible(false);
} else {
m_progressBar->setValue(percentage);
m_progressBar->setVisible(true);
m_progressBarLabel->setText(message);
m_progressBarLabel->setVisible(true);
}
}
void MainWindow::obtainContextFocusLock() void MainWindow::obtainContextFocusLock()
{ {
m_contextMenuFocusLock = true; m_contextMenuFocusLock = true;

View File

@ -20,11 +20,15 @@
#define KEEPASSX_MAINWINDOW_H #define KEEPASSX_MAINWINDOW_H
#include <QActionGroup> #include <QActionGroup>
#include <QLabel>
#include <QMainWindow> #include <QMainWindow>
#include <QProgressBar>
#include <QStatusBar>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include "core/SignalMultiplexer.h" #include "core/SignalMultiplexer.h"
#include "gui/Application.h" #include "gui/Application.h"
#include "gui/Clipboard.h"
#include "gui/DatabaseWidget.h" #include "gui/DatabaseWidget.h"
#include "gui/osutils/ScreenLockListener.h" #include "gui/osutils/ScreenLockListener.h"
@ -143,6 +147,7 @@ private slots:
void releaseContextFocusLock(); void releaseContextFocusLock();
void agentEnabled(bool enabled); void agentEnabled(bool enabled);
void updateTrayIcon(); void updateTrayIcon();
void updateProgressBar(int percentage, QString message);
private: private:
static void setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback = 0); static void setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback = 0);
@ -174,6 +179,8 @@ private:
QPointer<QSystemTrayIcon> m_trayIcon; QPointer<QSystemTrayIcon> m_trayIcon;
QPointer<ScreenLockListener> m_screenLockListener; QPointer<ScreenLockListener> m_screenLockListener;
QPointer<SearchWidget> m_searchWidget; QPointer<SearchWidget> m_searchWidget;
QPointer<QProgressBar> m_progressBar;
QPointer<QLabel> m_progressBarLabel;
Q_DISABLE_COPY(MainWindow) Q_DISABLE_COPY(MainWindow)

View File

@ -69,3 +69,7 @@ QPlainTextEdit, QTextEdit {
background-color: palette(base); background-color: palette(base);
padding-left: 4px; padding-left: 4px;
} }
QStatusBar {
background-color: palette(window);
}

View File

@ -21,6 +21,7 @@
#include <QDialog> #include <QDialog>
#include <QMainWindow> #include <QMainWindow>
#include <QMenuBar> #include <QMenuBar>
#include <QStatusBar>
#include <QToolBar> #include <QToolBar>
DarkStyle::DarkStyle() DarkStyle::DarkStyle()
@ -110,7 +111,7 @@ QString DarkStyle::getAppStyleSheet() const
void DarkStyle::polish(QWidget* widget) void DarkStyle::polish(QWidget* widget)
{ {
if (qobject_cast<QMainWindow*>(widget) || qobject_cast<QDialog*>(widget) || qobject_cast<QMenuBar*>(widget) if (qobject_cast<QMainWindow*>(widget) || qobject_cast<QDialog*>(widget) || qobject_cast<QMenuBar*>(widget)
|| qobject_cast<QToolBar*>(widget)) { || qobject_cast<QToolBar*>(widget) || qobject_cast<QStatusBar*>(widget)) {
auto palette = widget->palette(); auto palette = widget->palette();
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
if (!osUtils->isDarkMode()) { if (!osUtils->isDarkMode()) {

View File

@ -22,6 +22,7 @@
#include <QDialog> #include <QDialog>
#include <QMainWindow> #include <QMainWindow>
#include <QMenuBar> #include <QMenuBar>
#include <QStatusBar>
#include <QToolBar> #include <QToolBar>
LightStyle::LightStyle() LightStyle::LightStyle()
@ -111,7 +112,7 @@ QString LightStyle::getAppStyleSheet() const
void LightStyle::polish(QWidget* widget) void LightStyle::polish(QWidget* widget)
{ {
if (qobject_cast<QMainWindow*>(widget) || qobject_cast<QDialog*>(widget) || qobject_cast<QMenuBar*>(widget) if (qobject_cast<QMainWindow*>(widget) || qobject_cast<QDialog*>(widget) || qobject_cast<QMenuBar*>(widget)
|| qobject_cast<QToolBar*>(widget)) { || qobject_cast<QToolBar*>(widget) || qobject_cast<QStatusBar*>(widget)) {
auto palette = widget->palette(); auto palette = widget->palette();
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
if (osUtils->isDarkMode()) { if (osUtils->isDarkMode()) {