Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

qsplitter.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** $Id: qsplitter.cpp,v 1.2 2004/03/01 17:56:47 chicken Exp $
00003 **
00004 **  Splitter widget
00005 **
00006 **  Created:  980105
00007 **
00008 ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
00009 **
00010 ** This file is part of the widgets module of the Qt GUI Toolkit.
00011 **
00012 ** This file may be distributed under the terms of the Q Public License
00013 ** as defined by Trolltech AS of Norway and appearing in the file
00014 ** LICENSE.QPL included in the packaging of this file.
00015 **
00016 ** This file may be distributed and/or modified under the terms of the
00017 ** GNU General Public License version 2 as published by the Free Software
00018 ** Foundation and appearing in the file LICENSE.GPL included in the
00019 ** packaging of this file.
00020 **
00021 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00022 ** licenses may use this file in accordance with the Qt Commercial License
00023 ** Agreement provided with the Software.
00024 **
00025 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00026 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00027 **
00028 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00029 **   information about Qt Commercial License Agreements.
00030 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00031 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00032 **
00033 ** Contact info@trolltech.com if any conditions of this licensing are
00034 ** not clear to you.
00035 **
00036 **********************************************************************/
00037 #include "qsplitter.h"
00038 
00039 #include "qdrawutil.h"
00040 #include "qlayoutengine_p.h"
00041 #include "qobjectlist.h"
00042 #include "qapplication.h" //sendPostedEvents
00043 
00044 class QSplitterHandle : public QWidget
00045 {
00046 public:
00047     QSplitterHandle( Qt::Orientation o,
00048                        QSplitter *parent, const char* name=0 );
00049     void setOrientation( Qt::Orientation o );
00050     Qt::Orientation orientation() const { return orient; }
00051 
00052     bool opaque() const { return s->opaqueResize(); }
00053 
00054     QSize sizeHint() const;
00055     QSizePolicy sizePolicy() const;
00056 
00057     int id() const { return myId; } // data->list.at(id())->wid == this
00058     void setId( int i ) { myId = i; }
00059 
00060 protected:
00061     void paintEvent( QPaintEvent * );
00062     void mouseMoveEvent( QMouseEvent * );
00063     void mousePressEvent( QMouseEvent * );
00064     void mouseReleaseEvent( QMouseEvent * );
00065 
00066 private:
00067     Qt::Orientation orient;
00068     bool opaq;
00069     int myId;
00070 
00071     QSplitter *s;
00072 };
00073 
00074 static int mouseOffset;
00075 static int opaqueOldPos = -1; //### there's only one mouse, but this is a bit risky
00076 
00077 
00078 QSplitterHandle::QSplitterHandle( Qt::Orientation o,
00079                                   QSplitter *parent, const char * name )
00080     : QWidget( parent, name )
00081 {
00082     s = parent;
00083     setOrientation(o);
00084 }
00085 
00086 QSizePolicy QSplitterHandle::sizePolicy() const
00087 {
00088     //### removeme 3.0
00089     return QWidget::sizePolicy();
00090 }
00091 
00092 QSize QSplitterHandle::sizeHint() const
00093 {
00094     int sw = style().splitterWidth();
00095     return QSize(sw,sw).expandedTo( QApplication::globalStrut() );
00096 }
00097 
00098 void QSplitterHandle::setOrientation( Qt::Orientation o )
00099 {
00100     orient = o;
00101 #ifndef QT_NO_CURSOR
00102     if ( o == QSplitter::Horizontal )
00103         setCursor( splitHCursor );
00104     else
00105         setCursor( splitVCursor );
00106 #endif
00107 }
00108 
00109 
00110 void QSplitterHandle::mouseMoveEvent( QMouseEvent *e )
00111 {
00112     if ( !(e->state()&LeftButton) )
00113         return;
00114     QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
00115                  - mouseOffset;
00116     if ( opaque() ) {
00117         s->moveSplitter( pos, id() );
00118     } else {
00119         int min = pos; int max = pos;
00120         s->getRange( id(), &min, &max );
00121         s->setRubberband( QMAX( min, QMIN(max, pos )));
00122     }
00123 }
00124 
00125 void QSplitterHandle::mousePressEvent( QMouseEvent *e )
00126 {
00127     if ( e->button() == LeftButton )
00128         mouseOffset = s->pick(e->pos());
00129 }
00130 
00131 void QSplitterHandle::mouseReleaseEvent( QMouseEvent *e )
00132 {
00133     if ( !opaque() && e->button() == LeftButton ) {
00134         QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()));
00135         s->setRubberband( -1 );
00136         s->moveSplitter( pos, id() );
00137     }
00138 }
00139 
00140 void QSplitterHandle::paintEvent( QPaintEvent * )
00141 {
00142     QPainter p( this );
00143     s->drawSplitter( &p, 0, 0, width(), height() );
00144 }
00145 
00146 
00147 class QSplitterLayoutStruct
00148 {
00149 public:
00150     QSplitter::ResizeMode mode;
00151     QCOORD sizer;
00152     bool isSplitter;
00153     QWidget *wid;
00154 };
00155 
00156 class QSplitterData
00157 {
00158 public:
00159     QSplitterData() : opaque( FALSE ), firstShow( TRUE ) {}
00160 
00161     QList<QSplitterLayoutStruct> list;
00162     bool opaque;
00163     bool firstShow;
00164 };
00165 
00166 
00167 // NOT REVISED
00216 static QSize minSize( const QWidget *w )
00217 {
00218     QSize min = w->minimumSize();
00219     QSize s;
00220     if ( min.height() <= 0 || min.width() <= 0 )
00221         s = w->minimumSizeHint();
00222     if ( min.height() > 0 )
00223         s.setHeight( min.height() );
00224     if ( min.width() > 0 )
00225         s.setWidth( min.width() );
00226     return s.expandedTo(QSize(0,0));
00227 }
00228 
00233 QSplitter::QSplitter( QWidget *parent, const char *name )
00234     :QFrame(parent,name,WPaintUnclipped)
00235 {
00236      orient = Horizontal;
00237      init();
00238 }
00239 
00240 
00245 QSplitter::QSplitter( Orientation o, QWidget *parent, const char *name )
00246     :QFrame(parent,name,WPaintUnclipped)
00247 {
00248      orient = o;
00249      init();
00250 }
00251 
00252 
00257 QSplitter::~QSplitter()
00258 {
00259     data->list.setAutoDelete( TRUE );
00260     delete data;
00261 }
00262 
00263 
00264 void QSplitter::init()
00265 {
00266     data = new QSplitterData;
00267     if ( orient == Horizontal )
00268         setSizePolicy( QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Minimum) );
00269     else
00270         setSizePolicy( QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed) );
00271 }
00272 
00273 
00288 void QSplitter::setOrientation( Orientation o )
00289 {
00290     if ( orient == o )
00291         return;
00292     orient = o;
00293 
00294     if ( orient == Horizontal )
00295         setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ) );
00296     else
00297         setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
00298 
00299     QSplitterLayoutStruct *s = data->list.first();
00300     while ( s ) {
00301         if ( s->isSplitter )
00302             ((QSplitterHandle*)s->wid)->setOrientation( o );
00303         s = data->list.next();  // ### next at end of loop, no iterator
00304     }
00305     recalc( isVisible() );
00306 }
00307 
00308 
00319 void QSplitter::resizeEvent( QResizeEvent * )
00320 {
00321     doResize();
00322 }
00323 
00324 
00334 QSplitterLayoutStruct *QSplitter::addWidget( QWidget *w, bool first )
00335 {
00336     QSplitterLayoutStruct *s;
00337     QSplitterHandle *newHandle = 0;
00338     if ( data->list.count() > 0 ) {
00339         s = new QSplitterLayoutStruct;
00340         s->mode = KeepSize;
00341         newHandle = new QSplitterHandle( orientation(), this );
00342         s->wid = newHandle;
00343         newHandle->setId(data->list.count());
00344         s->isSplitter = TRUE;
00345         s->sizer = pick( newHandle->sizeHint() );
00346         if ( first )
00347             data->list.insert( 0, s );
00348         else
00349             data->list.append( s );
00350     }
00351     s = new QSplitterLayoutStruct;
00352     s->mode = Stretch;
00353     s->wid = w;
00354     if ( !testWState( WState_Resized ) && w->sizeHint().isValid() )
00355         s->sizer = pick( w->sizeHint() );
00356     else
00357         s->sizer = pick( w->size() );
00358     s->isSplitter = FALSE;
00359     if ( first )
00360         data->list.insert( 0, s );
00361     else
00362         data->list.append( s );
00363     if ( newHandle && isVisible() )
00364         newHandle->show(); //will trigger sending of post events
00365     return s;
00366 }
00367 
00368 
00373 void QSplitter::childEvent( QChildEvent *c )
00374 {
00375     if ( c->type() == QEvent::ChildInserted ) {
00376         if ( !c->child()->isWidgetType() )
00377             return;
00378 
00379         if ( ((QWidget*)c->child())->testWFlags( WType_TopLevel ) )
00380             return;
00381 
00382         QSplitterLayoutStruct *s = data->list.first();
00383         while ( s ) {
00384             if ( s->wid == c->child() )
00385                 return;
00386             s = data->list.next();
00387         }
00388         addWidget( (QWidget*)c->child() );
00389         recalc( isVisible() );
00390 
00391     } else if ( c->type() == QEvent::ChildRemoved ) {
00392         QSplitterLayoutStruct *p = 0;
00393         if ( data->list.count() > 1 )
00394             p = data->list.at(1); //remove handle _after_ first widget.
00395         QSplitterLayoutStruct *s = data->list.first();
00396         while ( s ) {
00397             if ( s->wid == c->child() ) {
00398                 data->list.removeRef( s );
00399                 delete s;
00400                 if ( p && p->isSplitter ) {
00401                     data->list.removeRef( p );
00402                     delete p->wid; //will call childEvent
00403                     delete p;
00404                 }
00405                 recalcId();
00406                 doResize();
00407                 return;
00408             }
00409             p = s;
00410             s = data->list.next();
00411         }
00412     }
00413 }
00414 
00415 
00421 void QSplitter::setRubberband( int p )
00422 {
00423     QPainter paint( this );
00424     paint.setPen( gray );
00425     paint.setBrush( gray );
00426     paint.setRasterOp( XorROP );
00427     QRect r = contentsRect();
00428     const int rBord = 3; //Themable????
00429     const int sw = style().splitterWidth();
00430     if ( orient == Horizontal ) {
00431         if ( opaqueOldPos >= 0 )
00432             paint.drawRect( opaqueOldPos + sw/2 - rBord , r.y(),
00433                             2*rBord, r.height() );
00434         if ( p >= 0 )
00435             paint.drawRect( p  + sw/2 - rBord, r.y(), 2*rBord, r.height() );
00436     } else {
00437         if ( opaqueOldPos >= 0 )
00438             paint.drawRect( r.x(), opaqueOldPos + sw/2 - rBord,
00439                             r.width(), 2*rBord );
00440         if ( p >= 0 )
00441             paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
00442     }
00443     opaqueOldPos = p;
00444 }
00445 
00446 
00449 bool QSplitter::event( QEvent *e )
00450 {
00451     if ( e->type() == QEvent::LayoutHint || ( e->type() == QEvent::Show && data->firstShow ) ) {
00452         recalc( isVisible() );
00453         if ( e->type() == QEvent::Show )
00454             data->firstShow = FALSE;
00455     }
00456     return QWidget::event( e );
00457 }
00458 
00459 
00466 void QSplitter::drawSplitter( QPainter *p,
00467                               QCOORD x, QCOORD y, QCOORD w, QCOORD h )
00468 {
00469     style().drawSplitter( p, x, y, w, h, colorGroup(), orient );
00470 }
00471 
00472 
00479 int QSplitter::idAfter( QWidget* w ) const
00480 {
00481     QSplitterLayoutStruct *s = data->list.first();
00482     bool seen_w = FALSE;
00483     while ( s ) {
00484         if ( s->isSplitter && seen_w )
00485             return data->list.at();
00486         if ( !s->isSplitter && s->wid == w )
00487             seen_w = TRUE;
00488         s = data->list.next();
00489     }
00490     return 0;
00491 }
00492 
00493 
00501 void QSplitter::moveSplitter( QCOORD p, int id )
00502 {
00503     p = adjustPos( p, id );
00504 
00505     QSplitterLayoutStruct *s = data->list.at(id);
00506     int oldP = orient == Horizontal? s->wid->x() : s->wid->y();
00507     bool upLeft = p < oldP;
00508 
00509     moveAfter( p, id, upLeft );
00510     moveBefore( p-1, id-1, upLeft );
00511 
00512     storeSizes();
00513 }
00514 
00515 
00516 void QSplitter::setG( QWidget *w, int p, int s )
00517 {
00518     if ( orient == Horizontal )
00519         w->setGeometry( p, contentsRect().y(), s, contentsRect().height() );
00520     else
00521         w->setGeometry( contentsRect().x(), p, contentsRect().width(), s );
00522 }
00523 
00524 
00531 void QSplitter::moveBefore( int pos, int id, bool upLeft )
00532 {
00533     QSplitterLayoutStruct *s = data->list.at(id);
00534     if ( !s )
00535         return;
00536     QWidget *w = s->wid;
00537     if ( w->isHidden() ) {
00538         moveBefore( pos, id-1, upLeft );
00539     } else if ( s->isSplitter ) {
00540         int dd = s->sizer;
00541         if ( upLeft ) {
00542             setG( w, pos-dd+1, dd );
00543             moveBefore( pos-dd, id-1, upLeft );
00544         } else {
00545             moveBefore( pos-dd, id-1, upLeft );
00546             setG( w, pos-dd+1, dd );
00547         }
00548     } else {
00549         int left = pick( w->pos() );
00550         int dd = pos - left + 1;
00551         dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
00552         int newLeft = pos-dd+1;
00553         setG( w, newLeft, dd );
00554         if ( left != newLeft )
00555             moveBefore( newLeft-1, id-1, upLeft );
00556     }
00557 }
00558 
00559 
00566 void QSplitter::moveAfter( int pos, int id, bool upLeft )
00567 {
00568     QSplitterLayoutStruct *s = id < int(data->list.count()) ?
00569                                data->list.at(id) : 0;
00570     if ( !s )
00571         return;
00572     QWidget *w = s->wid;
00573     if ( w->isHidden() ) {
00574         moveAfter( pos, id+1, upLeft );
00575     } else if ( pick( w->pos() ) == pos ) {
00576         //No need to do anything if it's already there.
00577         return;
00578     } else if ( s->isSplitter ) {
00579         int dd = s->sizer;
00580         if ( upLeft ) {
00581             setG( w, pos, dd );
00582             moveAfter( pos+dd, id+1, upLeft );
00583         } else {
00584             moveAfter( pos+dd, id+1, upLeft );
00585             setG( w, pos, dd );
00586         }
00587     } else {
00588         int right = pick( w->geometry().bottomRight() );
00589 
00590         int dd = right - pos + 1;
00591         dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
00592         int newRight = pos+dd-1;
00593         setG( w, pos, dd );
00594         moveAfter( newRight+1, id+1, upLeft );
00595     }
00596 }
00597 
00598 
00605 void QSplitter::getRange( int id, int *min, int *max )
00606 {
00607     int minB = 0;       //before
00608     int maxB = 0;
00609     int minA = 0;
00610     int maxA = 0;       //after
00611     int n = data->list.count();
00612     if ( id < 0 || id >= n )
00613         return;
00614     int i;
00615     for ( i = 0; i < id; i++ ) {
00616         QSplitterLayoutStruct *s = data->list.at(i);
00617         if ( s->wid->isHidden() ) {
00618             //ignore
00619         } else if ( s->isSplitter ) {
00620             minB += s->sizer;
00621             maxB += s->sizer;
00622         } else {
00623             minB += pick( minSize(s->wid) );
00624             maxB += pick( s->wid->maximumSize() );
00625         }
00626     }
00627     for ( i = id; i < n; i++ ) {
00628         QSplitterLayoutStruct *s = data->list.at(i);
00629         if ( s->wid->isHidden() ) {
00630             //ignore
00631         } else  if ( s->isSplitter ) {
00632             minA += s->sizer;
00633             maxA += s->sizer;
00634         } else {
00635             minA += pick( minSize(s->wid) );
00636             maxA += pick( s->wid->maximumSize() );
00637         }
00638     }
00639     QRect r = contentsRect();
00640     if ( min )
00641         *min = pick(r.topLeft()) + QMAX( minB, pick(r.size())-maxA );
00642     if ( max )
00643         *max = pick(r.topLeft()) + QMIN( maxB, pick(r.size())-minA );
00644 
00645 }
00646 
00647 
00654 int QSplitter::adjustPos( int p, int id )
00655 {
00656     int min = 0;
00657     int max = 0;
00658     getRange( id, &min, &max );
00659     p = QMAX( min, QMIN( p, max ) );
00660 
00661     return p;
00662 }
00663 
00664 
00665 void QSplitter::doResize()
00666 {
00667     QRect r = contentsRect();
00668     int i;
00669     int n = data->list.count();
00670     QArray<QLayoutStruct> a( n );
00671     for ( i = 0; i< n; i++ ) {
00672         a[i].init();
00673         QSplitterLayoutStruct *s = data->list.at(i);
00674         if ( s->wid->isHidden() ) {
00675             a[i].stretch = 0;
00676             a[i].sizeHint = a[i].minimumSize = 0;
00677             a[i].maximumSize = 0;
00678         } else if ( s->isSplitter ) {
00679             a[i].stretch = 0;
00680             a[i].sizeHint = a[i].minimumSize = a[i].maximumSize = s->sizer;
00681             a[i].empty = FALSE;
00682         } else if ( s->mode == KeepSize ) {
00683             a[i].stretch = 0;
00684             a[i].minimumSize = pick( minSize(s->wid) );
00685             a[i].sizeHint = s->sizer;
00686             a[i].maximumSize = pick( s->wid->maximumSize() );
00687             a[i].empty = FALSE;
00688         } else if ( s->mode == FollowSizeHint ) {
00689             a[i].stretch = 0;
00690             a[i].minimumSize = a[i].sizeHint = pick( s->wid->sizeHint() );
00691             a[i].maximumSize = pick( s->wid->maximumSize() );
00692             a[i].empty = FALSE;
00693         } else { //proportional
00694             a[i].stretch = s->sizer;
00695             a[i].maximumSize = pick( s->wid->maximumSize() );
00696             a[i].sizeHint = a[i].minimumSize = pick( minSize(s->wid) );
00697             a[i].empty = FALSE;
00698         }
00699     }
00700 
00701     qGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 );
00702     for ( i = 0; i< n; i++ ) {
00703         QSplitterLayoutStruct *s = data->list.at(i);
00704         if ( orient == Horizontal )
00705             s->wid->setGeometry( a[i].pos, r.top(), a[i].size, r.height() );
00706         else
00707             s->wid->setGeometry( r.left(), a[i].pos, r.width(), a[i].size );
00708     }
00709 
00710 }
00711 
00712 
00713 void QSplitter::recalc( bool update )
00714 {
00715     int fi = 2*frameWidth();
00716     int maxl = fi;
00717     int minl = fi;
00718     int maxt = QWIDGETSIZE_MAX;
00719     int mint = fi;
00720     int n = data->list.count();
00721     bool first = TRUE;
00722     /*
00723       The splitter before a hidden widget is always hidden.
00724       The splitter before the first visible widget is hidden.
00725       The splitter before any other visible widget is visible.
00726     */
00727     for ( int i = 0; i< n; i++ ) {
00728         QSplitterLayoutStruct *s = data->list.at(i);
00729         if ( !s->isSplitter ) {
00730             QSplitterLayoutStruct *p = (i > 0) ? p = data->list.at( i-1 ) : 0;
00731             if ( p && p->isSplitter )
00732                 if ( first || s->wid->isHidden() )
00733                     p->wid->hide(); //may trigger new recalc
00734                 else
00735                     p->wid->show(); //may trigger new recalc
00736             if ( !s->wid->isHidden() )
00737                 first = FALSE;
00738         }
00739     }
00740 
00741     bool empty=TRUE;
00742     for ( int j = 0; j< n; j++ ) {
00743         QSplitterLayoutStruct *s = data->list.at(j);
00744         if ( !s->wid->isHidden() ) {
00745             empty = FALSE;
00746             if ( s->isSplitter ) {
00747                 minl += s->sizer;
00748                 maxl += s->sizer;
00749             } else {
00750                 QSize minS = minSize(s->wid);
00751                 minl += pick( minS );
00752                 maxl += pick( s->wid->maximumSize() );
00753                 mint = QMAX( mint, trans( minS ));
00754                 int tm = trans( s->wid->maximumSize() );
00755                 if ( tm > 0 )
00756                     maxt = QMIN( maxt, tm );
00757             }
00758         }
00759     }
00760     if ( empty )
00761         maxl = maxt = 0;
00762     else
00763         maxl = QMIN( maxl, QWIDGETSIZE_MAX );
00764     if ( maxt < mint )
00765         maxt = mint;
00766 
00767     if ( orient == Horizontal ) {
00768         setMaximumSize( maxl, maxt );
00769         setMinimumSize( minl, mint );
00770     } else {
00771         setMaximumSize( maxt, maxl );
00772         setMinimumSize( mint, minl );
00773     }
00774     if ( update )
00775         doResize();
00776 }
00777 
00801 void QSplitter::setResizeMode( QWidget *w, ResizeMode mode )
00802 {
00803     processChildEvents();
00804     QSplitterLayoutStruct *s = data->list.first();
00805     while ( s ) {
00806         if ( s->wid == w  ) {
00807             s->mode = mode;
00808             return;
00809         }
00810         s = data->list.next();
00811     }
00812     s = addWidget( w, TRUE );
00813     s->mode = mode;
00814 }
00815 
00816 
00823 bool QSplitter::opaqueResize() const
00824 {
00825     return data->opaque;
00826 }
00827 
00828 
00835 void QSplitter::setOpaqueResize( bool on )
00836 {
00837     data->opaque = on;
00838 }
00839 
00840 
00845 void QSplitter::moveToFirst( QWidget *w )
00846 {
00847     processChildEvents();
00848     bool found = FALSE;
00849     QSplitterLayoutStruct *s = data->list.first();
00850     while ( s ) {
00851         if ( s->wid == w  ) {
00852             found = TRUE;
00853             QSplitterLayoutStruct *p = data->list.prev();
00854             if ( p ) { // not already at first place
00855                 data->list.take(); //take p
00856                 data->list.take(); // take s
00857                 data->list.insert( 0, p );
00858                 data->list.insert( 0, s );
00859             }
00860             break;
00861         }
00862         s = data->list.next();
00863     }
00864      if ( !found )
00865         addWidget( w, TRUE );
00866      recalcId();
00867 }
00868 
00869 
00874 void QSplitter::moveToLast( QWidget *w )
00875 {
00876     processChildEvents();
00877     bool found = FALSE;
00878     QSplitterLayoutStruct *s = data->list.first();
00879     while ( s ) {
00880         if ( s->wid == w  ) {
00881             found = TRUE;
00882             data->list.take(); // take s
00883             QSplitterLayoutStruct *p = data->list.current();
00884             if ( p ) { // the splitter handle after s
00885                 data->list.take(); //take p
00886                 data->list.append( p );
00887             }
00888             data->list.append( s );
00889             break;
00890         }
00891         s = data->list.next();
00892     }
00893      if ( !found )
00894         addWidget( w);
00895      recalcId();
00896 }
00897 
00898 
00899 void QSplitter::recalcId()
00900 {
00901     int n = data->list.count();
00902     for ( int i = 0; i < n; i++ ) {
00903         QSplitterLayoutStruct *s = data->list.at(i);
00904         if ( s->isSplitter )
00905             ((QSplitterHandle*)s->wid)->setId(i);
00906     }
00907 }
00908 
00909 
00912 QSize QSplitter::sizeHint() const
00913 {
00914     constPolish();
00915     int l = 0;
00916     int t = 0;
00917     if ( children() ) {
00918         const QObjectList * c = children();
00919         QObjectListIt it( *c );
00920         QObject * o;
00921 
00922         while( (o=it.current()) != 0 ) {
00923             ++it;
00924             if ( o->isWidgetType() &&
00925                  !((QWidget*)o)->isHidden() ) {
00926                 QSize s = ((QWidget*)o)->sizeHint();
00927                 if ( s.isValid() ) {
00928                     l += pick( s );
00929                     t = QMAX( t, trans( s ) );
00930                 }
00931             }
00932         }
00933     }
00934     return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
00935 }
00936 
00937 
00942 QSize QSplitter::minimumSizeHint() const
00943 {
00944     constPolish();
00945     int l = 0;
00946     int t = 0;
00947     if ( children() ) {
00948         const QObjectList * c = children();
00949         QObjectListIt it( *c );
00950         QObject * o;
00951 
00952         while( (o=it.current()) != 0 ) {
00953             ++it;
00954             if ( o->isWidgetType() &&
00955                  !((QWidget*)o)->isHidden() ) {
00956                 QSize s = minSize((QWidget*)o);
00957                 if ( s.isValid() ) {
00958                     l += pick( s );
00959                     t = QMAX( t, trans( s ) );
00960                 }
00961             }
00962         }
00963     }
00964     return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
00965 }
00966 
00967 
00968 
00971 QSizePolicy QSplitter::sizePolicy() const
00972 {
00973     return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
00974 }
00975 
00976 
00981 void QSplitter::storeSizes()
00982 {
00983     QSplitterLayoutStruct *s = data->list.first();
00984     while ( s ) {
00985         if ( !s->isSplitter )
00986             s->sizer = pick( s->wid->size() );
00987         s = data->list.next();
00988     }
00989 }
00990 
00991 
00992 #if 0 // ### remove this code ASAP
00993 
01001 void QSplitter::setHidden( QWidget *w, bool hide )
01002 {
01003     if ( w == w1 ) {
01004         w1show = !hide;
01005     } else if ( w == w2 ) {
01006         w2show = !hide;
01007     } else {
01008 #ifdef CHECK_RANGE
01009         qWarning( "QSplitter::setHidden(), unknown widget" );
01010 #endif
01011         return;
01012     }
01013     if ( hide )
01014         w->hide();
01015     else
01016         w->show();
01017     recalc( TRUE );
01018 }
01019 
01020 
01025 bool QSplitter::isHidden( QWidget *w ) const
01026 {
01027     if ( w == w1 )
01028         return !w1show;
01029      else if ( w == w2 )
01030         return !w2show;
01031 #ifdef CHECK_RANGE
01032     else
01033         qWarning( "QSplitter::isHidden(), unknown widget" );
01034 #endif
01035     return FALSE;
01036 }
01037 #endif
01038 
01039 
01050 QValueList<int> QSplitter::sizes() const
01051 {
01052     if ( !testWState(WState_Polished) ) {
01053         QWidget* that = (QWidget*) this;
01054         that->polish();
01055     }
01056     QValueList<int> list;
01057     QSplitterLayoutStruct *s = data->list.first();
01058     while ( s ) {
01059         if ( !s->isSplitter )
01060             list.append( s->sizer );
01061         s = data->list.next();
01062     }
01063     return list;
01064 }
01065 
01066 
01067 
01081 void QSplitter::setSizes( QValueList<int> list )
01082 {
01083     processChildEvents();
01084     QValueList<int>::Iterator it = list.begin();
01085     QSplitterLayoutStruct *s = data->list.first();
01086     while ( s && it != list.end() ) {
01087         if ( !s->isSplitter ) {
01088             s->sizer = *it;
01089             ++it;
01090         }
01091         s = data->list.next();
01092     }
01093     doResize();
01094 }
01095 
01096 
01102 void QSplitter::processChildEvents()
01103 {
01104     QApplication::sendPostedEvents( this, QEvent::ChildInserted );
01105 }
01106 
01107 
01112 void QSplitter::styleChange( QStyle& old )
01113 {
01114     int sw = style().splitterWidth();
01115     QSplitterLayoutStruct *s = data->list.first();
01116     while ( s ) {
01117         if ( s->isSplitter )
01118             s->sizer = sw;
01119         s = data->list.next();
01120     }
01121     doResize();
01122     QFrame::styleChange( old );
01123 }
01124 

Generated on Sat Nov 5 16:16:31 2005 for OPIE by  doxygen 1.4.2