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