| 240 | } |
| 241 | |
| 242 | void MessageBox::showEvent(QShowEvent* event) { |
| 243 | QDialog::showEvent(event); |
| 244 | |
| 245 | const bool first_show = !size_finalized_; |
| 246 | size_finalized_ = true; |
| 247 | |
| 248 | // (1) Grow to fit the word-wrapped BODY on first show. Widths are resolved by |
| 249 | // now (the dialog was sized to its hint and laid out before this event), so the |
| 250 | // body's real wrap width is known. heightForWidth does not feed sizeHint and |
| 251 | // the styled card breaks its propagation, so the dialog can open a single line |
| 252 | // tall and clip a multi-line body — re-measure at the resolved width and grow. |
| 253 | if (first_show) { |
| 254 | const int label_w = body_label_->width(); |
| 255 | if (label_w > 0) { |
| 256 | const int needed = body_label_->heightForWidth(label_w); |
| 257 | const int extra = needed - body_label_->height(); |
| 258 | if (extra > 0) { |
| 259 | body_label_->setMinimumHeight(needed); // hard floor: the wrapped text never clips |
| 260 | resize(width(), height() + extra); |
| 261 | } |
| 262 | } |
| 263 | } |
| 264 | |
| 265 | // (2) Pin the dialog to the exact height its content needs at the shown width |
| 266 | // so the QVBoxLayout never compresses the inter-button spacings. Otherwise the |
| 267 | // layout steals the wrapped-body height deficit from the most compressible |
| 268 | // items — the gaps between stacked buttons — and they shrink by a different |
| 269 | // amount per dialog. Runs after (1) so the grown body minimum height is |
| 270 | // already reflected in the layout's heightForWidth (6 px between buttons, |
| 271 | // 14 px elsewhere). |
| 272 | if (layout() != nullptr && layout()->hasHeightForWidth()) { |
| 273 | const int needed = layout()->heightForWidth(width()); |
| 274 | if (needed > 0 && needed != height()) { |
| 275 | resize(width(), needed); |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | // exec() centered us at the pre-grow size; re-center on first show after any |
| 280 | // growth so the dialog stays balanced relative to its parent window. Guarded by |
| 281 | // first_show so a later re-show (which still runs the spacing fix) does not |
| 282 | // move a dialog the user may have positioned. |
| 283 | if (first_show) { |
| 284 | if (const QWidget* anchor = parentWidget() != nullptr ? parentWidget()->window() : nullptr) { |
| 285 | const QRect parent_geom = anchor->geometry(); |
| 286 | move(parent_geom.center().x() - (width() / 2), parent_geom.center().y() - (height() / 2)); |
| 287 | } |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | void MessageBox::rewrapButtonLabels() { |
| 292 | // Widest a single button line may be before the dialog would exceed its |
nothing calls this directly
no test coverage detected