00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "kdialog.h"
00024 #include "kdialog_p.h"
00025 #include <kdebug.h>
00026 #include "kdialogqueue_p.h"
00027
00028 #include <config.h>
00029
00030 #include <QApplication>
00031 #include <QDesktopWidget>
00032 #include <QDialogButtonBox>
00033 #include <QHBoxLayout>
00034 #include <QHideEvent>
00035 #include <QPointer>
00036 #include <QStyle>
00037 #include <QTimer>
00038 #include <QVBoxLayout>
00039 #include <QWhatsThis>
00040
00041 #include <klocale.h>
00042 #include <kpushbutton.h>
00043 #include <kseparator.h>
00044 #include <kstandardguiitem.h>
00045 #include <ktoolinvocation.h>
00046 #include <kurllabel.h>
00047 #include <kwhatsthismanager_p.h>
00048
00049 #ifdef Q_WS_X11
00050 #include <qx11info_x11.h>
00051 #include <netwm.h>
00052 #endif
00053
00054 void KDialogPrivate::setupLayout()
00055 {
00056 Q_Q(KDialog);
00057 if (!dirty) {
00058 QMetaObject::invokeMethod( q, "queuedLayoutUpdate", Qt::QueuedConnection );
00059 dirty = true;
00060 }
00061 }
00062
00063 void KDialogPrivate::queuedLayoutUpdate()
00064 {
00065 if (!dirty)
00066 return;
00067
00068 dirty = false;
00069
00070 Q_Q(KDialog);
00071
00072
00073
00074 QPointer<QWidget> focusWidget = mMainWidget ? mMainWidget->focusWidget() : 0;
00075
00076 if (q->layout() && q->layout() != mTopLayout) {
00077 kWarning(240) << q->metaObject()->className() << "created with a layout; don't do that, KDialog takes care of it, use mainWidget or setMainWidget instead";
00078 delete q->layout();
00079 }
00080
00081 delete mTopLayout;
00082
00083 if ( mButtonOrientation == Qt::Horizontal )
00084 mTopLayout = new QVBoxLayout(q);
00085 else
00086 mTopLayout = new QHBoxLayout(q);
00087
00088 if ( mUrlHelp )
00089 mTopLayout->addWidget( mUrlHelp, 0, Qt::AlignRight );
00090
00091 if ( mMainWidget )
00092 mTopLayout->addWidget( mMainWidget, 10 );
00093
00094 if ( mDetailsWidget )
00095 mTopLayout->addWidget( mDetailsWidget );
00096
00097 if ( mActionSeparator )
00098 mTopLayout->addWidget( mActionSeparator );
00099
00100 if ( mButtonBox ) {
00101 mButtonBox->setOrientation( mButtonOrientation );
00102 mTopLayout->addWidget( mButtonBox );
00103 }
00104
00105 if (focusWidget) {
00106 focusWidget->setFocus();
00107 }
00108 }
00109
00110 void KDialogPrivate::setButtonFocus(QPushButton *button, bool isDefault, bool isFocus)
00111 {
00112 button->setDefault( isDefault );
00113 if ( isFocus )
00114 button->setFocus();
00115 }
00116
00117 void KDialogPrivate::appendButton(KDialog::ButtonCode key, const KGuiItem &item)
00118 {
00119 QDialogButtonBox::ButtonRole role = QDialogButtonBox::InvalidRole;
00120 switch ( key ) {
00121 case KDialog::Help:
00122 case KDialog::Details:
00123 role = QDialogButtonBox::HelpRole;
00124 break;
00125 case KDialog::Default:
00126 case KDialog::Reset:
00127 role = QDialogButtonBox::ResetRole;
00128 break;
00129 case KDialog::Ok:
00130 role = QDialogButtonBox::AcceptRole;
00131 break;
00132 case KDialog::Apply:
00133 role = QDialogButtonBox::ApplyRole;
00134 break;
00135 case KDialog::Try:
00136 case KDialog::Yes:
00137 role = QDialogButtonBox::YesRole;
00138 break;
00139 case KDialog::Close:
00140 case KDialog::Cancel:
00141 role = QDialogButtonBox::RejectRole;
00142 break;
00143 case KDialog::No:
00144 role = QDialogButtonBox::NoRole;
00145 break;
00146 case KDialog::User1:
00147 case KDialog::User2:
00148 case KDialog::User3:
00149 role = QDialogButtonBox::ActionRole;
00150 break;
00151 case KDialog::NoDefault:
00152 default:
00153 role = QDialogButtonBox::InvalidRole;
00154 break;
00155 }
00156
00157 if ( role == QDialogButtonBox::InvalidRole )
00158 return;
00159
00160 KPushButton *button = new KPushButton( item );
00161 mButtonBox->addButton( button, role );
00162
00163 mButtonList.insert( key, button );
00164 mButtonSignalMapper.setMapping( button, key );
00165
00166 QObject::connect(button, SIGNAL(clicked()),
00167 &mButtonSignalMapper, SLOT( map() ) );
00168 }
00169
00170 void KDialogPrivate::init(KDialog *q)
00171 {
00172 q_ptr = q;
00173 KWhatsThisManager::init();
00174
00175 dirty = false;
00176
00177 q->setButtons(KDialog::Ok | KDialog::Cancel);
00178 q->setDefaultButton(KDialog::Ok);
00179
00180 q->connect(&mButtonSignalMapper, SIGNAL(mapped(int)), q, SLOT(slotButtonClicked(int)));
00181
00182 q->setPlainCaption(KGlobal::caption());
00183 }
00184
00185 void KDialogPrivate::helpLinkClicked()
00186 {
00187 q_ptr->slotButtonClicked(KDialog::Help);
00188 }
00189
00190 KDialog::KDialog( QWidget *parent, Qt::WFlags flags )
00191 : QDialog(parent, flags), d_ptr(new KDialogPrivate)
00192 {
00193 d_ptr->init(this);
00194 }
00195
00196 KDialog::KDialog(KDialogPrivate &dd, QWidget *parent, Qt::WFlags flags)
00197 : QDialog(parent, flags), d_ptr(&dd)
00198 {
00199 d_ptr->init(this);
00200 }
00201
00202 KDialog::~KDialog()
00203 {
00204 delete d_ptr;
00205 }
00206
00207 void KDialog::setButtons( ButtonCodes buttonMask )
00208 {
00209 Q_D(KDialog);
00210 if ( d->mButtonBox ) {
00211 d->mButtonList.clear();
00212
00213 delete d->mButtonBox;
00214 d->mButtonBox = 0;
00215 }
00216
00217 if ( buttonMask & Cancel )
00218 buttonMask &= ~Close;
00219
00220 if ( buttonMask & Apply )
00221 buttonMask &= ~Try;
00222
00223 if ( buttonMask & Details )
00224 buttonMask &= ~Default;
00225
00226 if ( buttonMask == None ) {
00227 d->setupLayout();
00228 return;
00229 }
00230
00231 d->mEscapeButton = (buttonMask & Cancel) ? Cancel : Close;
00232 d->mButtonBox = new QDialogButtonBox( this );
00233
00234 if ( buttonMask & Help )
00235 d->appendButton( Help, KStandardGuiItem::help() );
00236 if ( buttonMask & Default )
00237 d->appendButton( Default, KStandardGuiItem::defaults() );
00238 if ( buttonMask & Reset )
00239 d->appendButton( Reset, KStandardGuiItem::reset() );
00240 if ( buttonMask & User3 )
00241 d->appendButton( User3, KGuiItem() );
00242 if ( buttonMask & User2 )
00243 d->appendButton( User2, KGuiItem() );
00244 if ( buttonMask & User1 )
00245 d->appendButton( User1, KGuiItem() );
00246 if ( buttonMask & Ok )
00247 d->appendButton( Ok, KStandardGuiItem::ok() );
00248 if ( buttonMask & Apply )
00249 d->appendButton( Apply, KStandardGuiItem::apply() );
00250 if ( buttonMask & Try )
00251 d->appendButton( Try, KGuiItem(i18n( "&Try" )) );
00252 if ( buttonMask & Cancel )
00253 d->appendButton( Cancel, KStandardGuiItem::cancel() );
00254 if ( buttonMask & Close )
00255 d->appendButton( Close, KStandardGuiItem::close() );
00256 if ( buttonMask & Yes )
00257 d->appendButton( Yes, KStandardGuiItem::yes() );
00258 if ( buttonMask & No )
00259 d->appendButton( No, KStandardGuiItem::no() );
00260 if ( buttonMask & Details ) {
00261 d->appendButton( Details, KGuiItem(QString(), "help-about") );
00262 setDetailsWidgetVisible( false );
00263 }
00264
00265 d->setupLayout();
00266 }
00267
00268
00269 void KDialog::setButtonsOrientation( Qt::Orientation orientation )
00270 {
00271 Q_D(KDialog);
00272 if ( d->mButtonOrientation != orientation ) {
00273 d->mButtonOrientation = orientation;
00274
00275 if ( d->mActionSeparator )
00276 d->mActionSeparator->setOrientation( d->mButtonOrientation );
00277
00278 if ( d->mButtonOrientation == Qt::Vertical )
00279 enableLinkedHelp( false );
00280 }
00281 }
00282
00283 void KDialog::setEscapeButton( ButtonCode id )
00284 {
00285 d_func()->mEscapeButton = id;
00286 }
00287
00288 void KDialog::setDefaultButton( ButtonCode newDefaultButton )
00289 {
00290 Q_D(KDialog);
00291 bool makeDefault = true;
00292 if (newDefaultButton == NoDefault) {
00293
00294
00295 newDefaultButton = defaultButton();
00296 makeDefault = false;
00297 }
00298
00299 KPushButton *b = button(newDefaultButton);
00300 if (b) {
00301 d->setButtonFocus(b, makeDefault, false);
00302 }
00303 }
00304
00305 KDialog::ButtonCode KDialog::defaultButton() const
00306 {
00307 Q_D(const KDialog);
00308 QHashIterator<int, KPushButton*> it( d->mButtonList );
00309 while ( it.hasNext() ) {
00310 it.next();
00311 if ( it.value()->isDefault() )
00312 return (ButtonCode)it.key();
00313 }
00314
00315 return NoDefault;
00316 }
00317
00318 void KDialog::setMainWidget( QWidget *widget )
00319 {
00320 Q_D(KDialog);
00321 if ( d->mMainWidget == widget )
00322 return;
00323 d->mMainWidget = widget;
00324 if (d->mMainWidget && d->mMainWidget->layout()) {
00325
00326 d->mMainWidget->layout()->setMargin(0);
00327 }
00328 d->setupLayout();
00329 }
00330
00331 QWidget *KDialog::mainWidget()
00332 {
00333 Q_D(KDialog);
00334 if (!d->mMainWidget)
00335 setMainWidget( new QWidget(this) );
00336 return d->mMainWidget;
00337 }
00338
00339 QSize KDialog::sizeHint() const
00340 {
00341 Q_D(const KDialog);
00342
00343 if (!d->mMinSize.isEmpty())
00344 return d->mMinSize.expandedTo( minimumSizeHint() ) + d->mIncSize;
00345 else {
00346 if (d->dirty)
00347 const_cast<KDialogPrivate*>(d)->queuedLayoutUpdate();
00348 return QDialog::sizeHint() + d->mIncSize;
00349 }
00350 }
00351
00352 QSize KDialog::minimumSizeHint() const
00353 {
00354 Q_D(const KDialog);
00355
00356 if (d->dirty)
00357 const_cast<KDialogPrivate*>(d)->queuedLayoutUpdate();
00358 return QDialog::minimumSizeHint() + d->mIncSize;
00359 }
00360
00361
00362
00363
00364 void KDialog::keyPressEvent( QKeyEvent *event )
00365 {
00366 Q_D(KDialog);
00367 if ( event->modifiers() == 0 ) {
00368 if ( event->key() == Qt::Key_F1 ) {
00369 KPushButton *button = this->button( Help );
00370
00371 if ( button ) {
00372 button->animateClick();
00373 event->accept();
00374 return;
00375 }
00376 }
00377
00378 if ( event->key() == Qt::Key_Escape ) {
00379 KPushButton *button = this->button( d->mEscapeButton );
00380
00381 if ( button ) {
00382 button->animateClick();
00383 event->accept();
00384 return;
00385 }
00386
00387 }
00388 } else if ( event->key() == Qt::Key_F1 && event->modifiers() == Qt::ShiftModifier ) {
00389 QWhatsThis::enterWhatsThisMode();
00390 event->accept();
00391 return;
00392 } else if ( event->modifiers() == Qt::ControlModifier &&
00393 ( event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter ) ) {
00394
00395 KPushButton *button = this->button( Ok );
00396
00397 if ( button ) {
00398 button->animateClick();
00399 event->accept();
00400 return;
00401 }
00402 }
00403
00404 QDialog::keyPressEvent( event );
00405 }
00406
00407 int KDialog::marginHint()
00408 {
00409 return QApplication::style()->pixelMetric( QStyle::PM_DefaultChildMargin );
00410 }
00411
00412 int KDialog::spacingHint()
00413 {
00414 return QApplication::style()->pixelMetric( QStyle::PM_DefaultLayoutSpacing );
00415 }
00416
00417 int KDialog::groupSpacingHint()
00418 {
00419 return QApplication::fontMetrics().lineSpacing();
00420 }
00421
00422 QString KDialog::makeStandardCaption( const QString &userCaption,
00423 QWidget* window,
00424 CaptionFlags flags )
00425 {
00426 Q_UNUSED(window);
00427 QString caption = KGlobal::caption();
00428 QString captionString = userCaption.isEmpty() ? caption : userCaption;
00429
00430
00431 if (flags & ModifiedCaption)
00432 captionString += QString::fromUtf8(" [") + i18n("modified") + QString::fromUtf8("]");
00433
00434 if ( !userCaption.isEmpty() ) {
00435
00436
00437 if ( flags & AppNameCaption &&
00438 !caption.isEmpty() &&
00439 !userCaption.endsWith(caption) ) {
00440
00441
00442 captionString += i18nc("Document/application separator in titlebar", " – ") + caption;
00443 }
00444 }
00445
00446 return captionString;
00447 }
00448
00449 void KDialog::setCaption( const QString &_caption )
00450 {
00451 const QString caption = makeStandardCaption( _caption, this );
00452 setPlainCaption( caption );
00453 }
00454
00455 void KDialog::setCaption( const QString &caption, bool modified )
00456 {
00457 CaptionFlags flags = HIGCompliantCaption;
00458
00459 if ( modified )
00460 {
00461 flags |= ModifiedCaption;
00462 }
00463
00464 setPlainCaption( makeStandardCaption(caption, this, flags) );
00465 }
00466
00467
00468 void KDialog::setPlainCaption( const QString &caption )
00469 {
00470 QDialog::setWindowTitle( caption );
00471
00472 #ifdef Q_WS_X11
00473 NETWinInfo info( QX11Info::display(), winId(), QX11Info::appRootWindow(), 0 );
00474 info.setName( caption.toUtf8().constData() );
00475 #endif
00476 }
00477
00478 void KDialog::resizeLayout( QWidget *widget, int margin, int spacing )
00479 {
00480 if ( widget->layout() )
00481 resizeLayout( widget->layout(), margin, spacing );
00482
00483 if ( widget->children().count() > 0 ) {
00484 const QList<QObject*> list = widget->children();
00485 foreach ( QObject *object, list ) {
00486 if ( object->isWidgetType() )
00487 resizeLayout( (QWidget*)object, margin, spacing );
00488 }
00489 }
00490 }
00491
00492 void KDialog::resizeLayout( QLayout *layout, int margin, int spacing )
00493 {
00494 QLayoutItem *child;
00495 int pos = 0;
00496
00497 while ( (child = layout->itemAt( pos ) ) ) {
00498 if ( child->layout() )
00499 resizeLayout( child->layout(), margin, spacing );
00500
00501 ++pos;
00502 }
00503
00504 if ( layout->layout() ) {
00505 layout->layout()->setMargin( margin );
00506 layout->layout()->setSpacing( spacing );
00507 }
00508 }
00509
00510 static QRect screenRect( QWidget *widget, int screen )
00511 {
00512 QDesktopWidget *desktop = QApplication::desktop();
00513 KConfig gc( "kdeglobals", KConfig::NoGlobals );
00514 KConfigGroup cg(&gc, "Windows" );
00515 if ( desktop->isVirtualDesktop() &&
00516 cg.readEntry( "XineramaEnabled", true ) &&
00517 cg.readEntry( "XineramaPlacementEnabled", true ) ) {
00518
00519 if ( screen < 0 || screen >= desktop->numScreens() ) {
00520 if ( screen == -1 )
00521 screen = desktop->primaryScreen();
00522 else if ( screen == -3 )
00523 screen = desktop->screenNumber( QCursor::pos() );
00524 else
00525 screen = desktop->screenNumber( widget );
00526 }
00527
00528 return desktop->availableGeometry( screen );
00529 } else
00530 return desktop->geometry();
00531 }
00532
00533 void KDialog::centerOnScreen( QWidget *widget, int screen )
00534 {
00535 if ( !widget )
00536 return;
00537
00538 #ifdef Q_WS_X11
00539 if( !( widget->windowFlags() & Qt::X11BypassWindowManagerHint ) && widget->windowType() != Qt::Popup
00540 && NETRootInfo( QX11Info::display(), NET::Supported ).isSupported( NET::WM2FullPlacement )) {
00541 return;
00542 }
00543 #endif
00544
00545 QRect rect = screenRect( widget, screen );
00546
00547 widget->move( rect.center().x() - widget->width() / 2,
00548 rect.center().y() - widget->height() / 2 );
00549 }
00550
00551 bool KDialog::avoidArea( QWidget *widget, const QRect& area, int screen )
00552 {
00553 if ( !widget )
00554 return false;
00555
00556 QRect fg = widget->frameGeometry();
00557 if ( !fg.intersects( area ) )
00558 return true;
00559
00560 const QRect scr = screenRect( widget, screen );
00561 QRect avoid( area );
00562 avoid.translate( -5, -5 );
00563 avoid.setRight( avoid.right() + 10 );
00564 avoid.setBottom( avoid.bottom() + 10 );
00565
00566 if ( qMax( fg.top(), avoid.top() ) <= qMin( fg.bottom(), avoid.bottom() ) ) {
00567
00568 int spaceAbove = qMax( 0, avoid.top() - scr.top() );
00569 int spaceBelow = qMax( 0, scr.bottom() - avoid.bottom() );
00570 if ( spaceAbove > spaceBelow )
00571 if ( fg.height() <= spaceAbove )
00572 fg.setY( avoid.top() - fg.height() );
00573 else
00574 return false;
00575 else
00576 if ( fg.height() <= spaceBelow )
00577 fg.setY( avoid.bottom() );
00578 else
00579 return false;
00580 }
00581
00582 if ( qMax( fg.left(), avoid.left() ) <= qMin( fg.right(), avoid.right() ) ) {
00583
00584 const int spaceLeft = qMax( 0, avoid.left() - scr.left() );
00585 const int spaceRight = qMax( 0, scr.right() - avoid.right() );
00586 if ( spaceLeft > spaceRight )
00587 if ( fg.width() <= spaceLeft )
00588 fg.setX( avoid.left() - fg.width() );
00589 else
00590 return false;
00591 else
00592 if ( fg.width() <= spaceRight )
00593 fg.setX( avoid.right() );
00594 else
00595 return false;
00596 }
00597
00598 widget->move( fg.x(), fg.y() );
00599
00600 return true;
00601 }
00602
00603 void KDialog::showButtonSeparator( bool state )
00604 {
00605 Q_D(KDialog);
00606 if ( ( d->mActionSeparator != 0 ) == state )
00607 return;
00608 if ( state ) {
00609 if ( d->mActionSeparator )
00610 return;
00611
00612 d->mActionSeparator = new KSeparator( this );
00613 d->mActionSeparator->setOrientation( d->mButtonOrientation );
00614 } else {
00615 delete d->mActionSeparator;
00616 d->mActionSeparator = 0;
00617 }
00618
00619 d->setupLayout();
00620 }
00621
00622 void KDialog::setInitialSize( const QSize &size )
00623 {
00624 d_func()->mMinSize = size;
00625 adjustSize();
00626 }
00627
00628 void KDialog::incrementInitialSize( const QSize &size )
00629 {
00630 d_func()->mIncSize = size;
00631 adjustSize();
00632 }
00633
00634 KPushButton *KDialog::button( ButtonCode id ) const
00635 {
00636 Q_D(const KDialog);
00637 return d->mButtonList.value( id, 0 );
00638 }
00639
00640 void KDialog::enableButton( ButtonCode id, bool state )
00641 {
00642 KPushButton *button = this->button( id );
00643 if ( button )
00644 button->setEnabled( state );
00645 }
00646
00647 bool KDialog::isButtonEnabled( ButtonCode id ) const
00648 {
00649 KPushButton *button = this->button( id );
00650 if ( button )
00651 return button->isEnabled();
00652
00653 return false;
00654 }
00655
00656 void KDialog::enableButtonOk( bool state )
00657 {
00658 enableButton( Ok, state );
00659 }
00660
00661 void KDialog::enableButtonApply( bool state )
00662 {
00663 enableButton( Apply, state );
00664 }
00665
00666 void KDialog::enableButtonCancel( bool state )
00667 {
00668 enableButton( Cancel, state );
00669 }
00670
00671 void KDialog::showButton( ButtonCode id, bool state )
00672 {
00673 KPushButton *button = this->button( id );
00674 if ( button )
00675 state ? button->show() : button->hide();
00676 }
00677
00678 void KDialog::setButtonGuiItem( ButtonCode id, const KGuiItem &item )
00679 {
00680 KPushButton *button = this->button( id );
00681 if ( !button )
00682 return;
00683
00684 button->setGuiItem( item );
00685 }
00686
00687 void KDialog::setButtonMenu( ButtonCode id, QMenu *menu, ButtonPopupMode popupmode)
00688 {
00689 KPushButton *button = this->button( id );
00690 if ( button ) {
00691 if (popupmode==InstantPopup)
00692 button->setMenu( menu );
00693 else
00694 button->setDelayedMenu(menu);
00695 }
00696 }
00697
00698 void KDialog::setButtonText( ButtonCode id, const QString &text )
00699 {
00700 Q_D(KDialog);
00701 if ( !d->mSettingDetails && (id == Details) ) {
00702 d->mDetailsButtonText = text;
00703 setDetailsWidgetVisible( d->mDetailsVisible );
00704 return;
00705 }
00706
00707 KPushButton *button = this->button( id );
00708 if ( button )
00709 button->setText( text );
00710 }
00711
00712 QString KDialog::buttonText( ButtonCode id ) const
00713 {
00714 KPushButton *button = this->button( id );
00715 if ( button )
00716 return button->text();
00717 else
00718 return QString();
00719 }
00720
00721 void KDialog::setButtonIcon( ButtonCode id, const KIcon &icon )
00722 {
00723 KPushButton *button = this->button( id );
00724 if ( button )
00725 button->setIcon( icon );
00726 }
00727
00728 KIcon KDialog::buttonIcon( ButtonCode id ) const
00729 {
00730 KPushButton *button = this->button( id );
00731 if ( button )
00732 return KIcon(button->icon());
00733 else
00734 return KIcon();
00735 }
00736
00737 void KDialog::setButtonToolTip( ButtonCode id, const QString &text )
00738 {
00739 KPushButton *button = this->button( id );
00740 if ( button ) {
00741 if ( text.isEmpty() )
00742 button->setToolTip( QString() );
00743 else
00744 button->setToolTip( text );
00745 }
00746 }
00747
00748 QString KDialog::buttonToolTip( ButtonCode id ) const
00749 {
00750 KPushButton *button = this->button( id );
00751 if ( button )
00752 return button->toolTip();
00753 else
00754 return QString();
00755 }
00756
00757 void KDialog::setButtonWhatsThis( ButtonCode id, const QString &text )
00758 {
00759 KPushButton *button = this->button( id );
00760 if ( button ) {
00761 if ( text.isEmpty() )
00762 button->setWhatsThis( QString() );
00763 else
00764 button->setWhatsThis( text );
00765 }
00766 }
00767
00768 QString KDialog::buttonWhatsThis( ButtonCode id ) const
00769 {
00770 KPushButton *button = this->button( id );
00771 if ( button )
00772 return button->whatsThis();
00773 else
00774 return QString();
00775 }
00776
00777 void KDialog::setButtonFocus( ButtonCode id )
00778 {
00779 KPushButton *button = this->button( id );
00780 if ( button )
00781 d_func()->setButtonFocus(button, button->isDefault(), true);
00782 }
00783
00784 void KDialog::setDetailsWidget( QWidget *detailsWidget )
00785 {
00786 Q_D(KDialog);
00787 if ( d->mDetailsWidget == detailsWidget )
00788 return;
00789 delete d->mDetailsWidget;
00790 d->mDetailsWidget = detailsWidget;
00791
00792 if ( d->mDetailsWidget->parentWidget() != this )
00793 d->mDetailsWidget->setParent( this );
00794
00795 d->mDetailsWidget->hide();
00796 d->setupLayout();
00797
00798 if ( !d->mSettingDetails )
00799 setDetailsWidgetVisible( d->mDetailsVisible );
00800 }
00801
00802 bool KDialog::isDetailsWidgetVisible() const
00803 {
00804 return d_func()->mDetailsVisible;
00805 }
00806
00807 void KDialog::setDetailsWidgetVisible( bool visible )
00808 {
00809 Q_D(KDialog);
00810 if ( d->mDetailsButtonText.isEmpty() )
00811 d->mDetailsButtonText = i18n( "&Details" );
00812
00813 d->mSettingDetails = true;
00814 d->mDetailsVisible = visible;
00815 if ( d->mDetailsVisible ) {
00816 emit aboutToShowDetails();
00817 setButtonText( Details, d->mDetailsButtonText + " <<" );
00818 if ( d->mDetailsWidget ) {
00819 if ( layout() )
00820 layout()->setEnabled( false );
00821
00822 d->mDetailsWidget->show();
00823
00824 adjustSize();
00825
00826 if ( layout() ) {
00827 layout()->activate();
00828 layout()->setEnabled( true );
00829 }
00830 }
00831 } else {
00832 setButtonText( Details, d->mDetailsButtonText + " >>" );
00833 if ( d->mDetailsWidget )
00834 d->mDetailsWidget->hide();
00835
00836 if ( layout() )
00837 layout()->activate();
00838
00839 adjustSize();
00840 }
00841
00842 d->mSettingDetails = false;
00843 }
00844
00845 void KDialog::delayedDestruct()
00846 {
00847 if ( isVisible() )
00848 hide();
00849
00850 deleteLater();
00851 }
00852
00853
00854 void KDialog::slotButtonClicked( int button )
00855 {
00856 Q_D(KDialog);
00857 emit buttonClicked( static_cast<KDialog::ButtonCode>(button) );
00858
00859 switch( button ) {
00860 case Ok:
00861 emit okClicked();
00862 accept();
00863 break;
00864 case Apply:
00865 emit applyClicked();
00866 break;
00867 case Try:
00868 emit tryClicked();
00869 break;
00870 case User3:
00871 emit user3Clicked();
00872 break;
00873 case User2:
00874 emit user2Clicked();
00875 break;
00876 case User1:
00877 emit user1Clicked();
00878 break;
00879 case Yes:
00880 emit yesClicked();
00881 done( Yes );
00882 break;
00883 case No:
00884 emit noClicked();
00885 done( No );
00886 break;
00887 case Cancel:
00888 emit cancelClicked();
00889 reject();
00890 break;
00891 case Close:
00892 emit closeClicked();
00893 close();
00894 break;
00895 case Help:
00896 emit helpClicked();
00897 if ( !d->mAnchor.isEmpty() || !d->mHelpApp.isEmpty() )
00898 KToolInvocation::invokeHelp( d->mAnchor, d->mHelpApp );
00899 break;
00900 case Default:
00901 emit defaultClicked();
00902 break;
00903 case Reset:
00904 emit resetClicked();
00905 break;
00906 case Details:
00907 setDetailsWidgetVisible( !d->mDetailsVisible );
00908 break;
00909 }
00910 }
00911
00912 void KDialog::enableLinkedHelp( bool state )
00913 {
00914 Q_D(KDialog);
00915 if ( ( d->mUrlHelp != 0 ) == state )
00916 return;
00917 if ( state ) {
00918 if ( d->mUrlHelp )
00919 return;
00920
00921 d->mUrlHelp = new KUrlLabel( this );
00922 d->mUrlHelp->setText( helpLinkText() );
00923 d->mUrlHelp->setFloatEnabled( true );
00924 d->mUrlHelp->setUnderline( true );
00925 d->mUrlHelp->setMinimumHeight( fontMetrics().height() + marginHint() );
00926 connect( d->mUrlHelp, SIGNAL(leftClickedUrl()), SLOT(helpLinkClicked()) );
00927
00928 d->mUrlHelp->show();
00929 } else {
00930 delete d->mUrlHelp;
00931 d->mUrlHelp = 0;
00932 }
00933
00934 d->setupLayout();
00935 }
00936
00937
00938 void KDialog::setHelp( const QString &anchor, const QString &appname )
00939 {
00940 Q_D(KDialog);
00941 d->mAnchor = anchor;
00942 d->mHelpApp = appname;
00943 }
00944
00945
00946 void KDialog::setHelpLinkText( const QString &text )
00947 {
00948 Q_D(KDialog);
00949 d->mHelpLinkText = text;
00950 if ( d->mUrlHelp )
00951 d->mUrlHelp->setText( helpLinkText() );
00952 }
00953
00954 QString KDialog::helpLinkText() const
00955 {
00956 Q_D(const KDialog);
00957 return ( d->mHelpLinkText.isEmpty() ? i18n( "Get help..." ) : d->mHelpLinkText );
00958 }
00959
00960 void KDialog::updateGeometry()
00961 {
00962 }
00963
00964 void KDialog::hideEvent( QHideEvent *event )
00965 {
00966 emit hidden();
00967
00968 if ( !event->spontaneous() )
00969 emit finished();
00970 }
00971
00972 void KDialog::closeEvent( QCloseEvent *event )
00973 {
00974 Q_D(KDialog);
00975 KPushButton *button = this->button( d->mEscapeButton );
00976 if ( button && !isHidden() )
00977 button->animateClick();
00978 else
00979 QDialog::closeEvent( event );
00980 }
00981
00982 void KDialog::restoreDialogSize( const KConfigGroup& cfg )
00983 {
00984 int width, height;
00985 int scnum = QApplication::desktop()->screenNumber( parentWidget() );
00986 QRect desk = QApplication::desktop()->screenGeometry( scnum );
00987
00988 width = sizeHint().width();
00989 height = sizeHint().height();
00990
00991 width = cfg.readEntry( QString::fromLatin1( "Width %1" ).arg( desk.width() ), width );
00992 height = cfg.readEntry( QString::fromLatin1( "Height %1" ).arg( desk.height() ), height );
00993
00994 resize( width, height );
00995 }
00996
00997 void KDialog::saveDialogSize( KConfigGroup& config, KConfigGroup::WriteConfigFlags options ) const
00998 {
00999 int scnum = QApplication::desktop()->screenNumber( parentWidget() );
01000 QRect desk = QApplication::desktop()->screenGeometry( scnum );
01001
01002 const QSize sizeToSave = size();
01003
01004 config.writeEntry( QString::fromLatin1("Width %1").arg( desk.width() ), sizeToSave.width(), options );
01005 config.writeEntry( QString::fromLatin1("Height %1").arg( desk.height() ), sizeToSave.height(), options );
01006 }
01007
01008
01009 class KDialogQueue::Private
01010 {
01011 public:
01012 Private(KDialogQueue *q): q(q) {}
01013
01014 void slotShowQueuedDialog();
01015
01016 KDialogQueue *q;
01017 QList< QPointer<QDialog> > queue;
01018 bool busy;
01019
01020 };
01021
01022 KDialogQueue* KDialogQueue::self()
01023 {
01024 K_GLOBAL_STATIC(KDialogQueue, _self)
01025 return _self;
01026 }
01027
01028 KDialogQueue::KDialogQueue()
01029 : d( new Private(this) )
01030 {
01031 d->busy = false;
01032 }
01033
01034 KDialogQueue::~KDialogQueue()
01035 {
01036 delete d;
01037 }
01038
01039
01040 void KDialogQueue::queueDialog( QDialog *dialog )
01041 {
01042 KDialogQueue *_this = self();
01043 _this->d->queue.append( dialog );
01044
01045 QTimer::singleShot( 0, _this, SLOT( slotShowQueuedDialog() ) );
01046 }
01047
01048 void KDialogQueue::Private::slotShowQueuedDialog()
01049 {
01050 if ( busy )
01051 return;
01052
01053 QDialog *dialog;
01054 do {
01055 if ( queue.isEmpty() )
01056 return;
01057 dialog = queue.first();
01058 queue.pop_front();
01059 } while( !dialog );
01060
01061 busy = true;
01062 dialog->exec();
01063 busy = false;
01064 delete dialog;
01065
01066 if ( !queue.isEmpty() )
01067 QTimer::singleShot( 20, q, SLOT( slotShowQueuedDialog() ) );
01068 }
01069
01070 #include "kdialog.moc"
01071 #include "kdialogqueue_p.moc"