187static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment,
const QSizeF &size,
const QRectF &rectangle)
189 alignment = QGuiApplicationPrivate::visualAlignment(direction, alignment);
190 qreal x = rectangle.x();
191 qreal y = rectangle.y();
192 qreal w = size.width();
193 qreal h = size.height();
195 if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter || (alignment & Qt::AlignVertical_Mask) == 0)
196 y += qMax<qreal>(0, (rectangle.size().height() - h) / 2);
197 else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
198 y += qMax<qreal>(0, rectangle.size().height() - h);
199 if ((alignment & Qt::AlignRight) == Qt::AlignRight)
200 x += qMax<qreal>(0, rectangle.size().width() - w);
201 else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
202 x += qMax<qreal>(0, (rectangle.size().width() - w) / 2);
203 return QRectF(x, y, w, h);
206void QQuickDialogButtonBoxPrivate::resizeContent()
208 Q_Q(QQuickDialogButtonBox);
209 if (!contentItem || !contentModel)
212 QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
214 geometry = alignedRect(q->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight, alignment, QSizeF(contentWidth, contentHeight), geometry);
216 contentItem->setPosition(geometry.topLeft());
217 contentItem->setSize(geometry.size());
220void QQuickDialogButtonBoxPrivate::updateLayout()
222 Q_Q(QQuickDialogButtonBox);
223 const int count = contentModel->count();
227 const int halign = alignment & Qt::AlignHorizontal_Mask;
228 const int valign = alignment & Qt::AlignVertical_Mask;
230 QList<QQuickAbstractButton *> buttons;
231 const qreal cw = (alignment & Qt::AlignHorizontal_Mask) == 0 ? q->availableWidth() : contentWidth;
232 const qreal itemWidth = (cw - qMax(0, count - 1) * spacing) / count;
234 for (
int i = 0; i < count; ++i) {
235 QQuickItem *item = q->itemAt(i);
237 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
238 if (!p->widthValid()) {
240 item->setWidth(itemWidth);
244 item->setHeight(contentHeight);
247 p->widthValidFlag =
false;
250 buttons +=
static_cast<QQuickAbstractButton *>(item);
253 struct ButtonLayout {
254 ButtonLayout(QPlatformDialogHelper::ButtonLayout layout)
255 : m_layout(QPlatformDialogHelper::buttonLayout(Qt::Horizontal, layout))
259 bool operator()(QQuickAbstractButton *first, QQuickAbstractButton *second)
261 const QPlatformDialogHelper::ButtonRole firstRole = QQuickDialogPrivate::buttonRole(first);
262 const QPlatformDialogHelper::ButtonRole secondRole = QQuickDialogPrivate::buttonRole(second);
264 if (firstRole != secondRole && firstRole != QPlatformDialogHelper::InvalidRole && secondRole != QPlatformDialogHelper::InvalidRole) {
265 const int *l = m_layout;
266 while (*l != QPlatformDialogHelper::EOL) {
268 const int role = (*l & ~QPlatformDialogHelper::Reverse);
269 if (role == firstRole)
271 if (role == secondRole)
277 if (firstRole == secondRole)
280 return firstRole != QPlatformDialogHelper::InvalidRole;
285 std::stable_sort(buttons.begin(), buttons.end(), ButtonLayout(
static_cast<QPlatformDialogHelper::ButtonLayout>(buttonLayout)));
287 for (
int i = 0; i < buttons.size() - 1; ++i)
288 q->insertItem(i, buttons.at(i));
291qreal QQuickDialogButtonBoxPrivate::getContentWidth()
const
293 Q_Q(
const QQuickDialogButtonBox);
297 const int count = contentModel->count();
298 const qreal totalSpacing = qMax(0, count - 1) * spacing;
299 qreal totalWidth = totalSpacing;
301 for (
int i = 0; i < count; ++i) {
302 QQuickItem *item = q->itemAt(i);
304 totalWidth += item->implicitWidth();
305 maxWidth = qMax(maxWidth, item->implicitWidth());
308 if ((alignment & Qt::AlignHorizontal_Mask) == 0)
309 totalWidth = qMax(totalWidth, count * maxWidth + totalSpacing);
313qreal QQuickDialogButtonBoxPrivate::getContentHeight()
const
315 Q_Q(
const QQuickDialogButtonBox);
319 const int count = contentModel->count();
321 for (
int i = 0; i < count; ++i) {
322 QQuickItem *item = q->itemAt(i);
324 maxHeight = qMax(maxHeight, item->implicitHeight());
329void QQuickDialogButtonBoxPrivate::handleClick()
331 Q_Q(QQuickDialogButtonBox);
332 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender());
340 const QPlatformDialogHelper::ButtonRole role = QQuickDialogPrivate::buttonRole(button);
341 QPointer<QQuickDialogButtonBox> guard(q);
343 emit q->clicked(button);
349 case QPlatformDialogHelper::AcceptRole:
350 case QPlatformDialogHelper::YesRole:
353 case QPlatformDialogHelper::RejectRole:
354 case QPlatformDialogHelper::NoRole:
357 case QPlatformDialogHelper::ApplyRole:
360 case QPlatformDialogHelper::ResetRole:
363 case QPlatformDialogHelper::DestructiveRole:
366 case QPlatformDialogHelper::HelpRole:
367 emit q->helpRequested();
379QQuickAbstractButton *QQuickDialogButtonBoxPrivate::createStandardButton(QPlatformDialogHelper::StandardButton standardButton)
381 Q_Q(QQuickDialogButtonBox);
385 QQmlContext *creationContext = delegate->creationContext();
386 if (!creationContext)
387 creationContext = qmlContext(q);
389 QObject *object = delegate->beginCreate(creationContext);
390 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(object);
392 QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button,
true));
393 QQuickDialogButtonBoxAttachedPrivate::get(attached)->standardButton = standardButton;
394 attached->setButtonRole(QPlatformDialogHelper::buttonRole(standardButton));
395 button->setText(buttonText(standardButton));
396 delegate->completeCreate();
397 button->setParent(q);
405void QQuickDialogButtonBoxPrivate::removeStandardButtons()
407 Q_Q(QQuickDialogButtonBox);
408 int i = q->count() - 1;
410 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->itemAt(i));
412 QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(
413 qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button,
false));
415 QQuickDialogButtonBoxAttachedPrivate *p = QQuickDialogButtonBoxAttachedPrivate::get(attached);
416 if (p->standardButton != QPlatformDialogHelper::NoButton) {
417 q->removeItem(button);
418 button->deleteLater();
426void QQuickDialogButtonBoxPrivate::updateLanguage()
428 Q_Q(QQuickDialogButtonBox);
429 int i = q->count() - 1;
431 QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(itemAt(i));
433 QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(
434 qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button,
true));
435 const auto boxAttachedPrivate = QQuickDialogButtonBoxAttachedPrivate::get(attached);
436 const QPlatformDialogHelper::StandardButton standardButton = boxAttachedPrivate->standardButton;
438 if (standardButton != QPlatformDialogHelper::NoButton) {
439 button->setText(buttonText(standardButton));
446QPlatformDialogHelper::StandardButton QQuickDialogButtonBoxPrivate::standardButton(QQuickAbstractButton *button)
const {
447 QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button,
false));
449 return QQuickDialogButtonBoxAttachedPrivate::get(attached)->standardButton;
451 return QPlatformDialogHelper::NoButton;
454QQuickDialogButtonBox::QQuickDialogButtonBox(QQuickItem *parent)
455 : QQuickContainer(*(
new QQuickDialogButtonBoxPrivate), parent)
457 Q_D(QQuickDialogButtonBox);
458 d->changeTypes |= QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight;
459 d->buttonLayout = platformButtonLayout();
460 d->setSizePolicy(QLayoutPolicy::Preferred, QLayoutPolicy::Fixed);
536void QQuickDialogButtonBox::setAlignment(Qt::Alignment alignment)
538 Q_D(QQuickDialogButtonBox);
539 if (d->alignment == alignment)
542 d->alignment = alignment;
543 if (isComponentComplete()) {
547 emit alignmentChanged();
593void QQuickDialogButtonBox::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons)
595 Q_D(QQuickDialogButtonBox);
596 if (d->standardButtons == buttons)
599 d->removeStandardButtons();
601 for (
int i = QPlatformDialogHelper::FirstButton; i <= QPlatformDialogHelper::LastButton; i<<=1) {
602 QPlatformDialogHelper::StandardButton standardButton =
static_cast<QPlatformDialogHelper::StandardButton>(i);
603 if (standardButton & buttons) {
604 QQuickAbstractButton *button = d->createStandardButton(standardButton);
610 if (isComponentComplete())
613 d->standardButtons = buttons;
614 emit standardButtonsChanged();
624QQuickAbstractButton *QQuickDialogButtonBox::standardButton(QPlatformDialogHelper::StandardButton button)
const
626 Q_D(
const QQuickDialogButtonBox);
627 if (Q_UNLIKELY(!(d->standardButtons & button)))
629 for (
int i = 0, n = count(); i < n; ++i) {
630 QQuickAbstractButton *btn = qobject_cast<QQuickAbstractButton *>(d->itemAt(i));
632 QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(btn,
false));
633 if (attached && QQuickDialogButtonBoxAttachedPrivate::get(attached)->standardButton == button)
690void QQuickDialogButtonBox::setButtonLayout(QPlatformDialogHelper::ButtonLayout layout)
692 Q_D(QQuickDialogButtonBox);
693 if (d->buttonLayout == layout)
696 d->buttonLayout = layout;
697 if (isComponentComplete())
699 emit buttonLayoutChanged();
736void QQuickDialogButtonBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
738 Q_D(QQuickDialogButtonBox);
739 QQuickContainer::contentItemChange(newItem, oldItem);
741 QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight);
743 QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight);
751void QQuickDialogButtonBox::itemAdded(
int index, QQuickItem *item)
753 Q_D(QQuickDialogButtonBox);
755 if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(item))
756 QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, d, &QQuickDialogButtonBoxPrivate::handleClick);
757 if (QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(item,
false)))
758 QQuickDialogButtonBoxAttachedPrivate::get(attached)->setButtonBox(
this);
759 d->updateImplicitContentSize();
760 if (isComponentComplete())
764void QQuickDialogButtonBox::itemRemoved(
int index, QQuickItem *item)
766 Q_D(QQuickDialogButtonBox);
768 if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(item))
769 QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, d, &QQuickDialogButtonBoxPrivate::handleClick);
770 if (QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(item,
false)))
771 QQuickDialogButtonBoxAttachedPrivate::get(attached)->setButtonBox(
nullptr);
772 d->updateImplicitContentSize();
773 if (isComponentComplete())
794QQuickDialogButtonBoxAttached::QQuickDialogButtonBoxAttached(QObject *parent)
795 : QObject(*(
new QQuickDialogButtonBoxAttachedPrivate), parent)
797 Q_D(QQuickDialogButtonBoxAttached);
798 QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent);
799 while (parentItem && !d->buttonBox) {
800 d->buttonBox = qobject_cast<QQuickDialogButtonBox *>(parentItem);
801 parentItem = parentItem->parentItem();