kdeui Library API Documentation

kdialog.cpp

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 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 * Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include <kconfig.h> 00022 #include <kapplication.h> 00023 #include <kdialog.h> 00024 #include <kwhatsthismanager_p.h> 00025 #include <kdebug.h> 00026 #include <kstaticdeleter.h> 00027 00028 #include <qlayout.h> 00029 #include <qobjectlist.h> 00030 #include <qguardedptr.h> 00031 #include <qlineedit.h> 00032 #include <qvaluelist.h> 00033 #include <qtimer.h> 00034 #include <qcursor.h> 00035 00036 #include "config.h" 00037 #ifdef Q_WS_X11 00038 #include <netwm.h> 00039 #endif 00040 00041 const int KDialog::mMarginSize = 11; 00042 const int KDialog::mSpacingSize = 6; 00043 00044 template class QPtrList<QLayoutItem>; 00045 00046 KDialog::KDialog(QWidget *parent, const char *name, bool modal, WFlags f) 00047 : QDialog(parent, name, modal, f), d(0) 00048 { 00049 KWhatsThisManager::init (); 00050 } 00051 00052 // 00053 // Grab QDialogs keypresses if non-modal. 00054 // 00055 void KDialog::keyPressEvent(QKeyEvent *e) 00056 { 00057 if ( e->state() == 0 ) 00058 { 00059 switch ( e->key() ) 00060 { 00061 case Key_Escape: 00062 case Key_Enter: 00063 case Key_Return: 00064 { 00065 if(testWFlags(WType_Dialog | WShowModal)) 00066 { 00067 QDialog::keyPressEvent(e); 00068 } 00069 else 00070 { 00071 e->ignore(); 00072 } 00073 } 00074 break; 00075 default: 00076 e->ignore(); 00077 return; 00078 } 00079 } 00080 else 00081 { 00082 // accept the dialog when Ctrl-Return is pressed 00083 if ( e->state() == ControlButton && 00084 (e->key() == Key_Return || e->key() == Key_Enter) ) 00085 { 00086 e->accept(); 00087 accept(); 00088 } 00089 else 00090 { 00091 e->ignore(); 00092 } 00093 } 00094 } 00095 00096 00097 int KDialog::marginHint() 00098 { 00099 return mMarginSize; 00100 } 00101 00102 00103 int KDialog::spacingHint() 00104 { 00105 return mSpacingSize; 00106 } 00107 00108 // KDE4: Remove me 00109 void KDialog::polish() 00110 { 00111 QDialog::polish(); 00112 } 00113 00114 00115 void KDialog::setCaption( const QString &_caption ) 00116 { 00117 QString caption = kapp ? kapp->makeStdCaption( _caption ) : _caption; 00118 setPlainCaption( caption ); 00119 } 00120 00121 00122 void KDialog::setPlainCaption( const QString &caption ) 00123 { 00124 QDialog::setCaption( caption ); 00125 00126 #ifdef Q_WS_X11 00127 NETWinInfo info( qt_xdisplay(), winId(), qt_xrootwin(), 0 ); 00128 info.setName( caption.utf8().data() ); 00129 #endif 00130 } 00131 00132 00133 void KDialog::resizeLayout( QWidget *w, int margin, int spacing ) 00134 { 00135 if( w->layout() ) 00136 { 00137 resizeLayout( w->layout(), margin, spacing ); 00138 } 00139 00140 if( w->children() ) 00141 { 00142 const QObjectList * const l = w->children(); 00143 QObjectListIterator itr(*l); 00144 QObject *o; 00145 while ((o = itr.current()) != 0) { 00146 if( o->isWidgetType() ) 00147 { 00148 resizeLayout( (QWidget*)o, margin, spacing ); 00149 } 00150 ++itr; 00151 } 00152 } 00153 } 00154 00155 00156 void KDialog::resizeLayout( QLayoutItem *lay, int margin, int spacing ) 00157 { 00158 QLayoutIterator it = lay->iterator(); 00159 QLayoutItem *child; 00160 while ( (child = it.current() ) ) 00161 { 00162 resizeLayout( child, margin, spacing ); 00163 ++it; 00164 } 00165 if( lay->layout() ) 00166 { 00167 lay->layout()->setMargin( margin ); 00168 lay->layout()->setSpacing( spacing ); 00169 } 00170 } 00171 00172 static QRect screenRect( QWidget *w, int screen ) 00173 { 00174 QDesktopWidget *desktop = QApplication::desktop(); 00175 KConfig gc("kdeglobals", false, false); 00176 gc.setGroup("Windows"); 00177 if (desktop->isVirtualDesktop() && 00178 gc.readBoolEntry("XineramaEnabled", true) && 00179 gc.readBoolEntry("XineramaPlacementEnabled", true)) { 00180 if ( screen < 0 || screen >= desktop->numScreens() ) { 00181 if ( screen == -1 ) { 00182 screen = desktop->primaryScreen(); 00183 } else if ( screen == -3 ) { 00184 screen = desktop->screenNumber( QCursor::pos() ); 00185 } else { 00186 screen = desktop->screenNumber( w ); 00187 } 00188 } 00189 return desktop->screenGeometry(screen); 00190 } else { 00191 return desktop->geometry(); 00192 } 00193 } 00194 00195 void KDialog::centerOnScreen( QWidget *w, int screen ) 00196 { 00197 if ( !w ) 00198 return; 00199 QRect r = screenRect( w, screen ); 00200 00201 w->move( r.center().x() - w->width()/2, 00202 r.center().y() - w->height()/2 ); 00203 } 00204 00205 bool KDialog::avoidArea( QWidget *w, const QRect& area, int screen ) 00206 { 00207 if ( !w ) 00208 return false; 00209 QRect fg = w->frameGeometry(); 00210 if ( !fg.intersects( area ) ) 00211 return true; // nothing to do. 00212 00213 QRect scr = screenRect( w, screen ); 00214 QRect avoid( area ); // let's add some margin 00215 avoid.moveBy( -5, -5 ); 00216 avoid.rRight() += 10; 00217 avoid.rBottom() += 10; 00218 00219 if ( QMAX( fg.top(), avoid.top() ) <= QMIN( fg.bottom(), avoid.bottom() ) ) 00220 { 00221 // We need to move the widget up or down 00222 int spaceAbove = QMAX(0, avoid.top() - scr.top()); 00223 int spaceBelow = QMAX(0, scr.bottom() - avoid.bottom()); 00224 if ( spaceAbove > spaceBelow ) // where's the biggest side? 00225 if ( fg.height() <= spaceAbove ) // big enough? 00226 fg.setY( avoid.top() - fg.height() ); 00227 else 00228 return false; 00229 else 00230 if ( fg.height() <= spaceBelow ) // big enough? 00231 fg.setY( avoid.bottom() ); 00232 else 00233 return false; 00234 } 00235 00236 if ( QMAX( fg.left(), avoid.left() ) <= QMIN( fg.right(), avoid.right() ) ) 00237 { 00238 // We need to move the widget left or right 00239 int spaceLeft = QMAX(0, avoid.left() - scr.left()); 00240 int spaceRight = QMAX(0, scr.right() - avoid.right()); 00241 if ( spaceLeft > spaceRight ) // where's the biggest side? 00242 if ( fg.width() <= spaceLeft ) // big enough? 00243 fg.setX( avoid.left() - fg.width() ); 00244 else 00245 return false; 00246 else 00247 if ( fg.width() <= spaceRight ) // big enough? 00248 fg.setX( avoid.right() ); 00249 else 00250 return false; 00251 } 00252 //kdDebug() << "Moving window to " << fg.x() << "," << fg.y() << endl; 00253 w->move(fg.x(), fg.y()); 00254 return true; 00255 } 00256 00257 class KDialogQueuePrivate 00258 { 00259 public: 00260 QValueList< QGuardedPtr<QDialog> > queue; 00261 bool busy; 00262 }; 00263 00264 static KStaticDeleter<KDialogQueue> ksdkdq; 00265 00266 KDialogQueue *KDialogQueue::_self=0; 00267 00268 KDialogQueue* KDialogQueue::self() 00269 { 00270 if (!_self) 00271 _self = ksdkdq.setObject(_self, new KDialogQueue); 00272 return _self; 00273 } 00274 00275 KDialogQueue::KDialogQueue() : d(new KDialogQueuePrivate) 00276 { 00277 d->busy = false; 00278 } 00279 00280 KDialogQueue::~KDialogQueue() 00281 { 00282 delete d; 00283 _self = 0; 00284 } 00285 00286 // static 00287 void KDialogQueue::queueDialog(QDialog *dialog) 00288 { 00289 KDialogQueue *_this = self(); 00290 _this->d->queue.append(dialog); 00291 QTimer::singleShot(0, _this, SLOT(slotShowQueuedDialog())); 00292 } 00293 00294 void KDialogQueue::slotShowQueuedDialog() 00295 { 00296 if (d->busy) 00297 return; 00298 QDialog *dialog; 00299 do { 00300 if(d->queue.isEmpty()) 00301 return; 00302 dialog = d->queue.first(); 00303 d->queue.pop_front(); 00304 } 00305 while(!dialog); 00306 00307 d->busy = true; 00308 dialog->exec(); 00309 d->busy = false; 00310 delete dialog; 00311 00312 if (!d->queue.isEmpty()) 00313 QTimer::singleShot(20, this, SLOT(slotShowQueuedDialog())); 00314 else 00315 ksdkdq.destructObject(); // Suicide. 00316 } 00317 00318 void KDialog::virtual_hook( int, void* ) 00319 { /*BASE::virtual_hook( id, data );*/ } 00320 00321 #include "kdialog.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 22:56:22 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003