00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include <kconfig.h>
00022 #include <kapplication.h>
00023 #include <kdialog.h>
00024 #include <kdebug.h>
00025 #include <kstaticdeleter.h>
00026 
00027 #include <qlayout.h>
00028 #include <qobjectlist.h>
00029 #include <qguardedptr.h>
00030 #include <qlineedit.h>
00031 #include <qvaluelist.h>
00032 #include <qtimer.h>
00033 #include <qcursor.h>
00034 
00035 #include "config.h"
00036 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00037 #include <netwm.h> 
00038 #endif
00039 
00040 int KDialog::mMarginSize = 11;
00041 int KDialog::mSpacingSize = 6;
00042 
00043 template class QPtrList<QLayoutItem>;
00044 
00045 KDialog::KDialog(QWidget *parent, const char *name, bool modal, WFlags f)
00046   : QDialog(parent, name, modal, f)
00047 {
00048 }
00049 
00050 
00051 
00052 
00053 void KDialog::keyPressEvent(QKeyEvent *e)
00054 {
00055   if ( e->state() == 0 )
00056   {
00057     switch ( e->key() )
00058     {
00059       case Key_Escape:
00060       case Key_Enter:
00061       case Key_Return:
00062       {
00063         if(testWFlags(WType_Dialog | WShowModal))
00064     {
00065           QDialog::keyPressEvent(e);
00066     }
00067         else
00068         {
00069       e->ignore();
00070         }
00071       }
00072       break;
00073       default:
00074     e->ignore();
00075     return;
00076     }
00077   }
00078   else
00079   {
00080       
00081       if ( e->state() == ControlButton &&
00082            (e->key() == Key_Return || e->key() == Key_Enter) )
00083       {
00084           e->accept();
00085           accept();
00086       }
00087       else
00088       {
00089           e->ignore();
00090       }
00091   }
00092 }
00093 
00094 
00095 int KDialog::marginHint()
00096 {
00097   return( mMarginSize );
00098 }
00099 
00100 
00101 int KDialog::spacingHint()
00102 {
00103   return( mSpacingSize );
00104 }
00105 
00106 
00107 void KDialog::polish()
00108 {
00109   QDialog::polish();
00110   QWidget *w = focusWidget();
00111   if( w && w->isEnabled() && w->inherits( "QLineEdit" ) &&
00112       !w->inherits( "KPasswordEdit" ))
00113     ((QLineEdit*)w)->selectAll();
00114 }
00115 
00116 
00117 void KDialog::setCaption( const QString &_caption )
00118 {
00119   QString caption = kapp ? kapp->makeStdCaption( _caption ) : _caption;
00120   setPlainCaption( caption );
00121 }
00122 
00123 
00124 void KDialog::setPlainCaption( const QString &caption )
00125 {
00126   QDialog::setCaption( caption );
00127 
00128 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00129 
00130   NETWinInfo info( qt_xdisplay(), winId(), qt_xrootwin(), 0 );
00131   info.setName( caption.utf8().data() );
00132 #endif
00133 }
00134 
00135 
00136 void KDialog::resizeLayout( QWidget *w, int margin, int spacing )
00137 {
00138   if( w->layout() )
00139   {
00140     resizeLayout( w->layout(), margin, spacing );
00141   }
00142 
00143   if( w->children() )
00144   {
00145     QObjectList *l = (QObjectList*)w->children(); 
00146     for( uint i=0; i < l->count(); i++ )
00147     {
00148       QObject *o = l->at(i);
00149       if( o->isWidgetType() )
00150       {
00151     resizeLayout( (QWidget*)o, margin, spacing );
00152       }
00153     }
00154   }
00155 }
00156 
00157 
00158 void KDialog::resizeLayout( QLayoutItem *lay, int margin, int spacing )
00159 {
00160   QLayoutIterator it = lay->iterator();
00161   QLayoutItem *child;
00162   while ( (child = it.current() ) )
00163   {
00164     resizeLayout( child, margin, spacing );
00165     ++it;
00166   }
00167   if( lay->layout() != 0 )
00168   {
00169     lay->layout()->setMargin( margin );
00170     lay->layout()->setSpacing( spacing );
00171   }
00172 }
00173 
00174 static QRect screenRect( QWidget *w, int screen )
00175 {
00176   QDesktopWidget *desktop = QApplication::desktop();
00177   KConfig gc("kdeglobals", false, false);
00178   gc.setGroup("Windows");
00179   if (desktop->isVirtualDesktop() &&
00180       gc.readBoolEntry("XineramaEnabled", true) &&
00181       gc.readBoolEntry("XineramaPlacementEnabled", true)) {
00182     if ( screen < 0 || screen >= desktop->numScreens() ) {
00183       if ( screen == -1 ) {
00184         screen = desktop->primaryScreen();
00185       } else if ( screen == -3 ) {
00186         screen = desktop->screenNumber( QCursor::pos() );
00187       } else {
00188         screen = desktop->screenNumber( w );
00189       }
00190     }
00191     return desktop->screenGeometry(screen);
00192   } else {
00193     return desktop->geometry();
00194   }
00195 }
00196 
00197 void KDialog::centerOnScreen( QWidget *w, int screen )
00198 {
00199   if ( !w )
00200     return;
00201   QRect r = screenRect( w, screen );
00202 
00203   w->move( r.center().x() - w->width()/2,
00204            r.center().y() - w->height()/2 );
00205 }
00206 
00207 bool KDialog::avoidArea( QWidget *w, const QRect& area, int screen )
00208 {
00209   if ( !w )
00210     return false;
00211   QRect fg = w->frameGeometry();
00212   if ( !fg.intersects( area ) )
00213     return true; 
00214 
00215   QRect scr = screenRect( w, screen );
00216   QRect avoid( area ); 
00217   avoid.moveBy( -5, -5 );
00218   avoid.rRight() += 10;
00219   avoid.rBottom() += 10;
00220 
00221   if ( QMAX( fg.top(), avoid.top() ) <= QMIN( fg.bottom(), avoid.bottom() ) )
00222   {
00223     
00224     int spaceAbove = QMAX(0, avoid.top() - scr.top());
00225     int spaceBelow = QMAX(0, scr.bottom() - avoid.bottom());
00226     if ( spaceAbove > spaceBelow ) 
00227       if ( fg.height() <= spaceAbove ) 
00228         fg.setY( avoid.top() - fg.height() );
00229       else
00230         return false;
00231     else
00232       if ( fg.height() <= spaceBelow ) 
00233         fg.setY( avoid.bottom() );
00234       else
00235         return false;
00236   }
00237 
00238   if ( QMAX( fg.left(), avoid.left() ) <= QMIN( fg.right(), avoid.right() ) )
00239   {
00240     
00241     int spaceLeft = QMAX(0, avoid.left() - scr.left());
00242     int spaceRight = QMAX(0, scr.right() - avoid.right());
00243     if ( spaceLeft > spaceRight ) 
00244       if ( fg.width() <= spaceLeft ) 
00245         fg.setX( avoid.left() - fg.width() );
00246       else
00247         return false;
00248     else
00249       if ( fg.width() <= spaceRight ) 
00250         fg.setX( avoid.right() );
00251       else
00252         return false;
00253   }
00254   
00255   w->move(fg.x(), fg.y());
00256   return true;
00257 }
00258 
00259 class KDialogQueuePrivate
00260 {
00261 public:
00262   QValueList< QGuardedPtr<QDialog> > queue;
00263   bool busy;
00264 };
00265 
00266 static KStaticDeleter<KDialogQueue> ksdkdq;
00267 
00268 KDialogQueue *KDialogQueue::_self=0;
00269 
00270 KDialogQueue* KDialogQueue::self()
00271 {
00272    if (!_self)
00273       _self = ksdkdq.setObject(_self, new KDialogQueue);
00274    return _self;
00275 }
00276 
00277 KDialogQueue::KDialogQueue()
00278 {
00279    d = new KDialogQueuePrivate;
00280    d->busy = false;
00281 }
00282 
00283 KDialogQueue::~KDialogQueue()
00284 {
00285    delete d; d = 0;
00286    _self = 0;
00287 }
00288 
00289 
00290 void KDialogQueue::queueDialog(QDialog *dialog)
00291 {
00292    KDialogQueue *_this = self();
00293    _this->d->queue.append(dialog);
00294    QTimer::singleShot(0, _this, SLOT(slotShowQueuedDialog()));
00295 }
00296 
00297 void KDialogQueue::slotShowQueuedDialog()
00298 {
00299    if (d->busy)
00300       return;
00301    QDialog *dialog;
00302    do {
00303       if(!d->queue.count())
00304          return;
00305       dialog = d->queue.first();
00306       d->queue.remove(d->queue.begin());
00307    }
00308    while(!dialog);
00309 
00310    d->busy = true;
00311    dialog->exec();
00312    d->busy = false;
00313    delete dialog;
00314 
00315    if (d->queue.count())
00316       QTimer::singleShot(20, this, SLOT(slotShowQueuedDialog()));
00317    else
00318       ksdkdq.destructObject(); 
00319 }
00320 
00321 void KDialog::virtual_hook( int, void* )
00322 {  }
00323 
00324 #include "kdialog.moc"