summaryrefslogtreecommitdiff
path: root/libqtaux/qsplitter.cpp
Unidiff
Diffstat (limited to 'libqtaux/qsplitter.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libqtaux/qsplitter.cpp4
1 files changed, 0 insertions, 4 deletions
diff --git a/libqtaux/qsplitter.cpp b/libqtaux/qsplitter.cpp
index ab6e01b..39321f8 100644
--- a/libqtaux/qsplitter.cpp
+++ b/libqtaux/qsplitter.cpp
@@ -1,1128 +1,1124 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Splitter widget 4** Splitter widget
5** 5**
6** Created: 980105 6** Created: 980105
7** 7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the widgets module of the Qt GUI Toolkit. 10** This file is part of the widgets module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition 21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License 22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software. 23** Agreement provided with the Software.
24** 24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27** 27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for 28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements. 29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information. 30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information. 31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32** 32**
33** Contact info@trolltech.com if any conditions of this licensing are 33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37#include "qsplitter.h" 37#include "qsplitter.h"
38 38
39#include "qpainter.h"
40#include "qdrawutil.h" 39#include "qdrawutil.h"
41#include "qbitmap.h"
42#include "qlayoutengine_p.h" 40#include "qlayoutengine_p.h"
43#include "qlist.h"
44#include "qarray.h"
45#include "qobjectlist.h" 41#include "qobjectlist.h"
46#include "qapplication.h" //sendPostedEvents 42#include "qapplication.h" //sendPostedEvents
47 43
48class QSplitterHandle : public QWidget 44class QSplitterHandle : public QWidget
49{ 45{
50public: 46public:
51 QSplitterHandle( Qt::Orientation o, 47 QSplitterHandle( Qt::Orientation o,
52 QSplitter *parent, const char* name=0 ); 48 QSplitter *parent, const char* name=0 );
53 void setOrientation( Qt::Orientation o ); 49 void setOrientation( Qt::Orientation o );
54 Qt::Orientation orientation() const { return orient; } 50 Qt::Orientation orientation() const { return orient; }
55 51
56 bool opaque() const { return s->opaqueResize(); } 52 bool opaque() const { return s->opaqueResize(); }
57 53
58 QSize sizeHint() const; 54 QSize sizeHint() const;
59 QSizePolicy sizePolicy() const; 55 QSizePolicy sizePolicy() const;
60 56
61 int id() const { return myId; } // data->list.at(id())->wid == this 57 int id() const { return myId; } // data->list.at(id())->wid == this
62 void setId( int i ) { myId = i; } 58 void setId( int i ) { myId = i; }
63 59
64protected: 60protected:
65 void paintEvent( QPaintEvent * ); 61 void paintEvent( QPaintEvent * );
66 void mouseMoveEvent( QMouseEvent * ); 62 void mouseMoveEvent( QMouseEvent * );
67 void mousePressEvent( QMouseEvent * ); 63 void mousePressEvent( QMouseEvent * );
68 void mouseReleaseEvent( QMouseEvent * ); 64 void mouseReleaseEvent( QMouseEvent * );
69 65
70private: 66private:
71 Qt::Orientation orient; 67 Qt::Orientation orient;
72 bool opaq; 68 bool opaq;
73 int myId; 69 int myId;
74 70
75 QSplitter *s; 71 QSplitter *s;
76}; 72};
77 73
78static int mouseOffset; 74static int mouseOffset;
79static int opaqueOldPos = -1; //### there's only one mouse, but this is a bit risky 75static int opaqueOldPos = -1; //### there's only one mouse, but this is a bit risky
80 76
81 77
82QSplitterHandle::QSplitterHandle( Qt::Orientation o, 78QSplitterHandle::QSplitterHandle( Qt::Orientation o,
83 QSplitter *parent, const char * name ) 79 QSplitter *parent, const char * name )
84 : QWidget( parent, name ) 80 : QWidget( parent, name )
85{ 81{
86 s = parent; 82 s = parent;
87 setOrientation(o); 83 setOrientation(o);
88} 84}
89 85
90QSizePolicy QSplitterHandle::sizePolicy() const 86QSizePolicy QSplitterHandle::sizePolicy() const
91{ 87{
92 //### removeme 3.0 88 //### removeme 3.0
93 return QWidget::sizePolicy(); 89 return QWidget::sizePolicy();
94} 90}
95 91
96QSize QSplitterHandle::sizeHint() const 92QSize QSplitterHandle::sizeHint() const
97{ 93{
98 int sw = style().splitterWidth(); 94 int sw = style().splitterWidth();
99 return QSize(sw,sw).expandedTo( QApplication::globalStrut() ); 95 return QSize(sw,sw).expandedTo( QApplication::globalStrut() );
100} 96}
101 97
102void QSplitterHandle::setOrientation( Qt::Orientation o ) 98void QSplitterHandle::setOrientation( Qt::Orientation o )
103{ 99{
104 orient = o; 100 orient = o;
105#ifndef QT_NO_CURSOR 101#ifndef QT_NO_CURSOR
106 if ( o == QSplitter::Horizontal ) 102 if ( o == QSplitter::Horizontal )
107 setCursor( splitHCursor ); 103 setCursor( splitHCursor );
108 else 104 else
109 setCursor( splitVCursor ); 105 setCursor( splitVCursor );
110#endif 106#endif
111} 107}
112 108
113 109
114void QSplitterHandle::mouseMoveEvent( QMouseEvent *e ) 110void QSplitterHandle::mouseMoveEvent( QMouseEvent *e )
115{ 111{
116 if ( !(e->state()&LeftButton) ) 112 if ( !(e->state()&LeftButton) )
117 return; 113 return;
118 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos())) 114 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
119 - mouseOffset; 115 - mouseOffset;
120 if ( opaque() ) { 116 if ( opaque() ) {
121 s->moveSplitter( pos, id() ); 117 s->moveSplitter( pos, id() );
122 } else { 118 } else {
123 int min = pos; int max = pos; 119 int min = pos; int max = pos;
124 s->getRange( id(), &min, &max ); 120 s->getRange( id(), &min, &max );
125 s->setRubberband( QMAX( min, QMIN(max, pos ))); 121 s->setRubberband( QMAX( min, QMIN(max, pos )));
126 } 122 }
127} 123}
128 124
129void QSplitterHandle::mousePressEvent( QMouseEvent *e ) 125void QSplitterHandle::mousePressEvent( QMouseEvent *e )
130{ 126{
131 if ( e->button() == LeftButton ) 127 if ( e->button() == LeftButton )
132 mouseOffset = s->pick(e->pos()); 128 mouseOffset = s->pick(e->pos());
133} 129}
134 130
135void QSplitterHandle::mouseReleaseEvent( QMouseEvent *e ) 131void QSplitterHandle::mouseReleaseEvent( QMouseEvent *e )
136{ 132{
137 if ( !opaque() && e->button() == LeftButton ) { 133 if ( !opaque() && e->button() == LeftButton ) {
138 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos())); 134 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()));
139 s->setRubberband( -1 ); 135 s->setRubberband( -1 );
140 s->moveSplitter( pos, id() ); 136 s->moveSplitter( pos, id() );
141 } 137 }
142} 138}
143 139
144void QSplitterHandle::paintEvent( QPaintEvent * ) 140void QSplitterHandle::paintEvent( QPaintEvent * )
145{ 141{
146 QPainter p( this ); 142 QPainter p( this );
147 s->drawSplitter( &p, 0, 0, width(), height() ); 143 s->drawSplitter( &p, 0, 0, width(), height() );
148} 144}
149 145
150 146
151class QSplitterLayoutStruct 147class QSplitterLayoutStruct
152{ 148{
153public: 149public:
154 QSplitter::ResizeMode mode; 150 QSplitter::ResizeMode mode;
155 QCOORD sizer; 151 QCOORD sizer;
156 bool isSplitter; 152 bool isSplitter;
157 QWidget *wid; 153 QWidget *wid;
158}; 154};
159 155
160class QSplitterData 156class QSplitterData
161{ 157{
162public: 158public:
163 QSplitterData() : opaque( FALSE ), firstShow( TRUE ) {} 159 QSplitterData() : opaque( FALSE ), firstShow( TRUE ) {}
164 160
165 QList<QSplitterLayoutStruct> list; 161 QList<QSplitterLayoutStruct> list;
166 bool opaque; 162 bool opaque;
167 bool firstShow; 163 bool firstShow;
168}; 164};
169 165
170 166
171// NOT REVISED 167// NOT REVISED
172/*! 168/*!
173 \class QSplitter qsplitter.h 169 \class QSplitter qsplitter.h
174 \brief The QSplitter class implements a splitter widget. 170 \brief The QSplitter class implements a splitter widget.
175 171
176 \ingroup organizers 172 \ingroup organizers
177 173
178 A splitter lets the user control the size of child widgets by 174 A splitter lets the user control the size of child widgets by
179 dragging the boundary between the children. Any number of widgets 175 dragging the boundary between the children. Any number of widgets
180 may be controlled. 176 may be controlled.
181 177
182 To show a QListBox, a QListView and a QMultiLineEdit side by side: 178 To show a QListBox, a QListView and a QMultiLineEdit side by side:
183 179
184 \code 180 \code
185 QSplitter *split = new QSplitter( parent ); 181 QSplitter *split = new QSplitter( parent );
186 QListBox *lb = new QListBox( split ); 182 QListBox *lb = new QListBox( split );
187 QListView *lv = new QListView( split ); 183 QListView *lv = new QListView( split );
188 QMultiLineEdit *ed = new QMultiLineEdit( split ); 184 QMultiLineEdit *ed = new QMultiLineEdit( split );
189 \endcode 185 \endcode
190 186
191 In QSplitter the boundary can be either horizontal or vertical. The 187 In QSplitter the boundary can be either horizontal or vertical. The
192 default is horizontal (the children are side by side) and you 188 default is horizontal (the children are side by side) and you
193 can use setOrientation( QSplitter::Vertical ) to set it to vertical. 189 can use setOrientation( QSplitter::Vertical ) to set it to vertical.
194 190
195 By default, all widgets can be as large or as small as the user 191 By default, all widgets can be as large or as small as the user
196 wishes, down to \link QWidget::minimumSizeHint() minimumSizeHint()\endlink. 192 wishes, down to \link QWidget::minimumSizeHint() minimumSizeHint()\endlink.
197 You can naturally use setMinimumSize() and/or 193 You can naturally use setMinimumSize() and/or
198 setMaximumSize() on the children. Use setResizeMode() to specify that 194 setMaximumSize() on the children. Use setResizeMode() to specify that
199 a widget should keep its size when the splitter is resized. 195 a widget should keep its size when the splitter is resized.
200 196
201 QSplitter normally resizes the children only at the end of a 197 QSplitter normally resizes the children only at the end of a
202 resize operation, but if you call setOpaqueResize( TRUE ), the 198 resize operation, but if you call setOpaqueResize( TRUE ), the
203 widgets are resized as often as possible. 199 widgets are resized as often as possible.
204 200
205 The initial distribution of size between the widgets is determined 201 The initial distribution of size between the widgets is determined
206 by the initial size of each widget. You can also use setSizes() to 202 by the initial size of each widget. You can also use setSizes() to
207 set the sizes of all the widgets. The function sizes() returns the 203 set the sizes of all the widgets. The function sizes() returns the
208 sizes set by the user. 204 sizes set by the user.
209 205
210 If you hide() a child, its space will be distributed among the other 206 If you hide() a child, its space will be distributed among the other
211 children. When you show() it again, it will be reinstated. 207 children. When you show() it again, it will be reinstated.
212 208
213 <img src=qsplitter-m.png> <img src=qsplitter-w.png> 209 <img src=qsplitter-m.png> <img src=qsplitter-w.png>
214 210
215 \sa QTabBar 211 \sa QTabBar
216*/ 212*/
217 213
218 214
219 215
220static QSize minSize( const QWidget *w ) 216static QSize minSize( const QWidget *w )
221{ 217{
222 QSize min = w->minimumSize(); 218 QSize min = w->minimumSize();
223 QSize s; 219 QSize s;
224 if ( min.height() <= 0 || min.width() <= 0 ) 220 if ( min.height() <= 0 || min.width() <= 0 )
225 s = w->minimumSizeHint(); 221 s = w->minimumSizeHint();
226 if ( min.height() > 0 ) 222 if ( min.height() > 0 )
227 s.setHeight( min.height() ); 223 s.setHeight( min.height() );
228 if ( min.width() > 0 ) 224 if ( min.width() > 0 )
229 s.setWidth( min.width() ); 225 s.setWidth( min.width() );
230 return s.expandedTo(QSize(0,0)); 226 return s.expandedTo(QSize(0,0));
231} 227}
232 228
233/*! 229/*!
234 Constructs a horizontal splitter. 230 Constructs a horizontal splitter.
235*/ 231*/
236 232
237QSplitter::QSplitter( QWidget *parent, const char *name ) 233QSplitter::QSplitter( QWidget *parent, const char *name )
238 :QFrame(parent,name,WPaintUnclipped) 234 :QFrame(parent,name,WPaintUnclipped)
239{ 235{
240 orient = Horizontal; 236 orient = Horizontal;
241 init(); 237 init();
242} 238}
243 239
244 240
245/*! 241/*!
246 Constructs splitter with orientation \a o. 242 Constructs splitter with orientation \a o.
247*/ 243*/
248 244
249QSplitter::QSplitter( Orientation o, QWidget *parent, const char *name ) 245QSplitter::QSplitter( Orientation o, QWidget *parent, const char *name )
250 :QFrame(parent,name,WPaintUnclipped) 246 :QFrame(parent,name,WPaintUnclipped)
251{ 247{
252 orient = o; 248 orient = o;
253 init(); 249 init();
254} 250}
255 251
256 252
257/*! 253/*!
258 Destructs the splitter. 254 Destructs the splitter.
259*/ 255*/
260 256
261QSplitter::~QSplitter() 257QSplitter::~QSplitter()
262{ 258{
263 data->list.setAutoDelete( TRUE ); 259 data->list.setAutoDelete( TRUE );
264 delete data; 260 delete data;
265} 261}
266 262
267 263
268void QSplitter::init() 264void QSplitter::init()
269{ 265{
270 data = new QSplitterData; 266 data = new QSplitterData;
271 if ( orient == Horizontal ) 267 if ( orient == Horizontal )
272 setSizePolicy( QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Minimum) ); 268 setSizePolicy( QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Minimum) );
273 else 269 else
274 setSizePolicy( QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed) ); 270 setSizePolicy( QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed) );
275} 271}
276 272
277 273
278/*! 274/*!
279 \fn void QSplitter::refresh() 275 \fn void QSplitter::refresh()
280 276
281 Updates the splitter state. You should not need to call this 277 Updates the splitter state. You should not need to call this
282 function during normal use of the splitter. 278 function during normal use of the splitter.
283*/ 279*/
284 280
285 281
286/*! Sets the orientation to \a o. By default the orientation is 282/*! Sets the orientation to \a o. By default the orientation is
287 horizontal (the widgets are side by side). 283 horizontal (the widgets are side by side).
288 284
289 \sa orientation() 285 \sa orientation()
290*/ 286*/
291 287
292void QSplitter::setOrientation( Orientation o ) 288void QSplitter::setOrientation( Orientation o )
293{ 289{
294 if ( orient == o ) 290 if ( orient == o )
295 return; 291 return;
296 orient = o; 292 orient = o;
297 293
298 if ( orient == Horizontal ) 294 if ( orient == Horizontal )
299 setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ) ); 295 setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ) );
300 else 296 else
301 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) ); 297 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
302 298
303 QSplitterLayoutStruct *s = data->list.first(); 299 QSplitterLayoutStruct *s = data->list.first();
304 while ( s ) { 300 while ( s ) {
305 if ( s->isSplitter ) 301 if ( s->isSplitter )
306 ((QSplitterHandle*)s->wid)->setOrientation( o ); 302 ((QSplitterHandle*)s->wid)->setOrientation( o );
307 s = data->list.next(); // ### next at end of loop, no iterator 303 s = data->list.next(); // ### next at end of loop, no iterator
308 } 304 }
309 recalc( isVisible() ); 305 recalc( isVisible() );
310} 306}
311 307
312 308
313/*! 309/*!
314 \fn Orientation QSplitter::orientation() const 310 \fn Orientation QSplitter::orientation() const
315 311
316 Returns the orientation (\c Horizontal or \c Vertical) of the splitter. 312 Returns the orientation (\c Horizontal or \c Vertical) of the splitter.
317 \sa setOrientation() 313 \sa setOrientation()
318*/ 314*/
319 315
320/*! 316/*!
321 \reimp 317 \reimp
322*/ 318*/
323void QSplitter::resizeEvent( QResizeEvent * ) 319void QSplitter::resizeEvent( QResizeEvent * )
324{ 320{
325 doResize(); 321 doResize();
326} 322}
327 323
328 324
329/*! 325/*!
330 Inserts the widget \a w at the end, or at the beginning if \a first is TRUE 326 Inserts the widget \a w at the end, or at the beginning if \a first is TRUE
331 327
332 It is the responsibility of the caller of this function to make sure 328 It is the responsibility of the caller of this function to make sure
333 that \a w is not already in the splitter, and to call recalcId if 329 that \a w is not already in the splitter, and to call recalcId if
334 needed. (If \a first is TRUE, then recalcId is very probably 330 needed. (If \a first is TRUE, then recalcId is very probably
335 needed.) 331 needed.)
336*/ 332*/
337 333
338QSplitterLayoutStruct *QSplitter::addWidget( QWidget *w, bool first ) 334QSplitterLayoutStruct *QSplitter::addWidget( QWidget *w, bool first )
339{ 335{
340 QSplitterLayoutStruct *s; 336 QSplitterLayoutStruct *s;
341 QSplitterHandle *newHandle = 0; 337 QSplitterHandle *newHandle = 0;
342 if ( data->list.count() > 0 ) { 338 if ( data->list.count() > 0 ) {
343 s = new QSplitterLayoutStruct; 339 s = new QSplitterLayoutStruct;
344 s->mode = KeepSize; 340 s->mode = KeepSize;
345 newHandle = new QSplitterHandle( orientation(), this ); 341 newHandle = new QSplitterHandle( orientation(), this );
346 s->wid = newHandle; 342 s->wid = newHandle;
347 newHandle->setId(data->list.count()); 343 newHandle->setId(data->list.count());
348 s->isSplitter = TRUE; 344 s->isSplitter = TRUE;
349 s->sizer = pick( newHandle->sizeHint() ); 345 s->sizer = pick( newHandle->sizeHint() );
350 if ( first ) 346 if ( first )
351 data->list.insert( 0, s ); 347 data->list.insert( 0, s );
352 else 348 else
353 data->list.append( s ); 349 data->list.append( s );
354 } 350 }
355 s = new QSplitterLayoutStruct; 351 s = new QSplitterLayoutStruct;
356 s->mode = Stretch; 352 s->mode = Stretch;
357 s->wid = w; 353 s->wid = w;
358 if ( !testWState( WState_Resized ) && w->sizeHint().isValid() ) 354 if ( !testWState( WState_Resized ) && w->sizeHint().isValid() )
359 s->sizer = pick( w->sizeHint() ); 355 s->sizer = pick( w->sizeHint() );
360 else 356 else
361 s->sizer = pick( w->size() ); 357 s->sizer = pick( w->size() );
362 s->isSplitter = FALSE; 358 s->isSplitter = FALSE;
363 if ( first ) 359 if ( first )
364 data->list.insert( 0, s ); 360 data->list.insert( 0, s );
365 else 361 else
366 data->list.append( s ); 362 data->list.append( s );
367 if ( newHandle && isVisible() ) 363 if ( newHandle && isVisible() )
368 newHandle->show(); //will trigger sending of post events 364 newHandle->show(); //will trigger sending of post events
369 return s; 365 return s;
370} 366}
371 367
372 368
373/*! 369/*!
374 Tells the splitter that a child widget has been inserted/removed. 370 Tells the splitter that a child widget has been inserted/removed.
375*/ 371*/
376 372
377void QSplitter::childEvent( QChildEvent *c ) 373void QSplitter::childEvent( QChildEvent *c )
378{ 374{
379 if ( c->type() == QEvent::ChildInserted ) { 375 if ( c->type() == QEvent::ChildInserted ) {
380 if ( !c->child()->isWidgetType() ) 376 if ( !c->child()->isWidgetType() )
381 return; 377 return;
382 378
383 if ( ((QWidget*)c->child())->testWFlags( WType_TopLevel ) ) 379 if ( ((QWidget*)c->child())->testWFlags( WType_TopLevel ) )
384 return; 380 return;
385 381
386 QSplitterLayoutStruct *s = data->list.first(); 382 QSplitterLayoutStruct *s = data->list.first();
387 while ( s ) { 383 while ( s ) {
388 if ( s->wid == c->child() ) 384 if ( s->wid == c->child() )
389 return; 385 return;
390 s = data->list.next(); 386 s = data->list.next();
391 } 387 }
392 addWidget( (QWidget*)c->child() ); 388 addWidget( (QWidget*)c->child() );
393 recalc( isVisible() ); 389 recalc( isVisible() );
394 390
395 } else if ( c->type() == QEvent::ChildRemoved ) { 391 } else if ( c->type() == QEvent::ChildRemoved ) {
396 QSplitterLayoutStruct *p = 0; 392 QSplitterLayoutStruct *p = 0;
397 if ( data->list.count() > 1 ) 393 if ( data->list.count() > 1 )
398 p = data->list.at(1); //remove handle _after_ first widget. 394 p = data->list.at(1); //remove handle _after_ first widget.
399 QSplitterLayoutStruct *s = data->list.first(); 395 QSplitterLayoutStruct *s = data->list.first();
400 while ( s ) { 396 while ( s ) {
401 if ( s->wid == c->child() ) { 397 if ( s->wid == c->child() ) {
402 data->list.removeRef( s ); 398 data->list.removeRef( s );
403 delete s; 399 delete s;
404 if ( p && p->isSplitter ) { 400 if ( p && p->isSplitter ) {
405 data->list.removeRef( p ); 401 data->list.removeRef( p );
406 delete p->wid; //will call childEvent 402 delete p->wid; //will call childEvent
407 delete p; 403 delete p;
408 } 404 }
409 recalcId(); 405 recalcId();
410 doResize(); 406 doResize();
411 return; 407 return;
412 } 408 }
413 p = s; 409 p = s;
414 s = data->list.next(); 410 s = data->list.next();
415 } 411 }
416 } 412 }
417} 413}
418 414
419 415
420/*! 416/*!
421 Shows a rubber band at position \a p. If \a p is negative, the 417 Shows a rubber band at position \a p. If \a p is negative, the
422 rubber band is removed. 418 rubber band is removed.
423*/ 419*/
424 420
425void QSplitter::setRubberband( int p ) 421void QSplitter::setRubberband( int p )
426{ 422{
427 QPainter paint( this ); 423 QPainter paint( this );
428 paint.setPen( gray ); 424 paint.setPen( gray );
429 paint.setBrush( gray ); 425 paint.setBrush( gray );
430 paint.setRasterOp( XorROP ); 426 paint.setRasterOp( XorROP );
431 QRect r = contentsRect(); 427 QRect r = contentsRect();
432 const int rBord = 3; //Themable???? 428 const int rBord = 3; //Themable????
433 const int sw = style().splitterWidth(); 429 const int sw = style().splitterWidth();
434 if ( orient == Horizontal ) { 430 if ( orient == Horizontal ) {
435 if ( opaqueOldPos >= 0 ) 431 if ( opaqueOldPos >= 0 )
436 paint.drawRect( opaqueOldPos + sw/2 - rBord , r.y(), 432 paint.drawRect( opaqueOldPos + sw/2 - rBord , r.y(),
437 2*rBord, r.height() ); 433 2*rBord, r.height() );
438 if ( p >= 0 ) 434 if ( p >= 0 )
439 paint.drawRect( p + sw/2 - rBord, r.y(), 2*rBord, r.height() ); 435 paint.drawRect( p + sw/2 - rBord, r.y(), 2*rBord, r.height() );
440 } else { 436 } else {
441 if ( opaqueOldPos >= 0 ) 437 if ( opaqueOldPos >= 0 )
442 paint.drawRect( r.x(), opaqueOldPos + sw/2 - rBord, 438 paint.drawRect( r.x(), opaqueOldPos + sw/2 - rBord,
443 r.width(), 2*rBord ); 439 r.width(), 2*rBord );
444 if ( p >= 0 ) 440 if ( p >= 0 )
445 paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord ); 441 paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
446 } 442 }
447 opaqueOldPos = p; 443 opaqueOldPos = p;
448} 444}
449 445
450 446
451/*! \reimp */ 447/*! \reimp */
452 448
453bool QSplitter::event( QEvent *e ) 449bool QSplitter::event( QEvent *e )
454{ 450{
455 if ( e->type() == QEvent::LayoutHint || ( e->type() == QEvent::Show && data->firstShow ) ) { 451 if ( e->type() == QEvent::LayoutHint || ( e->type() == QEvent::Show && data->firstShow ) ) {
456 recalc( isVisible() ); 452 recalc( isVisible() );
457 if ( e->type() == QEvent::Show ) 453 if ( e->type() == QEvent::Show )
458 data->firstShow = FALSE; 454 data->firstShow = FALSE;
459 } 455 }
460 return QWidget::event( e ); 456 return QWidget::event( e );
461} 457}
462 458
463 459
464/*! 460/*!
465 Draws the splitter handle in the rectangle described by \a x, \a y, 461 Draws the splitter handle in the rectangle described by \a x, \a y,
466 \a w, \a h using painter \a p. 462 \a w, \a h using painter \a p.
467 \sa QStyle::drawSplitter 463 \sa QStyle::drawSplitter
468*/ 464*/
469 465
470void QSplitter::drawSplitter( QPainter *p, 466void QSplitter::drawSplitter( QPainter *p,
471 QCOORD x, QCOORD y, QCOORD w, QCOORD h ) 467 QCOORD x, QCOORD y, QCOORD w, QCOORD h )
472{ 468{
473 style().drawSplitter( p, x, y, w, h, colorGroup(), orient ); 469 style().drawSplitter( p, x, y, w, h, colorGroup(), orient );
474} 470}
475 471
476 472
477/*! 473/*!
478 Returns the id of the splitter to the right of or below the widget \a w, 474 Returns the id of the splitter to the right of or below the widget \a w,
479 or 0 if there is no such splitter. 475 or 0 if there is no such splitter.
480 (ie. it is either not in this QSplitter, or it is at the end). 476 (ie. it is either not in this QSplitter, or it is at the end).
481*/ 477*/
482 478
483int QSplitter::idAfter( QWidget* w ) const 479int QSplitter::idAfter( QWidget* w ) const
484{ 480{
485 QSplitterLayoutStruct *s = data->list.first(); 481 QSplitterLayoutStruct *s = data->list.first();
486 bool seen_w = FALSE; 482 bool seen_w = FALSE;
487 while ( s ) { 483 while ( s ) {
488 if ( s->isSplitter && seen_w ) 484 if ( s->isSplitter && seen_w )
489 return data->list.at(); 485 return data->list.at();
490 if ( !s->isSplitter && s->wid == w ) 486 if ( !s->isSplitter && s->wid == w )
491 seen_w = TRUE; 487 seen_w = TRUE;
492 s = data->list.next(); 488 s = data->list.next();
493 } 489 }
494 return 0; 490 return 0;
495} 491}
496 492
497 493
498/*! 494/*!
499 Moves the left/top edge of the splitter handle with id \a id as 495 Moves the left/top edge of the splitter handle with id \a id as
500 close as possible to \a p which is the distance from the left (or 496 close as possible to \a p which is the distance from the left (or
501 top) edge of the widget. 497 top) edge of the widget.
502 498
503 \sa idAfter() 499 \sa idAfter()
504*/ 500*/
505void QSplitter::moveSplitter( QCOORD p, int id ) 501void QSplitter::moveSplitter( QCOORD p, int id )
506{ 502{
507 p = adjustPos( p, id ); 503 p = adjustPos( p, id );
508 504
509 QSplitterLayoutStruct *s = data->list.at(id); 505 QSplitterLayoutStruct *s = data->list.at(id);
510 int oldP = orient == Horizontal? s->wid->x() : s->wid->y(); 506 int oldP = orient == Horizontal? s->wid->x() : s->wid->y();
511 bool upLeft = p < oldP; 507 bool upLeft = p < oldP;
512 508
513 moveAfter( p, id, upLeft ); 509 moveAfter( p, id, upLeft );
514 moveBefore( p-1, id-1, upLeft ); 510 moveBefore( p-1, id-1, upLeft );
515 511
516 storeSizes(); 512 storeSizes();
517} 513}
518 514
519 515
520void QSplitter::setG( QWidget *w, int p, int s ) 516void QSplitter::setG( QWidget *w, int p, int s )
521{ 517{
522 if ( orient == Horizontal ) 518 if ( orient == Horizontal )
523 w->setGeometry( p, contentsRect().y(), s, contentsRect().height() ); 519 w->setGeometry( p, contentsRect().y(), s, contentsRect().height() );
524 else 520 else
525 w->setGeometry( contentsRect().x(), p, contentsRect().width(), s ); 521 w->setGeometry( contentsRect().x(), p, contentsRect().width(), s );
526} 522}
527 523
528 524
529/*! 525/*!
530 Places the right/bottom edge of the widget at \a id at position \a pos. 526 Places the right/bottom edge of the widget at \a id at position \a pos.
531 527
532 \sa idAfter() 528 \sa idAfter()
533*/ 529*/
534 530
535void QSplitter::moveBefore( int pos, int id, bool upLeft ) 531void QSplitter::moveBefore( int pos, int id, bool upLeft )
536{ 532{
537 QSplitterLayoutStruct *s = data->list.at(id); 533 QSplitterLayoutStruct *s = data->list.at(id);
538 if ( !s ) 534 if ( !s )
539 return; 535 return;
540 QWidget *w = s->wid; 536 QWidget *w = s->wid;
541 if ( w->isHidden() ) { 537 if ( w->isHidden() ) {
542 moveBefore( pos, id-1, upLeft ); 538 moveBefore( pos, id-1, upLeft );
543 } else if ( s->isSplitter ) { 539 } else if ( s->isSplitter ) {
544 int dd = s->sizer; 540 int dd = s->sizer;
545 if ( upLeft ) { 541 if ( upLeft ) {
546 setG( w, pos-dd+1, dd ); 542 setG( w, pos-dd+1, dd );
547 moveBefore( pos-dd, id-1, upLeft ); 543 moveBefore( pos-dd, id-1, upLeft );
548 } else { 544 } else {
549 moveBefore( pos-dd, id-1, upLeft ); 545 moveBefore( pos-dd, id-1, upLeft );
550 setG( w, pos-dd+1, dd ); 546 setG( w, pos-dd+1, dd );
551 } 547 }
552 } else { 548 } else {
553 int left = pick( w->pos() ); 549 int left = pick( w->pos() );
554 int dd = pos - left + 1; 550 int dd = pos - left + 1;
555 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize()))); 551 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
556 int newLeft = pos-dd+1; 552 int newLeft = pos-dd+1;
557 setG( w, newLeft, dd ); 553 setG( w, newLeft, dd );
558 if ( left != newLeft ) 554 if ( left != newLeft )
559 moveBefore( newLeft-1, id-1, upLeft ); 555 moveBefore( newLeft-1, id-1, upLeft );
560 } 556 }
561} 557}
562 558
563 559
564/*! 560/*!
565 Places the left/top edge of the widget at \a id at position \a pos. 561 Places the left/top edge of the widget at \a id at position \a pos.
566 562
567 \sa idAfter() 563 \sa idAfter()
568*/ 564*/
569 565
570void QSplitter::moveAfter( int pos, int id, bool upLeft ) 566void QSplitter::moveAfter( int pos, int id, bool upLeft )
571{ 567{
572 QSplitterLayoutStruct *s = id < int(data->list.count()) ? 568 QSplitterLayoutStruct *s = id < int(data->list.count()) ?
573 data->list.at(id) : 0; 569 data->list.at(id) : 0;
574 if ( !s ) 570 if ( !s )
575 return; 571 return;
576 QWidget *w = s->wid; 572 QWidget *w = s->wid;
577 if ( w->isHidden() ) { 573 if ( w->isHidden() ) {
578 moveAfter( pos, id+1, upLeft ); 574 moveAfter( pos, id+1, upLeft );
579 } else if ( pick( w->pos() ) == pos ) { 575 } else if ( pick( w->pos() ) == pos ) {
580 //No need to do anything if it's already there. 576 //No need to do anything if it's already there.
581 return; 577 return;
582 } else if ( s->isSplitter ) { 578 } else if ( s->isSplitter ) {
583 int dd = s->sizer; 579 int dd = s->sizer;
584 if ( upLeft ) { 580 if ( upLeft ) {
585 setG( w, pos, dd ); 581 setG( w, pos, dd );
586 moveAfter( pos+dd, id+1, upLeft ); 582 moveAfter( pos+dd, id+1, upLeft );
587 } else { 583 } else {
588 moveAfter( pos+dd, id+1, upLeft ); 584 moveAfter( pos+dd, id+1, upLeft );
589 setG( w, pos, dd ); 585 setG( w, pos, dd );
590 } 586 }
591 } else { 587 } else {
592 int right = pick( w->geometry().bottomRight() ); 588 int right = pick( w->geometry().bottomRight() );
593 589
594 int dd = right - pos + 1; 590 int dd = right - pos + 1;
595 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize()))); 591 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
596 int newRight = pos+dd-1; 592 int newRight = pos+dd-1;
597 setG( w, pos, dd ); 593 setG( w, pos, dd );
598 moveAfter( newRight+1, id+1, upLeft ); 594 moveAfter( newRight+1, id+1, upLeft );
599 } 595 }
600} 596}
601 597
602 598
603/*! 599/*!
604 Returns the valid range of the splitter with id \a id in \a min and \a max. 600 Returns the valid range of the splitter with id \a id in \a min and \a max.
605 601
606 \sa idAfter() 602 \sa idAfter()
607*/ 603*/
608 604
609void QSplitter::getRange( int id, int *min, int *max ) 605void QSplitter::getRange( int id, int *min, int *max )
610{ 606{
611 int minB = 0;//before 607 int minB = 0;//before
612 int maxB = 0; 608 int maxB = 0;
613 int minA = 0; 609 int minA = 0;
614 int maxA = 0;//after 610 int maxA = 0;//after
615 int n = data->list.count(); 611 int n = data->list.count();
616 if ( id < 0 || id >= n ) 612 if ( id < 0 || id >= n )
617 return; 613 return;
618 int i; 614 int i;
619 for ( i = 0; i < id; i++ ) { 615 for ( i = 0; i < id; i++ ) {
620 QSplitterLayoutStruct *s = data->list.at(i); 616 QSplitterLayoutStruct *s = data->list.at(i);
621 if ( s->wid->isHidden() ) { 617 if ( s->wid->isHidden() ) {
622 //ignore 618 //ignore
623 } else if ( s->isSplitter ) { 619 } else if ( s->isSplitter ) {
624 minB += s->sizer; 620 minB += s->sizer;
625 maxB += s->sizer; 621 maxB += s->sizer;
626 } else { 622 } else {
627 minB += pick( minSize(s->wid) ); 623 minB += pick( minSize(s->wid) );
628 maxB += pick( s->wid->maximumSize() ); 624 maxB += pick( s->wid->maximumSize() );
629 } 625 }
630 } 626 }
631 for ( i = id; i < n; i++ ) { 627 for ( i = id; i < n; i++ ) {
632 QSplitterLayoutStruct *s = data->list.at(i); 628 QSplitterLayoutStruct *s = data->list.at(i);
633 if ( s->wid->isHidden() ) { 629 if ( s->wid->isHidden() ) {
634 //ignore 630 //ignore
635 } else if ( s->isSplitter ) { 631 } else if ( s->isSplitter ) {
636 minA += s->sizer; 632 minA += s->sizer;
637 maxA += s->sizer; 633 maxA += s->sizer;
638 } else { 634 } else {
639 minA += pick( minSize(s->wid) ); 635 minA += pick( minSize(s->wid) );
640 maxA += pick( s->wid->maximumSize() ); 636 maxA += pick( s->wid->maximumSize() );
641 } 637 }
642 } 638 }
643 QRect r = contentsRect(); 639 QRect r = contentsRect();
644 if ( min ) 640 if ( min )
645 *min = pick(r.topLeft()) + QMAX( minB, pick(r.size())-maxA ); 641 *min = pick(r.topLeft()) + QMAX( minB, pick(r.size())-maxA );
646 if ( max ) 642 if ( max )
647 *max = pick(r.topLeft()) + QMIN( maxB, pick(r.size())-minA ); 643 *max = pick(r.topLeft()) + QMIN( maxB, pick(r.size())-minA );
648 644
649} 645}
650 646
651 647
652/*! 648/*!
653 Returns the legal position closest to \a p of the splitter with id \a id. 649 Returns the legal position closest to \a p of the splitter with id \a id.
654 650
655 \sa idAfter() 651 \sa idAfter()
656*/ 652*/
657 653
658int QSplitter::adjustPos( int p, int id ) 654int QSplitter::adjustPos( int p, int id )
659{ 655{
660 int min = 0; 656 int min = 0;
661 int max = 0; 657 int max = 0;
662 getRange( id, &min, &max ); 658 getRange( id, &min, &max );
663 p = QMAX( min, QMIN( p, max ) ); 659 p = QMAX( min, QMIN( p, max ) );
664 660
665 return p; 661 return p;
666} 662}
667 663
668 664
669void QSplitter::doResize() 665void QSplitter::doResize()
670{ 666{
671 QRect r = contentsRect(); 667 QRect r = contentsRect();
672 int i; 668 int i;
673 int n = data->list.count(); 669 int n = data->list.count();
674 QArray<QLayoutStruct> a( n ); 670 QArray<QLayoutStruct> a( n );
675 for ( i = 0; i< n; i++ ) { 671 for ( i = 0; i< n; i++ ) {
676 a[i].init(); 672 a[i].init();
677 QSplitterLayoutStruct *s = data->list.at(i); 673 QSplitterLayoutStruct *s = data->list.at(i);
678 if ( s->wid->isHidden() ) { 674 if ( s->wid->isHidden() ) {
679 a[i].stretch = 0; 675 a[i].stretch = 0;
680 a[i].sizeHint = a[i].minimumSize = 0; 676 a[i].sizeHint = a[i].minimumSize = 0;
681 a[i].maximumSize = 0; 677 a[i].maximumSize = 0;
682 } else if ( s->isSplitter ) { 678 } else if ( s->isSplitter ) {
683 a[i].stretch = 0; 679 a[i].stretch = 0;
684 a[i].sizeHint = a[i].minimumSize = a[i].maximumSize = s->sizer; 680 a[i].sizeHint = a[i].minimumSize = a[i].maximumSize = s->sizer;
685 a[i].empty = FALSE; 681 a[i].empty = FALSE;
686 } else if ( s->mode == KeepSize ) { 682 } else if ( s->mode == KeepSize ) {
687 a[i].stretch = 0; 683 a[i].stretch = 0;
688 a[i].minimumSize = pick( minSize(s->wid) ); 684 a[i].minimumSize = pick( minSize(s->wid) );
689 a[i].sizeHint = s->sizer; 685 a[i].sizeHint = s->sizer;
690 a[i].maximumSize = pick( s->wid->maximumSize() ); 686 a[i].maximumSize = pick( s->wid->maximumSize() );
691 a[i].empty = FALSE; 687 a[i].empty = FALSE;
692 } else if ( s->mode == FollowSizeHint ) { 688 } else if ( s->mode == FollowSizeHint ) {
693 a[i].stretch = 0; 689 a[i].stretch = 0;
694 a[i].minimumSize = a[i].sizeHint = pick( s->wid->sizeHint() ); 690 a[i].minimumSize = a[i].sizeHint = pick( s->wid->sizeHint() );
695 a[i].maximumSize = pick( s->wid->maximumSize() ); 691 a[i].maximumSize = pick( s->wid->maximumSize() );
696 a[i].empty = FALSE; 692 a[i].empty = FALSE;
697 } else { //proportional 693 } else { //proportional
698 a[i].stretch = s->sizer; 694 a[i].stretch = s->sizer;
699 a[i].maximumSize = pick( s->wid->maximumSize() ); 695 a[i].maximumSize = pick( s->wid->maximumSize() );
700 a[i].sizeHint = a[i].minimumSize = pick( minSize(s->wid) ); 696 a[i].sizeHint = a[i].minimumSize = pick( minSize(s->wid) );
701 a[i].empty = FALSE; 697 a[i].empty = FALSE;
702 } 698 }
703 } 699 }
704 700
705 qGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 ); 701 qGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 );
706 for ( i = 0; i< n; i++ ) { 702 for ( i = 0; i< n; i++ ) {
707 QSplitterLayoutStruct *s = data->list.at(i); 703 QSplitterLayoutStruct *s = data->list.at(i);
708 if ( orient == Horizontal ) 704 if ( orient == Horizontal )
709 s->wid->setGeometry( a[i].pos, r.top(), a[i].size, r.height() ); 705 s->wid->setGeometry( a[i].pos, r.top(), a[i].size, r.height() );
710 else 706 else
711 s->wid->setGeometry( r.left(), a[i].pos, r.width(), a[i].size ); 707 s->wid->setGeometry( r.left(), a[i].pos, r.width(), a[i].size );
712 } 708 }
713 709
714} 710}
715 711
716 712
717void QSplitter::recalc( bool update ) 713void QSplitter::recalc( bool update )
718{ 714{
719 int fi = 2*frameWidth(); 715 int fi = 2*frameWidth();
720 int maxl = fi; 716 int maxl = fi;
721 int minl = fi; 717 int minl = fi;
722 int maxt = QWIDGETSIZE_MAX; 718 int maxt = QWIDGETSIZE_MAX;
723 int mint = fi; 719 int mint = fi;
724 int n = data->list.count(); 720 int n = data->list.count();
725 bool first = TRUE; 721 bool first = TRUE;
726 /* 722 /*
727 The splitter before a hidden widget is always hidden. 723 The splitter before a hidden widget is always hidden.
728 The splitter before the first visible widget is hidden. 724 The splitter before the first visible widget is hidden.
729 The splitter before any other visible widget is visible. 725 The splitter before any other visible widget is visible.
730 */ 726 */
731 for ( int i = 0; i< n; i++ ) { 727 for ( int i = 0; i< n; i++ ) {
732 QSplitterLayoutStruct *s = data->list.at(i); 728 QSplitterLayoutStruct *s = data->list.at(i);
733 if ( !s->isSplitter ) { 729 if ( !s->isSplitter ) {
734 QSplitterLayoutStruct *p = (i > 0) ? p = data->list.at( i-1 ) : 0; 730 QSplitterLayoutStruct *p = (i > 0) ? p = data->list.at( i-1 ) : 0;
735 if ( p && p->isSplitter ) 731 if ( p && p->isSplitter )
736 if ( first || s->wid->isHidden() ) 732 if ( first || s->wid->isHidden() )
737 p->wid->hide(); //may trigger new recalc 733 p->wid->hide(); //may trigger new recalc
738 else 734 else
739 p->wid->show(); //may trigger new recalc 735 p->wid->show(); //may trigger new recalc
740 if ( !s->wid->isHidden() ) 736 if ( !s->wid->isHidden() )
741 first = FALSE; 737 first = FALSE;
742 } 738 }
743 } 739 }
744 740
745 bool empty=TRUE; 741 bool empty=TRUE;
746 for ( int j = 0; j< n; j++ ) { 742 for ( int j = 0; j< n; j++ ) {
747 QSplitterLayoutStruct *s = data->list.at(j); 743 QSplitterLayoutStruct *s = data->list.at(j);
748 if ( !s->wid->isHidden() ) { 744 if ( !s->wid->isHidden() ) {
749 empty = FALSE; 745 empty = FALSE;
750 if ( s->isSplitter ) { 746 if ( s->isSplitter ) {
751 minl += s->sizer; 747 minl += s->sizer;
752 maxl += s->sizer; 748 maxl += s->sizer;
753 } else { 749 } else {
754 QSize minS = minSize(s->wid); 750 QSize minS = minSize(s->wid);
755 minl += pick( minS ); 751 minl += pick( minS );
756 maxl += pick( s->wid->maximumSize() ); 752 maxl += pick( s->wid->maximumSize() );
757 mint = QMAX( mint, trans( minS )); 753 mint = QMAX( mint, trans( minS ));
758 int tm = trans( s->wid->maximumSize() ); 754 int tm = trans( s->wid->maximumSize() );
759 if ( tm > 0 ) 755 if ( tm > 0 )
760 maxt = QMIN( maxt, tm ); 756 maxt = QMIN( maxt, tm );
761 } 757 }
762 } 758 }
763 } 759 }
764 if ( empty ) 760 if ( empty )
765 maxl = maxt = 0; 761 maxl = maxt = 0;
766 else 762 else
767 maxl = QMIN( maxl, QWIDGETSIZE_MAX ); 763 maxl = QMIN( maxl, QWIDGETSIZE_MAX );
768 if ( maxt < mint ) 764 if ( maxt < mint )
769 maxt = mint; 765 maxt = mint;
770 766
771 if ( orient == Horizontal ) { 767 if ( orient == Horizontal ) {
772 setMaximumSize( maxl, maxt ); 768 setMaximumSize( maxl, maxt );
773 setMinimumSize( minl, mint ); 769 setMinimumSize( minl, mint );
774 } else { 770 } else {
775 setMaximumSize( maxt, maxl ); 771 setMaximumSize( maxt, maxl );
776 setMinimumSize( mint, minl ); 772 setMinimumSize( mint, minl );
777 } 773 }
778 if ( update ) 774 if ( update )
779 doResize(); 775 doResize();
780} 776}
781 777
782/*! \enum QSplitter::ResizeMode 778/*! \enum QSplitter::ResizeMode
783 779
784 This enum type describes how QSplitter will resize each of its child widgets. The currently defined values are: <ul> 780 This enum type describes how QSplitter will resize each of its child widgets. The currently defined values are: <ul>
785 781
786 <li> \c Stretch - the widget will be resized when the splitter 782 <li> \c Stretch - the widget will be resized when the splitter
787 itself is resized. 783 itself is resized.
788 784
789 <li> \c KeepSize - QSplitter will try to keep this widget's size 785 <li> \c KeepSize - QSplitter will try to keep this widget's size
790 unchanged. 786 unchanged.
791 787
792 <li> \c FollowSizeHint - QSplitter will resize the widget when its 788 <li> \c FollowSizeHint - QSplitter will resize the widget when its
793 size hint changes. 789 size hint changes.
794 790
795 </ul> 791 </ul>
796 792
797*/ 793*/
798 794
799/*! 795/*!
800 Sets resize mode of \a w to \a mode. 796 Sets resize mode of \a w to \a mode.
801 797
802 \sa ResizeMode 798 \sa ResizeMode
803*/ 799*/
804 800
805void QSplitter::setResizeMode( QWidget *w, ResizeMode mode ) 801void QSplitter::setResizeMode( QWidget *w, ResizeMode mode )
806{ 802{
807 processChildEvents(); 803 processChildEvents();
808 QSplitterLayoutStruct *s = data->list.first(); 804 QSplitterLayoutStruct *s = data->list.first();
809 while ( s ) { 805 while ( s ) {
810 if ( s->wid == w ) { 806 if ( s->wid == w ) {
811 s->mode = mode; 807 s->mode = mode;
812 return; 808 return;
813 } 809 }
814 s = data->list.next(); 810 s = data->list.next();
815 } 811 }
816 s = addWidget( w, TRUE ); 812 s = addWidget( w, TRUE );
817 s->mode = mode; 813 s->mode = mode;
818} 814}
819 815
820 816
821/*! 817/*!
822 Returns TRUE if opaque resize is on, FALSE otherwise. 818 Returns TRUE if opaque resize is on, FALSE otherwise.
823 819
824 \sa setOpaqueResize() 820 \sa setOpaqueResize()
825*/ 821*/
826 822
827bool QSplitter::opaqueResize() const 823bool QSplitter::opaqueResize() const
828{ 824{
829 return data->opaque; 825 return data->opaque;
830} 826}
831 827
832 828
833/*! 829/*!
834 Sets opaque resize to \a on. Opaque resize is initially turned off. 830 Sets opaque resize to \a on. Opaque resize is initially turned off.
835 831
836 \sa opaqueResize() 832 \sa opaqueResize()
837*/ 833*/
838 834
839void QSplitter::setOpaqueResize( bool on ) 835void QSplitter::setOpaqueResize( bool on )
840{ 836{
841 data->opaque = on; 837 data->opaque = on;
842} 838}
843 839
844 840
845/*! 841/*!
846 Moves \a w to the leftmost/top position. 842 Moves \a w to the leftmost/top position.
847*/ 843*/
848 844
849void QSplitter::moveToFirst( QWidget *w ) 845void QSplitter::moveToFirst( QWidget *w )
850{ 846{
851 processChildEvents(); 847 processChildEvents();
852 bool found = FALSE; 848 bool found = FALSE;
853 QSplitterLayoutStruct *s = data->list.first(); 849 QSplitterLayoutStruct *s = data->list.first();
854 while ( s ) { 850 while ( s ) {
855 if ( s->wid == w ) { 851 if ( s->wid == w ) {
856 found = TRUE; 852 found = TRUE;
857 QSplitterLayoutStruct *p = data->list.prev(); 853 QSplitterLayoutStruct *p = data->list.prev();
858 if ( p ) { // not already at first place 854 if ( p ) { // not already at first place
859 data->list.take(); //take p 855 data->list.take(); //take p
860 data->list.take(); // take s 856 data->list.take(); // take s
861 data->list.insert( 0, p ); 857 data->list.insert( 0, p );
862 data->list.insert( 0, s ); 858 data->list.insert( 0, s );
863 } 859 }
864 break; 860 break;
865 } 861 }
866 s = data->list.next(); 862 s = data->list.next();
867 } 863 }
868 if ( !found ) 864 if ( !found )
869 addWidget( w, TRUE ); 865 addWidget( w, TRUE );
870 recalcId(); 866 recalcId();
871} 867}
872 868
873 869
874/*! 870/*!
875 Moves \a w to the rightmost/bottom position. 871 Moves \a w to the rightmost/bottom position.
876*/ 872*/
877 873
878void QSplitter::moveToLast( QWidget *w ) 874void QSplitter::moveToLast( QWidget *w )
879{ 875{
880 processChildEvents(); 876 processChildEvents();
881 bool found = FALSE; 877 bool found = FALSE;
882 QSplitterLayoutStruct *s = data->list.first(); 878 QSplitterLayoutStruct *s = data->list.first();
883 while ( s ) { 879 while ( s ) {
884 if ( s->wid == w ) { 880 if ( s->wid == w ) {
885 found = TRUE; 881 found = TRUE;
886 data->list.take(); // take s 882 data->list.take(); // take s
887 QSplitterLayoutStruct *p = data->list.current(); 883 QSplitterLayoutStruct *p = data->list.current();
888 if ( p ) { // the splitter handle after s 884 if ( p ) { // the splitter handle after s
889 data->list.take(); //take p 885 data->list.take(); //take p
890 data->list.append( p ); 886 data->list.append( p );
891 } 887 }
892 data->list.append( s ); 888 data->list.append( s );
893 break; 889 break;
894 } 890 }
895 s = data->list.next(); 891 s = data->list.next();
896 } 892 }
897 if ( !found ) 893 if ( !found )
898 addWidget( w); 894 addWidget( w);
899 recalcId(); 895 recalcId();
900} 896}
901 897
902 898
903void QSplitter::recalcId() 899void QSplitter::recalcId()
904{ 900{
905 int n = data->list.count(); 901 int n = data->list.count();
906 for ( int i = 0; i < n; i++ ) { 902 for ( int i = 0; i < n; i++ ) {
907 QSplitterLayoutStruct *s = data->list.at(i); 903 QSplitterLayoutStruct *s = data->list.at(i);
908 if ( s->isSplitter ) 904 if ( s->isSplitter )
909 ((QSplitterHandle*)s->wid)->setId(i); 905 ((QSplitterHandle*)s->wid)->setId(i);
910 } 906 }
911} 907}
912 908
913 909
914/*!\reimp 910/*!\reimp
915*/ 911*/
916QSize QSplitter::sizeHint() const 912QSize QSplitter::sizeHint() const
917{ 913{
918 constPolish(); 914 constPolish();
919 int l = 0; 915 int l = 0;
920 int t = 0; 916 int t = 0;
921 if ( children() ) { 917 if ( children() ) {
922 const QObjectList * c = children(); 918 const QObjectList * c = children();
923 QObjectListIt it( *c ); 919 QObjectListIt it( *c );
924 QObject * o; 920 QObject * o;
925 921
926 while( (o=it.current()) != 0 ) { 922 while( (o=it.current()) != 0 ) {
927 ++it; 923 ++it;
928 if ( o->isWidgetType() && 924 if ( o->isWidgetType() &&
929 !((QWidget*)o)->isHidden() ) { 925 !((QWidget*)o)->isHidden() ) {
930 QSize s = ((QWidget*)o)->sizeHint(); 926 QSize s = ((QWidget*)o)->sizeHint();
931 if ( s.isValid() ) { 927 if ( s.isValid() ) {
932 l += pick( s ); 928 l += pick( s );
933 t = QMAX( t, trans( s ) ); 929 t = QMAX( t, trans( s ) );
934 } 930 }
935 } 931 }
936 } 932 }
937 } 933 }
938 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l ); 934 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
939} 935}
940 936
941 937
942/*! 938/*!
943\reimp 939\reimp
944*/ 940*/
945 941
946QSize QSplitter::minimumSizeHint() const 942QSize QSplitter::minimumSizeHint() const
947{ 943{
948 constPolish(); 944 constPolish();
949 int l = 0; 945 int l = 0;
950 int t = 0; 946 int t = 0;
951 if ( children() ) { 947 if ( children() ) {
952 const QObjectList * c = children(); 948 const QObjectList * c = children();
953 QObjectListIt it( *c ); 949 QObjectListIt it( *c );
954 QObject * o; 950 QObject * o;
955 951
956 while( (o=it.current()) != 0 ) { 952 while( (o=it.current()) != 0 ) {
957 ++it; 953 ++it;
958 if ( o->isWidgetType() && 954 if ( o->isWidgetType() &&
959 !((QWidget*)o)->isHidden() ) { 955 !((QWidget*)o)->isHidden() ) {
960 QSize s = minSize((QWidget*)o); 956 QSize s = minSize((QWidget*)o);
961 if ( s.isValid() ) { 957 if ( s.isValid() ) {
962 l += pick( s ); 958 l += pick( s );
963 t = QMAX( t, trans( s ) ); 959 t = QMAX( t, trans( s ) );
964 } 960 }
965 } 961 }
966 } 962 }
967 } 963 }
968 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l ); 964 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
969} 965}
970 966
971 967
972 968
973/*!\reimp 969/*!\reimp
974*/ 970*/
975QSizePolicy QSplitter::sizePolicy() const 971QSizePolicy QSplitter::sizePolicy() const
976{ 972{
977 return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); 973 return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
978} 974}
979 975
980 976
981/*! 977/*!
982 Calculates stretch parameters from current sizes 978 Calculates stretch parameters from current sizes
983*/ 979*/
984 980
985void QSplitter::storeSizes() 981void QSplitter::storeSizes()
986{ 982{
987 QSplitterLayoutStruct *s = data->list.first(); 983 QSplitterLayoutStruct *s = data->list.first();
988 while ( s ) { 984 while ( s ) {
989 if ( !s->isSplitter ) 985 if ( !s->isSplitter )
990 s->sizer = pick( s->wid->size() ); 986 s->sizer = pick( s->wid->size() );
991 s = data->list.next(); 987 s = data->list.next();
992 } 988 }
993} 989}
994 990
995 991
996#if 0 // ### remove this code ASAP 992#if 0 // ### remove this code ASAP
997 993
998/*! 994/*!
999 Hides \a w if \a hide is TRUE, and updates the splitter. 995 Hides \a w if \a hide is TRUE, and updates the splitter.
1000 996
1001 \warning Due to a limitation in the current implementation, 997 \warning Due to a limitation in the current implementation,
1002 calling QWidget::hide() will not work. 998 calling QWidget::hide() will not work.
1003*/ 999*/
1004 1000
1005void QSplitter::setHidden( QWidget *w, bool hide ) 1001void QSplitter::setHidden( QWidget *w, bool hide )
1006{ 1002{
1007 if ( w == w1 ) { 1003 if ( w == w1 ) {
1008 w1show = !hide; 1004 w1show = !hide;
1009 } else if ( w == w2 ) { 1005 } else if ( w == w2 ) {
1010 w2show = !hide; 1006 w2show = !hide;
1011 } else { 1007 } else {
1012#ifdef CHECK_RANGE 1008#ifdef CHECK_RANGE
1013 qWarning( "QSplitter::setHidden(), unknown widget" ); 1009 qWarning( "QSplitter::setHidden(), unknown widget" );
1014#endif 1010#endif
1015 return; 1011 return;
1016 } 1012 }
1017 if ( hide ) 1013 if ( hide )
1018 w->hide(); 1014 w->hide();
1019 else 1015 else
1020 w->show(); 1016 w->show();
1021 recalc( TRUE ); 1017 recalc( TRUE );
1022} 1018}
1023 1019
1024 1020
1025/*! 1021/*!
1026 Returns the hidden status of \a w 1022 Returns the hidden status of \a w
1027*/ 1023*/
1028 1024
1029bool QSplitter::isHidden( QWidget *w ) const 1025bool QSplitter::isHidden( QWidget *w ) const
1030{ 1026{
1031 if ( w == w1 ) 1027 if ( w == w1 )
1032 return !w1show; 1028 return !w1show;
1033 else if ( w == w2 ) 1029 else if ( w == w2 )
1034 return !w2show; 1030 return !w2show;
1035#ifdef CHECK_RANGE 1031#ifdef CHECK_RANGE
1036 else 1032 else
1037 qWarning( "QSplitter::isHidden(), unknown widget" ); 1033 qWarning( "QSplitter::isHidden(), unknown widget" );
1038#endif 1034#endif
1039 return FALSE; 1035 return FALSE;
1040} 1036}
1041#endif 1037#endif
1042 1038
1043 1039
1044/*! 1040/*!
1045 Returns a list of the size parameters of all the widgets in this 1041 Returns a list of the size parameters of all the widgets in this
1046 splitter. 1042 splitter.
1047 1043
1048 Giving the values to setSizes() will give a splitter with the same 1044 Giving the values to setSizes() will give a splitter with the same
1049 layout as this one. 1045 layout as this one.
1050 1046
1051 \sa setSizes() 1047 \sa setSizes()
1052*/ 1048*/
1053 1049
1054QValueList<int> QSplitter::sizes() const 1050QValueList<int> QSplitter::sizes() const
1055{ 1051{
1056 if ( !testWState(WState_Polished) ) { 1052 if ( !testWState(WState_Polished) ) {
1057 QWidget* that = (QWidget*) this; 1053 QWidget* that = (QWidget*) this;
1058 that->polish(); 1054 that->polish();
1059 } 1055 }
1060 QValueList<int> list; 1056 QValueList<int> list;
1061 QSplitterLayoutStruct *s = data->list.first(); 1057 QSplitterLayoutStruct *s = data->list.first();
1062 while ( s ) { 1058 while ( s ) {
1063 if ( !s->isSplitter ) 1059 if ( !s->isSplitter )
1064 list.append( s->sizer ); 1060 list.append( s->sizer );
1065 s = data->list.next(); 1061 s = data->list.next();
1066 } 1062 }
1067 return list; 1063 return list;
1068} 1064}
1069 1065
1070 1066
1071 1067
1072/*! 1068/*!
1073 Sets the size parameters to the values given in \a list. 1069 Sets the size parameters to the values given in \a list.
1074 If the splitter is horizontal, the values set the sizes from 1070 If the splitter is horizontal, the values set the sizes from
1075 left to right. If it is vertical, the sizes are applied from 1071 left to right. If it is vertical, the sizes are applied from
1076 top to bottom. 1072 top to bottom.
1077 Extra values in \a list are ignored. 1073 Extra values in \a list are ignored.
1078 1074
1079 If \a list contains too few values, the result is undefined 1075 If \a list contains too few values, the result is undefined
1080 but the program will still be well-behaved. 1076 but the program will still be well-behaved.
1081 1077
1082 \sa sizes() 1078 \sa sizes()
1083*/ 1079*/
1084 1080
1085void QSplitter::setSizes( QValueList<int> list ) 1081void QSplitter::setSizes( QValueList<int> list )
1086{ 1082{
1087 processChildEvents(); 1083 processChildEvents();
1088 QValueList<int>::Iterator it = list.begin(); 1084 QValueList<int>::Iterator it = list.begin();
1089 QSplitterLayoutStruct *s = data->list.first(); 1085 QSplitterLayoutStruct *s = data->list.first();
1090 while ( s && it != list.end() ) { 1086 while ( s && it != list.end() ) {
1091 if ( !s->isSplitter ) { 1087 if ( !s->isSplitter ) {
1092 s->sizer = *it; 1088 s->sizer = *it;
1093 ++it; 1089 ++it;
1094 } 1090 }
1095 s = data->list.next(); 1091 s = data->list.next();
1096 } 1092 }
1097 doResize(); 1093 doResize();
1098} 1094}
1099 1095
1100 1096
1101/*! 1097/*!
1102 Gets all posted child events, ensuring that the internal state of 1098 Gets all posted child events, ensuring that the internal state of
1103 the splitter is consistent with the programmer's idea. 1099 the splitter is consistent with the programmer's idea.
1104*/ 1100*/
1105 1101
1106void QSplitter::processChildEvents() 1102void QSplitter::processChildEvents()
1107{ 1103{
1108 QApplication::sendPostedEvents( this, QEvent::ChildInserted ); 1104 QApplication::sendPostedEvents( this, QEvent::ChildInserted );
1109} 1105}
1110 1106
1111 1107
1112/*! 1108/*!
1113 \reimp 1109 \reimp
1114*/ 1110*/
1115 1111
1116void QSplitter::styleChange( QStyle& old ) 1112void QSplitter::styleChange( QStyle& old )
1117{ 1113{
1118 int sw = style().splitterWidth(); 1114 int sw = style().splitterWidth();
1119 QSplitterLayoutStruct *s = data->list.first(); 1115 QSplitterLayoutStruct *s = data->list.first();
1120 while ( s ) { 1116 while ( s ) {
1121 if ( s->isSplitter ) 1117 if ( s->isSplitter )
1122 s->sizer = sw; 1118 s->sizer = sw;
1123 s = data->list.next(); 1119 s = data->list.next();
1124 } 1120 }
1125 doResize(); 1121 doResize();
1126 QFrame::styleChange( old ); 1122 QFrame::styleChange( old );
1127} 1123}
1128 1124