File indexing completed on 2024-05-19 04:29:32
0001 /* This file is part of the KDE Libraries 0002 * SPDX-FileCopyrightText: 1998 Thomas Tanghus (tanghus@earthling.net) 0003 * SPDX-FileCopyrightText: 1999-2000 Espen Sand (espen@kde.org) 0004 * SPDX-FileCopyrightText: 1999-2000 Holger Freyther <freyther@kde.org> 0005 * SPDX-FileCopyrightText: 2005-2009 Olivier Goffart (ogoffart at kde.org) 0006 * 0007 * SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #include "KoDialog.h" 0011 #include "KoDialog_p.h" 0012 0013 #include <QWindow> 0014 #include <QApplication> 0015 #include <QGuiApplication> 0016 #include <QDialogButtonBox> 0017 #include <QHBoxLayout> 0018 #include <QHideEvent> 0019 #include <QPointer> 0020 #include <QStyle> 0021 #include <QTimer> 0022 #include <QVBoxLayout> 0023 #include <QWhatsThis> 0024 #include <QDebug> 0025 #include <QPushButton> 0026 #include <QDesktopWidget> 0027 #include <QTimer> 0028 0029 #include <kconfig.h> 0030 #include <klocalizedstring.h> 0031 0032 #include <kseparator.h> 0033 #include <kstandardguiitem.h> 0034 #include <khelpclient.h> 0035 #include <kurllabel.h> 0036 #include <kwindowconfig.h> 0037 0038 void KoDialogPrivate::setupLayout() 0039 { 0040 Q_Q(KoDialog); 0041 if (!dirty) { 0042 QMetaObject::invokeMethod(q, "queuedLayoutUpdate", Qt::QueuedConnection); 0043 dirty = true; 0044 } 0045 } 0046 0047 void KoDialogPrivate::queuedLayoutUpdate() 0048 { 0049 if (!dirty) { 0050 return; 0051 } 0052 0053 dirty = false; 0054 0055 Q_Q(KoDialog); 0056 0057 // Don't lose the focus widget when re-creating the layout. 0058 // Testcase: KOrganizer's "Select Categories" dialog 0059 QPointer<QWidget> focusWidget = mMainWidget ? mMainWidget->focusWidget() : 0; 0060 0061 if (q->layout() && q->layout() != mTopLayout) { 0062 qWarning() << q->metaObject()->className() << "created with a layout; don't do that, KoDialog takes care of it, use mainWidget or setMainWidget instead"; 0063 delete q->layout(); 0064 } 0065 0066 delete mTopLayout; 0067 0068 if (mButtonOrientation == Qt::Horizontal) { 0069 mTopLayout = new QVBoxLayout(q); 0070 } else { 0071 mTopLayout = new QHBoxLayout(q); 0072 } 0073 0074 if (mUrlHelp) { 0075 mTopLayout->addWidget(mUrlHelp, 0, Qt::AlignRight); 0076 } 0077 0078 if (mMainWidget) { 0079 mTopLayout->addWidget(mMainWidget, 10); 0080 } 0081 0082 if (mDetailsWidget) { 0083 mTopLayout->addWidget(mDetailsWidget); 0084 } 0085 0086 if (mActionSeparator) { 0087 mTopLayout->addWidget(mActionSeparator); 0088 } 0089 0090 if (mButtonBox) { 0091 mButtonBox->setOrientation(mButtonOrientation); 0092 mTopLayout->addWidget(mButtonBox); 0093 } 0094 0095 if (focusWidget) { 0096 focusWidget->setFocus(); 0097 } 0098 } 0099 0100 void KoDialogPrivate::appendButton(KoDialog::ButtonCode key, const KGuiItem &item) 0101 { 0102 Q_Q(KoDialog); 0103 0104 QDialogButtonBox::ButtonRole role = QDialogButtonBox::InvalidRole; 0105 switch (key) { 0106 case KoDialog::Help: 0107 case KoDialog::Details: 0108 role = QDialogButtonBox::HelpRole; 0109 break; 0110 case KoDialog::Default: 0111 case KoDialog::Reset: 0112 role = QDialogButtonBox::ResetRole; 0113 break; 0114 case KoDialog::Ok: 0115 role = QDialogButtonBox::AcceptRole; 0116 break; 0117 case KoDialog::Apply: 0118 role = QDialogButtonBox::ApplyRole; 0119 break; 0120 case KoDialog::Try: 0121 case KoDialog::Yes: 0122 role = QDialogButtonBox::YesRole; 0123 break; 0124 case KoDialog::Close: 0125 case KoDialog::Cancel: 0126 role = QDialogButtonBox::RejectRole; 0127 break; 0128 case KoDialog::No: 0129 role = QDialogButtonBox::NoRole; 0130 break; 0131 case KoDialog::User1: 0132 case KoDialog::User2: 0133 case KoDialog::User3: 0134 role = QDialogButtonBox::ActionRole; 0135 break; 0136 default: 0137 role = QDialogButtonBox::InvalidRole; 0138 break; 0139 } 0140 0141 if (role == QDialogButtonBox::InvalidRole) { 0142 return; 0143 } 0144 0145 QPushButton *button = new QPushButton; 0146 KGuiItem::assign(button, item); 0147 mButtonBox->addButton(button, role); 0148 0149 mButtonList.insert(key, button); 0150 0151 QObject::connect(button, &QPushButton::clicked, q, [=] { q->slotButtonClicked(key); }); 0152 0153 if (key == mDefaultButton) { 0154 // Now that it exists, set it as default 0155 q->setDefaultButton(mDefaultButton); 0156 } 0157 } 0158 0159 void KoDialogPrivate::init(KoDialog *q) 0160 { 0161 q_ptr = q; 0162 0163 dirty = false; 0164 0165 q->setButtons(KoDialog::Ok | KoDialog::Cancel); 0166 q->setDefaultButton(KoDialog::Ok); 0167 0168 q->setPlainCaption(qApp->applicationDisplayName()); // set appropriate initial window title for case it gets not set later 0169 } 0170 0171 void KoDialogPrivate::helpLinkClicked() 0172 { 0173 q_ptr->slotButtonClicked(KoDialog::Help); 0174 } 0175 0176 KoDialog::KoDialog(QWidget *parent, Qt::WindowFlags flags) 0177 : QDialog(parent ? parent : qApp->activeWindow(), flags) 0178 , d_ptr(new KoDialogPrivate) 0179 { 0180 d_ptr->init(this); 0181 } 0182 0183 KoDialog::KoDialog(KoDialogPrivate &dd, QWidget *parent, Qt::WindowFlags flags) 0184 : QDialog(parent ? parent : qApp->activeWindow(), flags) 0185 , d_ptr(&dd) 0186 { 0187 d_ptr->init(this); 0188 } 0189 0190 KoDialog::~KoDialog() 0191 { 0192 delete d_ptr; 0193 } 0194 0195 void KoDialog::setButtons(ButtonCodes buttonMask) 0196 { 0197 Q_D(KoDialog); 0198 if (d->mButtonBox) { 0199 d->mButtonList.clear(); 0200 0201 delete d->mButtonBox; 0202 d->mButtonBox = 0; 0203 } 0204 0205 if (buttonMask & Cancel) { 0206 buttonMask &= ~Close; 0207 } 0208 0209 if (buttonMask & Apply) { 0210 buttonMask &= ~Try; 0211 } 0212 0213 if (buttonMask & Details) { 0214 buttonMask &= ~Default; 0215 } 0216 0217 if (buttonMask == None) { 0218 d->setupLayout(); 0219 return; // When we want no button box 0220 } 0221 0222 d->mEscapeButton = (buttonMask & Cancel) ? Cancel : Close; 0223 d->mButtonBox = new QDialogButtonBox(this); 0224 0225 if (buttonMask & Help) { 0226 d->appendButton(Help, KStandardGuiItem::help()); 0227 } 0228 if (buttonMask & Default) { 0229 d->appendButton(Default, KStandardGuiItem::defaults()); 0230 } 0231 if (buttonMask & Reset) { 0232 d->appendButton(Reset, KStandardGuiItem::reset()); 0233 } 0234 if (buttonMask & User3) { 0235 d->appendButton(User3, KGuiItem()); 0236 } 0237 if (buttonMask & User2) { 0238 d->appendButton(User2, KGuiItem()); 0239 } 0240 if (buttonMask & User1) { 0241 d->appendButton(User1, KGuiItem()); 0242 } 0243 if (buttonMask & Ok) { 0244 d->appendButton(Ok, KStandardGuiItem::ok()); 0245 } 0246 if (buttonMask & Apply) { 0247 d->appendButton(Apply, KStandardGuiItem::apply()); 0248 } 0249 if (buttonMask & Try) { 0250 d->appendButton(Try, KGuiItem(i18n("&Try"))); 0251 } 0252 if (buttonMask & Cancel) { 0253 d->appendButton(Cancel, KStandardGuiItem::cancel()); 0254 } 0255 if (buttonMask & Close) { 0256 d->appendButton(Close, KStandardGuiItem::close()); 0257 } 0258 if (buttonMask & Yes) { 0259 d->appendButton(Yes, KStandardGuiItem::yes()); 0260 } 0261 if (buttonMask & No) { 0262 d->appendButton(No, KStandardGuiItem::no()); 0263 } 0264 if (buttonMask & Details) { 0265 d->appendButton(Details, KGuiItem(QString(), "help-about")); 0266 setDetailsWidgetVisible(false); 0267 } 0268 0269 d->setupLayout(); 0270 } 0271 0272 void KoDialog::setButtonsOrientation(Qt::Orientation orientation) 0273 { 0274 Q_D(KoDialog); 0275 if (d->mButtonOrientation != orientation) { 0276 d->mButtonOrientation = orientation; 0277 0278 if (d->mActionSeparator) { 0279 d->mActionSeparator->setOrientation(d->mButtonOrientation); 0280 } 0281 0282 if (d->mButtonOrientation == Qt::Vertical) { 0283 enableLinkedHelp(false); // 2000-06-18 Espen: No support for this yet. 0284 } 0285 } 0286 } 0287 0288 void KoDialog::setEscapeButton(ButtonCode id) 0289 { 0290 d_func()->mEscapeButton = id; 0291 } 0292 0293 void KoDialog::setDefaultButton(ButtonCode newDefaultButton) 0294 { 0295 Q_D(KoDialog); 0296 0297 if (newDefaultButton == None) { 0298 newDefaultButton = NoDefault; // #148969 0299 } 0300 0301 const KoDialog::ButtonCode oldDefault = defaultButton(); 0302 0303 bool oldDefaultHadFocus = false; 0304 0305 if (oldDefault != NoDefault) { 0306 QPushButton *old = button(oldDefault); 0307 if (old) { 0308 oldDefaultHadFocus = (focusWidget() == old); 0309 old->setDefault(false); 0310 } 0311 } 0312 0313 if (newDefaultButton != NoDefault) { 0314 QPushButton *b = button(newDefaultButton); 0315 if (b) { 0316 b->setDefault(true); 0317 if (focusWidget() == 0 || oldDefaultHadFocus) { 0318 // No widget had focus yet, or the old default button had 0319 // -> ok to give focus to the new default button, so that it's 0320 // really default (Enter triggers it). 0321 // But we don't do this if the kdialog user gave focus to a 0322 // specific widget in the dialog. 0323 b->setFocus(); 0324 } 0325 } 0326 } 0327 d->mDefaultButton = newDefaultButton; 0328 Q_ASSERT(defaultButton() == newDefaultButton); 0329 } 0330 0331 KoDialog::ButtonCode KoDialog::defaultButton() const 0332 { 0333 Q_D(const KoDialog); 0334 QHashIterator<int, QPushButton *> it(d->mButtonList); 0335 while (it.hasNext()) { 0336 it.next(); 0337 if (it.value()->isDefault()) { 0338 return (ButtonCode)it.key(); 0339 } 0340 } 0341 0342 return d->mDefaultButton; 0343 } 0344 0345 void KoDialog::setMainWidget(QWidget *widget) 0346 { 0347 Q_D(KoDialog); 0348 if (d->mMainWidget == widget) { 0349 return; 0350 } 0351 d->mMainWidget = widget; 0352 if (d->mMainWidget && d->mMainWidget->layout()) { 0353 // Avoid double-margin problem 0354 d->mMainWidget->layout()->setMargin(0); 0355 } 0356 d->setupLayout(); 0357 } 0358 0359 QWidget *KoDialog::mainWidget() 0360 { 0361 Q_D(KoDialog); 0362 if (!d->mMainWidget) { 0363 setMainWidget(new QWidget(this)); 0364 } 0365 return d->mMainWidget; 0366 } 0367 0368 QSize KoDialog::sizeHint() const 0369 { 0370 Q_D(const KoDialog); 0371 0372 if (!d->mMinSize.isEmpty()) { 0373 return d->mMinSize.expandedTo(minimumSizeHint()) + d->mIncSize; 0374 } else { 0375 if (d->dirty) { 0376 const_cast<KoDialogPrivate *>(d)->queuedLayoutUpdate(); 0377 } 0378 return QDialog::sizeHint() + d->mIncSize; 0379 } 0380 } 0381 0382 QSize KoDialog::minimumSizeHint() const 0383 { 0384 Q_D(const KoDialog); 0385 0386 if (d->dirty) { 0387 const_cast<KoDialogPrivate *>(d)->queuedLayoutUpdate(); 0388 } 0389 return QDialog::minimumSizeHint() + d->mIncSize; 0390 } 0391 0392 // 0393 // Grab QDialogs keypresses if non-modal. 0394 // 0395 void KoDialog::keyPressEvent(QKeyEvent *event) 0396 { 0397 Q_D(KoDialog); 0398 if (event->modifiers() == 0) { 0399 if (event->key() == Qt::Key_F1) { 0400 QPushButton *button = this->button(Help); 0401 0402 if (button) { 0403 button->animateClick(); 0404 event->accept(); 0405 return; 0406 } 0407 } 0408 0409 if (event->key() == Qt::Key_Escape) { 0410 QPushButton *button = this->button(d->mEscapeButton); 0411 0412 if (button) { 0413 button->animateClick(); 0414 event->accept(); 0415 return; 0416 } 0417 0418 } 0419 } else if (event->key() == Qt::Key_F1 && event->modifiers() == Qt::ShiftModifier) { 0420 QWhatsThis::enterWhatsThisMode(); 0421 event->accept(); 0422 return; 0423 } else if (event->modifiers() == Qt::ControlModifier && 0424 (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) { 0425 // accept the dialog when Ctrl-Return is pressed 0426 QPushButton *button = this->button(Ok); 0427 0428 if (button) { 0429 button->animateClick(); 0430 event->accept(); 0431 return; 0432 } 0433 } 0434 0435 QDialog::keyPressEvent(event); 0436 } 0437 0438 void KoDialog::showEvent(QShowEvent *e) 0439 { 0440 QDialog::showEvent(e); 0441 QTimer::singleShot(5, [&]() { 0442 adjustPosition(parentWidget()); 0443 }); 0444 } 0445 0446 int KoDialog::marginHint() 0447 { 0448 return QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin); 0449 } 0450 0451 int KoDialog::spacingHint() 0452 { 0453 return QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); 0454 } 0455 0456 int KoDialog::groupSpacingHint() 0457 { 0458 return QApplication::fontMetrics().lineSpacing(); 0459 } 0460 0461 QString KoDialog::makeStandardCaption(const QString &userCaption, 0462 QWidget *window, 0463 CaptionFlags flags) 0464 { 0465 Q_UNUSED(window); 0466 QString caption = qApp->applicationDisplayName(); 0467 QString captionString = userCaption.isEmpty() ? caption : userCaption; 0468 0469 // If the document is modified, add '[modified]'. 0470 if (flags & ModifiedCaption) { 0471 captionString += QString::fromUtf8(" [") + i18n("modified") + QString::fromUtf8("]"); 0472 } 0473 0474 if (!userCaption.isEmpty()) { 0475 // Add the application name if: 0476 // User asked for it, it's not a duplication and the app name (caption()) is not empty 0477 if (flags & AppNameCaption && 0478 !caption.isEmpty() && 0479 !userCaption.endsWith(caption)) { 0480 // TODO: check to see if this is a transient/secondary window before trying to add the app name 0481 // on platforms that need this 0482 captionString += i18nc("Document/application separator in titlebar", " – ") + caption; 0483 } 0484 } 0485 0486 return captionString; 0487 } 0488 0489 void KoDialog::setCaption(const QString &_caption) 0490 { 0491 const QString caption = makeStandardCaption(_caption, this); 0492 setPlainCaption(caption); 0493 } 0494 0495 void KoDialog::setCaption(const QString &caption, bool modified) 0496 { 0497 CaptionFlags flags = HIGCompliantCaption; 0498 0499 // ### Qt5 TODO: port to [*], see QWidget::setWindowFilePath 0500 if (modified) { 0501 flags |= ModifiedCaption; 0502 } 0503 0504 setPlainCaption(makeStandardCaption(caption, this, flags)); 0505 } 0506 0507 void KoDialog::setPlainCaption(const QString &caption) 0508 { 0509 if (QWidget *win = window()) { 0510 win->setWindowTitle(caption); 0511 } 0512 } 0513 0514 void KoDialog::resizeLayout(QWidget *widget, int margin, int spacing) //static 0515 { 0516 if (widget->layout()) { 0517 resizeLayout(widget->layout(), margin, spacing); 0518 } 0519 0520 if (widget->children().count() > 0) { 0521 const QList<QObject *> list = widget->children(); 0522 foreach (QObject *object, list) { 0523 if (object->isWidgetType()) { 0524 resizeLayout((QWidget *)object, margin, spacing); 0525 } 0526 } 0527 } 0528 } 0529 0530 void KoDialog::resizeLayout(QLayout *layout, int margin, int spacing) //static 0531 { 0532 QLayoutItem *child; 0533 int pos = 0; 0534 0535 while ((child = layout->itemAt(pos))) { 0536 if (child->layout()) { 0537 resizeLayout(child->layout(), margin, spacing); 0538 } 0539 0540 ++pos; 0541 } 0542 0543 if (layout->layout()) { 0544 layout->layout()->setMargin(margin); 0545 layout->layout()->setSpacing(spacing); 0546 } 0547 } 0548 0549 void KoDialog::showButtonSeparator(bool state) 0550 { 0551 Q_D(KoDialog); 0552 if ((d->mActionSeparator != 0) == state) { 0553 return; 0554 } 0555 if (state) { 0556 if (d->mActionSeparator) { 0557 return; 0558 } 0559 0560 d->mActionSeparator = new KSeparator(this); 0561 d->mActionSeparator->setOrientation(d->mButtonOrientation); 0562 } else { 0563 delete d->mActionSeparator; 0564 d->mActionSeparator = 0; 0565 } 0566 0567 d->setupLayout(); 0568 } 0569 0570 void KoDialog::setInitialSize(const QSize &size) 0571 { 0572 d_func()->mMinSize = size; 0573 adjustSize(); 0574 } 0575 0576 void KoDialog::incrementInitialSize(const QSize &size) 0577 { 0578 d_func()->mIncSize = size; 0579 adjustSize(); 0580 } 0581 0582 QPushButton *KoDialog::button(ButtonCode id) const 0583 { 0584 Q_D(const KoDialog); 0585 return d->mButtonList.value(id, 0); 0586 } 0587 0588 void KoDialog::enableButton(ButtonCode id, bool state) 0589 { 0590 QPushButton *button = this->button(id); 0591 if (button) { 0592 button->setEnabled(state); 0593 } 0594 } 0595 0596 bool KoDialog::isButtonEnabled(ButtonCode id) const 0597 { 0598 QPushButton *button = this->button(id); 0599 if (button) { 0600 return button->isEnabled(); 0601 } 0602 0603 return false; 0604 } 0605 0606 void KoDialog::enableButtonOk(bool state) 0607 { 0608 enableButton(Ok, state); 0609 } 0610 0611 void KoDialog::enableButtonApply(bool state) 0612 { 0613 enableButton(Apply, state); 0614 } 0615 0616 void KoDialog::enableButtonCancel(bool state) 0617 { 0618 enableButton(Cancel, state); 0619 } 0620 0621 void KoDialog::showButton(ButtonCode id, bool state) 0622 { 0623 QPushButton *button = this->button(id); 0624 if (button) { 0625 state ? button->show() : button->hide(); 0626 } 0627 } 0628 0629 void KoDialog::setButtonGuiItem(ButtonCode id, const KGuiItem &item) 0630 { 0631 QPushButton *button = this->button(id); 0632 if (!button) { 0633 return; 0634 } 0635 0636 KGuiItem::assign(button, item); 0637 } 0638 0639 void KoDialog::setButtonText(ButtonCode id, const QString &text) 0640 { 0641 Q_D(KoDialog); 0642 if (!d->mSettingDetails && (id == Details)) { 0643 d->mDetailsButtonText = text; 0644 setDetailsWidgetVisible(d->mDetailsVisible); 0645 return; 0646 } 0647 0648 QPushButton *button = this->button(id); 0649 if (button) { 0650 button->setText(text); 0651 } 0652 } 0653 0654 QString KoDialog::buttonText(ButtonCode id) const 0655 { 0656 QPushButton *button = this->button(id); 0657 if (button) { 0658 return button->text(); 0659 } else { 0660 return QString(); 0661 } 0662 } 0663 0664 void KoDialog::setButtonIcon(ButtonCode id, const QIcon &icon) 0665 { 0666 QPushButton *button = this->button(id); 0667 if (button) { 0668 button->setIcon(icon); 0669 } 0670 } 0671 0672 QIcon KoDialog::buttonIcon(ButtonCode id) const 0673 { 0674 QPushButton *button = this->button(id); 0675 if (button) { 0676 return button->icon(); 0677 } else { 0678 return QIcon(); 0679 } 0680 } 0681 0682 void KoDialog::setButtonToolTip(ButtonCode id, const QString &text) 0683 { 0684 QPushButton *button = this->button(id); 0685 if (button) { 0686 if (text.isEmpty()) { 0687 button->setToolTip(QString()); 0688 } else { 0689 button->setToolTip(text); 0690 } 0691 } 0692 } 0693 0694 QString KoDialog::buttonToolTip(ButtonCode id) const 0695 { 0696 QPushButton *button = this->button(id); 0697 if (button) { 0698 return button->toolTip(); 0699 } else { 0700 return QString(); 0701 } 0702 } 0703 0704 void KoDialog::setButtonWhatsThis(ButtonCode id, const QString &text) 0705 { 0706 QPushButton *button = this->button(id); 0707 if (button) { 0708 if (text.isEmpty()) { 0709 button->setWhatsThis(QString()); 0710 } else { 0711 button->setWhatsThis(text); 0712 } 0713 } 0714 } 0715 0716 QString KoDialog::buttonWhatsThis(ButtonCode id) const 0717 { 0718 QPushButton *button = this->button(id); 0719 if (button) { 0720 return button->whatsThis(); 0721 } else { 0722 return QString(); 0723 } 0724 } 0725 0726 void KoDialog::setButtonFocus(ButtonCode id) 0727 { 0728 QPushButton *button = this->button(id); 0729 if (button) { 0730 button->setFocus(); 0731 } 0732 } 0733 0734 void KoDialog::setDetailsWidget(QWidget *detailsWidget) 0735 { 0736 Q_D(KoDialog); 0737 if (d->mDetailsWidget == detailsWidget) { 0738 return; 0739 } 0740 delete d->mDetailsWidget; 0741 d->mDetailsWidget = detailsWidget; 0742 0743 if (d->mDetailsWidget->parentWidget() != this) { 0744 d->mDetailsWidget->setParent(this); 0745 } 0746 0747 d->mDetailsWidget->hide(); 0748 d->setupLayout(); 0749 0750 if (!d->mSettingDetails) { 0751 setDetailsWidgetVisible(d->mDetailsVisible); 0752 } 0753 } 0754 0755 bool KoDialog::isDetailsWidgetVisible() const 0756 { 0757 return d_func()->mDetailsVisible; 0758 } 0759 0760 void KoDialog::setDetailsWidgetVisible(bool visible) 0761 { 0762 Q_D(KoDialog); 0763 if (d->mDetailsButtonText.isEmpty()) { 0764 d->mDetailsButtonText = i18n("&Details"); 0765 } 0766 0767 d->mSettingDetails = true; 0768 d->mDetailsVisible = visible; 0769 if (d->mDetailsVisible) { 0770 emit aboutToShowDetails(); 0771 setButtonText(Details, d->mDetailsButtonText + " <<"); 0772 if (d->mDetailsWidget) { 0773 if (layout()) { 0774 layout()->setEnabled(false); 0775 } 0776 0777 d->mDetailsWidget->show(); 0778 0779 adjustSize(); 0780 0781 if (layout()) { 0782 layout()->activate(); 0783 layout()->setEnabled(true); 0784 } 0785 } 0786 } else { 0787 setButtonText(Details, d->mDetailsButtonText + " >>"); 0788 if (d->mDetailsWidget) { 0789 d->mDetailsWidget->hide(); 0790 } 0791 0792 if (layout()) { 0793 layout()->activate(); 0794 adjustSize(); 0795 } 0796 0797 } 0798 0799 d->mSettingDetails = false; 0800 } 0801 0802 void KoDialog::delayedDestruct() 0803 { 0804 if (isVisible()) { 0805 hide(); 0806 } 0807 0808 deleteLater(); 0809 } 0810 0811 void KoDialog::slotButtonClicked(int button) 0812 { 0813 Q_D(KoDialog); 0814 emit buttonClicked(static_cast<KoDialog::ButtonCode>(button)); 0815 0816 switch (button) { 0817 case Ok: 0818 emit okClicked(); 0819 accept(); 0820 break; 0821 case Apply: 0822 emit applyClicked(); 0823 break; 0824 case Try: 0825 emit tryClicked(); 0826 break; 0827 case User3: 0828 emit user3Clicked(); 0829 break; 0830 case User2: 0831 emit user2Clicked(); 0832 break; 0833 case User1: 0834 emit user1Clicked(); 0835 break; 0836 case Yes: 0837 emit yesClicked(); 0838 done(Yes); 0839 break; 0840 case No: 0841 emit noClicked(); 0842 done(No); 0843 break; 0844 case Cancel: 0845 emit cancelClicked(); 0846 reject(); 0847 break; 0848 case Close: 0849 emit closeClicked(); 0850 done(Close); // KDE5: call reject() instead; more QDialog-like. 0851 break; 0852 case Help: 0853 emit helpClicked(); 0854 if (!d->mAnchor.isEmpty() || !d->mHelpApp.isEmpty()) { 0855 KHelpClient::invokeHelp(d->mAnchor, d->mHelpApp); 0856 } 0857 break; 0858 case Default: 0859 emit defaultClicked(); 0860 break; 0861 case Reset: 0862 emit resetClicked(); 0863 break; 0864 case Details: 0865 setDetailsWidgetVisible(!d->mDetailsVisible); 0866 break; 0867 } 0868 0869 // If we're here from the closeEvent, and auto-delete is on, well, auto-delete now. 0870 if (d->mDeferredDelete) { 0871 d->mDeferredDelete = false; 0872 delayedDestruct(); 0873 } 0874 } 0875 0876 void KoDialog::enableLinkedHelp(bool state) 0877 { 0878 Q_D(KoDialog); 0879 if ((d->mUrlHelp != 0) == state) { 0880 return; 0881 } 0882 if (state) { 0883 if (d->mUrlHelp) { 0884 return; 0885 } 0886 0887 d->mUrlHelp = new KUrlLabel(this); 0888 d->mUrlHelp->setText(helpLinkText()); 0889 d->mUrlHelp->setFloatEnabled(true); 0890 d->mUrlHelp->setUnderline(true); 0891 d->mUrlHelp->setMinimumHeight(fontMetrics().height() + marginHint()); 0892 connect(d->mUrlHelp, SIGNAL(leftClickedUrl()), SLOT(helpLinkClicked())); 0893 0894 d->mUrlHelp->show(); 0895 } else { 0896 delete d->mUrlHelp; 0897 d->mUrlHelp = 0; 0898 } 0899 0900 d->setupLayout(); 0901 } 0902 0903 void KoDialog::setHelp(const QString &anchor, const QString &appname) 0904 { 0905 Q_D(KoDialog); 0906 d->mAnchor = anchor; 0907 d->mHelpApp = appname; 0908 } 0909 0910 void KoDialog::setHelpLinkText(const QString &text) 0911 { 0912 Q_D(KoDialog); 0913 d->mHelpLinkText = text; 0914 if (d->mUrlHelp) { 0915 d->mUrlHelp->setText(helpLinkText()); 0916 } 0917 } 0918 0919 QString KoDialog::helpLinkText() const 0920 { 0921 Q_D(const KoDialog); 0922 return (d->mHelpLinkText.isEmpty() ? i18n("Get help...") : d->mHelpLinkText); 0923 } 0924 0925 void KoDialog::hideEvent(QHideEvent *event) 0926 { 0927 emit hidden(); 0928 0929 if (!event->spontaneous()) { 0930 emit finished(); 0931 } 0932 } 0933 0934 void KoDialog::closeEvent(QCloseEvent *event) 0935 { 0936 Q_D(KoDialog); 0937 QPushButton *button = this->button(d->mEscapeButton); 0938 if (button && !isHidden()) { 0939 button->animateClick(); 0940 0941 if (testAttribute(Qt::WA_DeleteOnClose)) { 0942 // Don't let QWidget::close do a deferred delete just yet, wait for the click first 0943 d->mDeferredDelete = true; 0944 setAttribute(Qt::WA_DeleteOnClose, false); 0945 } 0946 } else { 0947 QDialog::closeEvent(event); 0948 } 0949 } 0950 0951 #include "moc_KoDialog.cpp"