[QtUtils] Add Debouncer helper (#7623)

* [QtUtils] Add Debouncer helper

* Extract long message to variable before confirm() call

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL
2026-10-24 22:43:10 +02:00
committed by GitHub
parent 11e2bb0d2f
commit 28c8474f03
3 changed files with 70 additions and 5 deletions

View File

@@ -171,11 +171,13 @@ void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, Releas
publishDate = release->getPublishDate().toString(QLocale().dateFormat(QLocale::LongFormat));
if (isCompatible) {
if (QtUtils::confirm(window(), tr("Update Available"),
tr("A new version of Cockatrice is available!") + "<br><br>" + "<b>" + tr("New version") +
QString(":</b> %1<br>").arg(release->getName()) + "<b>" + tr("Released") +
QString(":</b> %1 (<a href=\"%2\">").arg(publishDate, release->getDescriptionUrl()) +
tr("Changelog") + "</a>)<br><br>" + tr("Do you want to update now?"))) {
const QString message = tr("A new version of Cockatrice is available!") + "<br><br>" + "<b>" +
tr("New version") + QString(":</b> %1<br>").arg(release->getName()) + "<b>" +
tr("Released") +
QString(":</b> %1 (<a href=\"%2\">").arg(publishDate, release->getDescriptionUrl()) +
tr("Changelog") + "</a>)<br><br>" + tr("Do you want to update now?");
if (QtUtils::confirm(window(), tr("Update Available"), message)) {
downloadUpdate(release->getName());
} else {
closeDialog();

View File

@@ -21,6 +21,7 @@ set(UTILITY_HEADERS
libcockatrice/utility/card_ref.h
libcockatrice/utility/color.h
libcockatrice/utility/cryptoutil.h
libcockatrice/utility/debouncer.h
libcockatrice/utility/expression.h
libcockatrice/utility/levenshtein.h
libcockatrice/utility/local_server_name.h

View File

@@ -0,0 +1,62 @@
#ifndef COCKATRICE_DEBOUNCER_H
#define COCKATRICE_DEBOUNCER_H
#include <QObject>
#include <QTimer>
#include <functional>
#include <utility>
namespace QtUtils
{
/**
* @brief Runs the most recent call() after a period without further calls.
*
* Typical use is coalescing rapid model or editor updates into one refresh:
*
* debouncer.call([this] { refresh(); });
*
* The pending callback is owned by the debouncer and replaced when call() is invoked
* again. The debouncer must outlive any callback it schedules; parenting it to the
* owning widget is usually enough.
*/
class Debouncer : public QObject
{
public:
explicit Debouncer(int intervalMs, QObject *parent = nullptr) : QObject(parent)
{
timer.setSingleShot(true);
timer.setInterval(intervalMs);
connect(&timer, &QTimer::timeout, this, [this] {
if (callback) {
auto pending = std::move(callback);
callback = nullptr;
pending();
}
});
}
/**
* @brief Schedules @p newCallback, replacing any callback not run yet.
*/
void call(std::function<void()> newCallback)
{
callback = std::move(newCallback);
timer.start();
}
/**
* @brief Drops the pending callback and stops the timer.
*/
void cancel()
{
timer.stop();
callback = nullptr;
}
private:
QTimer timer;
std::function<void()> callback;
};
} // namespace QtUtils
#endif // COCKATRICE_DEBOUNCER_H