• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDEUI

kdialog.cpp

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

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal