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