diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-20 17:21:54 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-20 17:21:54 +0200 |
| commit | af902e0b2268085ff2ff4c21a4430ec4a94164bd (patch) | |
| tree | 80c9712390fb91a8abf2af4c3bcec87e49d4836a /src/busyindicator.cpp | |
| parent | e81e4f09a6a40162d0041253a35777e547d4dd81 (diff) | |
| download | qtmaildir-af902e0b2268085ff2ff4c21a4430ec4a94164bd.tar.gz qtmaildir-af902e0b2268085ff2ff4c21a4430ec4a94164bd.zip | |
refactor(ui): extract the busy indicator into a widget, item 134
The status bar's sync bar was a bare QProgressBar configured inline in
MainWindow, and item 123's send popup needs the same thing again. It also
needs the half MainWindow does not use: the popup drains a determinate bar
through its cancellable countdown and switches THE SAME widget to
indeterminate when send_command starts and the duration stops being
knowable. Building that inline a second time is what this removes.
BusyIndicator carries both modes. setBusy() resets the range as well as the
visibility, so the switch out of the countdown cannot leave the bar drawing
its last fraction, and setProgress() treats a total of zero as busy rather
than passing it through: setRange(0, 0) IS the indeterminate range, so a
zero total would otherwise hand the caller an animating bar while it
believed it had drawn an empty one.
Only the bar is extracted, not the status label the backlog row mentions
beside it. m_statusLabel has 34 uses across MainWindow for transient
messages, selection counts and sync phases; it belongs to the window rather
than to the indicator, and the send popup owns its own phase text.
The hidden-on-construction test needs a shown parent, which cost a mutation
to find. Measured against a standalone Qt program: a parentless widget
reports isVisible() false and isHidden() true whether or not hide() was ever
called, so both obvious assertions passed against a constructor with the
hide() deleted. What differs is WA_WState_ExplicitShowHide, and the
behaviour it produces appears only once a parent is shown, which is how the
status bar holds this widget.
All five mutations checked and killed: the zero-total guard, the range reset
in setBusy(), the value clamp, the show() in setProgress() and the hide() in
the constructor.
Diffstat (limited to 'src/busyindicator.cpp')
| -rw-r--r-- | src/busyindicator.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/busyindicator.cpp b/src/busyindicator.cpp new file mode 100644 index 0000000..0ccc719 --- /dev/null +++ b/src/busyindicator.cpp @@ -0,0 +1,65 @@ +/* + * qtmaildir - a Qt6 mail client for notmuch-indexed Maildirs + * Copyright (C) 2026 Danilo M. <danix@danix.xyz> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "busyindicator.h" + +BusyIndicator::BusyIndicator(QWidget *parent) + : QProgressBar(parent) +{ + // Starts indeterminate and hidden, which is what both consumers want + // before anything is happening. A caller that wants a fraction calls + // setProgress() and never sees this range. + setRange(0, 0); + + // The percentage would be meaningless in the indeterminate mode and is + // redundant beside the phase text in the determinate one, where the popup + // says what is being waited for. + setTextVisible(false); + hide(); +} + +void BusyIndicator::setBusy(bool busy) +{ + setRange(0, 0); + setVisible(busy); +} + +void BusyIndicator::setProgress(int value, int total) +{ + if (total <= 0) { + // Not an empty determinate bar: setRange(0, 0) IS the indeterminate + // range, so falling through here would hand the caller an animating + // bar while it believed it had shown a fraction. + setBusy(true); + return; + } + + setRange(0, total); + setValue(qBound(0, value, total)); + show(); +} + +bool BusyIndicator::isBusy() const +{ + return isVisible(); +} + +bool BusyIndicator::isDeterminate() const +{ + return maximum() > minimum(); +} |
