summaryrefslogtreecommitdiffabout
path: root/microkde/KDGanttMinimizeSplitter.cpp
Unidiff
Diffstat (limited to 'microkde/KDGanttMinimizeSplitter.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--microkde/KDGanttMinimizeSplitter.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/microkde/KDGanttMinimizeSplitter.cpp b/microkde/KDGanttMinimizeSplitter.cpp
index c60b566..029f14b 100644
--- a/microkde/KDGanttMinimizeSplitter.cpp
+++ b/microkde/KDGanttMinimizeSplitter.cpp
@@ -1,1652 +1,1657 @@
1/* -*- Mode: C++ -*- 1/* -*- Mode: C++ -*-
2 $Id$ 2 $Id$
3*/ 3*/
4 4
5/**************************************************************************** 5/****************************************************************************
6 ** Copyright (C) 2002-2004 Klarälvdalens Datakonsult AB. All rights reserved. 6 ** Copyright (C) 2002-2004 Klarälvdalens Datakonsult AB. All rights reserved.
7 ** 7 **
8 ** This file is part of the KDGantt library. 8 ** This file is part of the KDGantt library.
9 ** 9 **
10 ** This file may be distributed and/or modified under the terms of the 10 ** This file may be distributed and/or modified under the terms of the
11 ** GNU General Public License version 2 as published by the Free Software 11 ** GNU General Public License version 2 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.GPL included in the 12 ** Foundation and appearing in the file LICENSE.GPL included in the
13 ** packaging of this file. 13 ** packaging of this file.
14 ** 14 **
15 ** Licensees holding valid commercial KDGantt licenses may use this file in 15 ** Licensees holding valid commercial KDGantt licenses may use this file in
16 ** accordance with the KDGantt Commercial License Agreement provided with 16 ** accordance with the KDGantt Commercial License Agreement provided with
17 ** the Software. 17 ** the Software.
18 ** 18 **
19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 ** 21 **
22 ** See http://www.klaralvdalens-datakonsult.se/Public/products/ for 22 ** See http://www.klaralvdalens-datakonsult.se/Public/products/ for
23 ** information about KDGantt Commercial License Agreements. 23 ** information about KDGantt Commercial License Agreements.
24 ** 24 **
25 ** Contact info@klaralvdalens-datakonsult.se if any conditions of this 25 ** Contact info@klaralvdalens-datakonsult.se if any conditions of this
26 ** licensing are not clear to you. 26 ** licensing are not clear to you.
27 ** 27 **
28 ** As a special exception, permission is given to link this program 28 ** As a special exception, permission is given to link this program
29 ** with any edition of Qt, and distribute the resulting executable, 29 ** with any edition of Qt, and distribute the resulting executable,
30 ** without including the source code for Qt in the source distribution. 30 ** without including the source code for Qt in the source distribution.
31 ** 31 **
32 **********************************************************************/ 32 **********************************************************************/
33 33
34#include "KDGanttMinimizeSplitter.h" 34#include "KDGanttMinimizeSplitter.h"
35#ifndef QT_NO_SPLITTER___ 35#ifndef QT_NO_SPLITTER___
36 36
37#include "qpainter.h" 37#include "qpainter.h"
38#include "qdrawutil.h" 38#include "qdrawutil.h"
39#include "qbitmap.h" 39#include "qbitmap.h"
40#if QT_VERSION >= 0x030000 40#if QT_VERSION >= 0x030000
41#include "qptrlist.h" 41#include "qptrlist.h"
42#include "qmemarray.h" 42#include "qmemarray.h"
43#else 43#else
44#include <qlist.h> 44#include <qlist.h>
45#include <qarray.h> 45#include <qarray.h>
46#define QPtrList QList 46#define QPtrList QList
47#define QMemArray QArray 47#define QMemArray QArray
48#endif 48#endif
49#include "qlayoutengine_p.h" 49#include "qlayoutengine_p.h"
50#include "qobjectlist.h" 50#include "qobjectlist.h"
51#include "qstyle.h" 51#include "qstyle.h"
52#include "qapplication.h" //sendPostedEvents 52#include "qapplication.h" //sendPostedEvents
53#include <qvaluelist.h> 53#include <qvaluelist.h>
54#include <qcursor.h> 54#include <qcursor.h>
55#ifndef KDGANTT_MASTER_CVS 55#ifndef KDGANTT_MASTER_CVS
56//#include "KDGanttMinimizeSplitter.moc" 56//#include "KDGanttMinimizeSplitter.moc"
57#endif 57#endif
58 58
59 59
60 60
61#ifndef DOXYGEN_SKIP_INTERNAL 61#ifndef DOXYGEN_SKIP_INTERNAL
62 62
63#if QT_VERSION >= 232 63#if QT_VERSION >= 232
64static int mouseOffset; 64static int mouseOffset;
65static int opaqueOldPos = -1; //### there's only one mouse, but this is a bit risky 65static int opaqueOldPos = -1; //### there's only one mouse, but this is a bit risky
66 66
67 67
68KDGanttSplitterHandle::KDGanttSplitterHandle( Qt::Orientation o, 68KDGanttSplitterHandle::KDGanttSplitterHandle( Qt::Orientation o,
69 KDGanttMinimizeSplitter *parent, const char * name ) 69 KDGanttMinimizeSplitter *parent, const char * name )
70 : QWidget( parent, name ), _activeButton( 0 ), _collapsed( false ) 70 : QWidget( parent, name ), _activeButton( 0 ), _collapsed( false )
71{ 71{
72 72
73 if ( QApplication::desktop()->width() > 320 && QApplication::desktop()->width() < 650 ) { 73 if ( QApplication::desktop()->width() > 320 && QApplication::desktop()->width() < 650 ) {
74 mSizeHint = QSize(7,7); 74 mSizeHint = QSize(7,7);
75 mUseOffset = true; 75 mUseOffset = true;
76 } else { 76 } else {
77 mSizeHint = QSize(6,6); 77 mSizeHint = QSize(6,6);
78 mUseOffset = false; 78 mUseOffset = false;
79 } 79 }
80 s = parent; 80 s = parent;
81 setOrientation(o); 81 setOrientation(o);
82 setMouseTracking( true ); 82 setMouseTracking( true );
83 mMouseDown = false; 83 mMouseDown = false;
84 //setMaximumHeight( 5 ); // test only 84 //setMaximumHeight( 5 ); // test only
85} 85}
86 86
87QSize KDGanttSplitterHandle::sizeHint() const 87QSize KDGanttSplitterHandle::sizeHint() const
88{ 88{
89 return mSizeHint; 89 return mSizeHint;
90} 90}
91 91
92void KDGanttSplitterHandle::setOrientation( Qt::Orientation o ) 92void KDGanttSplitterHandle::setOrientation( Qt::Orientation o )
93{ 93{
94 orient = o; 94 orient = o;
95#ifndef QT_NO_CURSOR 95#ifndef QT_NO_CURSOR
96 if ( o == KDGanttMinimizeSplitter::Horizontal ) 96 if ( o == KDGanttMinimizeSplitter::Horizontal )
97 setCursor( splitHCursor ); 97 setCursor( splitHCursor );
98 else 98 else
99 setCursor( splitVCursor ); 99 setCursor( splitVCursor );
100#endif 100#endif
101} 101}
102 102
103 103
104void KDGanttSplitterHandle::mouseMoveEvent( QMouseEvent *e ) 104void KDGanttSplitterHandle::mouseMoveEvent( QMouseEvent *e )
105{ 105{
106 updateCursor( e->pos() ); 106 updateCursor( e->pos() );
107 if ( !(e->state()&LeftButton) ) 107 if ( !(e->state()&LeftButton) )
108 return; 108 return;
109 109
110 if ( _activeButton != 0) 110 if ( _activeButton != 0)
111 return; 111 return;
112 112
113 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos())) 113 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
114 - mouseOffset; 114 - mouseOffset;
115 if ( true /*opaque()*/ ) { 115 if ( opaque() ) {
116 s->moveSplitter( pos, id() ); 116 s->moveSplitter( pos, id() );
117 } else { 117 } else {
118 int min = pos; int max = pos; 118 int min = pos; int max = pos;
119 s->getRange( id(), &min, &max ); 119 s->getRange( id(), &min, &max );
120 s->setRubberband( QMAX( min, QMIN(max, pos ))); 120 s->setRubberband( QMAX( min, QMIN(max, pos )));
121 } 121 }
122 _collapsed = false; 122 _collapsed = false;
123} 123}
124 124
125void KDGanttSplitterHandle::mousePressEvent( QMouseEvent *e ) 125void KDGanttSplitterHandle::mousePressEvent( QMouseEvent *e )
126{ 126{
127 if ( e->button() == LeftButton ) { 127 if ( e->button() == LeftButton ) {
128 _activeButton = onButton( e->pos() ); 128 _activeButton = onButton( e->pos() );
129 mouseOffset = s->pick(e->pos()); 129 mouseOffset = s->pick(e->pos());
130 mMouseDown = true; 130 mMouseDown = true;
131 repaint(); 131 repaint();
132 updateCursor( e->pos() ); 132 updateCursor( e->pos() );
133 } 133 }
134} 134}
135 135
136void KDGanttSplitterHandle::updateCursor( const QPoint& p) 136void KDGanttSplitterHandle::updateCursor( const QPoint& p)
137{ 137{
138 if ( onButton( p ) != 0 ) { 138 if ( onButton( p ) != 0 ) {
139 setCursor( arrowCursor ); 139 setCursor( arrowCursor );
140 } 140 }
141 else { 141 else {
142 if ( orient == KDGanttMinimizeSplitter::Horizontal ) 142 if ( orient == KDGanttMinimizeSplitter::Horizontal )
143 setCursor( splitHCursor ); 143 setCursor( splitHCursor );
144 else 144 else
145 setCursor( splitVCursor ); 145 setCursor( splitVCursor );
146 } 146 }
147} 147}
148void KDGanttSplitterHandle::toggle() 148void KDGanttSplitterHandle::toggle()
149{ 149{
150 int pos; 150 int pos;
151 int min, max; 151 int min, max;
152 if ( !_collapsed ) { 152 if ( !_collapsed ) {
153 s->expandPos( id(), &min, &max ); 153 s->expandPos( id(), &min, &max );
154 if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left 154 if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left
155 || s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) { 155 || s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) {
156 pos = min; 156 pos = min;
157 } 157 }
158 else { 158 else {
159 pos = max; 159 pos = max;
160 } 160 }
161 161
162 _origPos = s->pick(mapToParent( QPoint( 0,0 ) )); 162 _origPos = s->pick(mapToParent( QPoint( 0,0 ) ));
163 s->moveSplitter( pos, id() ); 163 s->moveSplitter( pos, id() );
164 _collapsed = true; 164 _collapsed = true;
165 } 165 }
166 else { 166 else {
167 s->moveSplitter( _origPos, id() ); 167 s->moveSplitter( _origPos, id() );
168 _collapsed = false; 168 _collapsed = false;
169 } 169 }
170 repaint(); 170 repaint();
171} 171}
172 172
173void KDGanttSplitterHandle::mouseReleaseEvent( QMouseEvent *e ) 173void KDGanttSplitterHandle::mouseReleaseEvent( QMouseEvent *e )
174{ 174{
175 mMouseDown = false; 175 mMouseDown = false;
176 if ( _activeButton != 0 ) { 176 if ( _activeButton != 0 ) {
177 if ( onButton( e->pos() ) == _activeButton ) 177 if ( onButton( e->pos() ) == _activeButton )
178 { 178 {
179 toggle(); 179 toggle();
180 } 180 }
181 _activeButton = 0; 181 _activeButton = 0;
182 updateCursor( e->pos() ); 182 updateCursor( e->pos() );
183 } 183 }
184 else { 184 else {
185 if ( !opaque() && e->button() == LeftButton ) { 185 if ( !opaque() && e->button() == LeftButton ) {
186 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos())) 186 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
187 - mouseOffset; 187 - mouseOffset;
188 s->setRubberband( -1 ); 188 s->setRubberband( -1 );
189 s->moveSplitter( pos, id() ); 189 s->moveSplitter( pos, id() );
190 } 190 }
191 } 191 }
192 repaint(); 192 repaint();
193} 193}
194 194
195int KDGanttSplitterHandle::onButton( const QPoint& p ) 195int KDGanttSplitterHandle::onButton( const QPoint& p )
196{ 196{
197 QValueList<QPointArray> list = buttonRegions(); 197 QValueList<QPointArray> list = buttonRegions();
198 int index = 1; 198 int index = 1;
199 int add = 12; 199 int add = 12;
200 for( QValueList<QPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) { 200 for( QValueList<QPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) {
201 QRect rect = (*it).boundingRect(); 201 QRect rect = (*it).boundingRect();
202 rect.setLeft( rect.left()- add ); 202 rect.setLeft( rect.left()- add );
203 rect.setRight( rect.right() + add); 203 rect.setRight( rect.right() + add);
204 rect.setTop( rect.top()- add ); 204 rect.setTop( rect.top()- add );
205 rect.setBottom( rect.bottom() + add); 205 rect.setBottom( rect.bottom() + add);
206 if ( rect.contains( p ) ) { 206 if ( rect.contains( p ) ) {
207 return index; 207 return index;
208 } 208 }
209 index++; 209 index++;
210 } 210 }
211 return 0; 211 return 0;
212} 212}
213 213
214 214
215QValueList<QPointArray> KDGanttSplitterHandle::buttonRegions() 215QValueList<QPointArray> KDGanttSplitterHandle::buttonRegions()
216{ 216{
217 QValueList<QPointArray> list; 217 QValueList<QPointArray> list;
218 218
219 int sw = 8; 219 int sw = 8;
220 int yyy = 1; 220 int yyy = 1;
221 int xxx = 1; 221 int xxx = 1;
222 int voffset[] = { (int) -sw*3, (int) sw*3 }; 222 int voffset[] = { (int) -sw*3, (int) sw*3 };
223 for ( int i = 0; i < 2; i++ ) { 223 for ( int i = 0; i < 2; i++ ) {
224 QPointArray arr; 224 QPointArray arr;
225 if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right || 225 if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ||
226 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left) { 226 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left) {
227 int mid = height()/2 + voffset[i]; 227 int mid = height()/2 + voffset[i];
228 arr.setPoints( 3, 228 arr.setPoints( 3,
229 1-xxx, mid - sw + 4, 229 1-xxx, mid - sw + 4,
230 sw-3-xxx, mid, 230 sw-3-xxx, mid,
231 1-xxx, mid + sw -4); 231 1-xxx, mid + sw -4);
232 } 232 }
233 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left || 233 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left ||
234 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) { 234 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) {
235 int mid = height()/2 + voffset[i]; 235 int mid = height()/2 + voffset[i];
236 arr.setPoints( 3, 236 arr.setPoints( 3,
237 sw-4, mid - sw + 4, 237 sw-4, mid - sw + 4,
238 0, mid, 238 0, mid,
239 sw-4, mid + sw - 4); 239 sw-4, mid + sw - 4);
240 } 240 }
241 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up || 241 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ||
242 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down) { 242 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down) {
243 int mid = width()/2 + voffset[i]; 243 int mid = width()/2 + voffset[i];
244 arr.setPoints( 3, 244 arr.setPoints( 3,
245 mid - sw + 4, sw-4, 245 mid - sw + 4, sw-4,
246 mid, 0, 246 mid, 0,
247 mid + sw - 4, sw-4 ); 247 mid + sw - 4, sw-4 );
248 } 248 }
249 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down || 249 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down ||
250 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) { 250 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) {
251 int mid = width()/2 + voffset[i]; 251 int mid = width()/2 + voffset[i];
252 arr.setPoints( 3, 252 arr.setPoints( 3,
253 mid - sw + 4, 1-yyy, 253 mid - sw + 4, 1-yyy,
254 mid, sw-3-yyy, 254 mid, sw-3-yyy,
255 mid + sw -4, 1-yyy); 255 mid + sw -4, 1-yyy);
256 } 256 }
257 list.append( arr ); 257 list.append( arr );
258 } 258 }
259 return list; 259 return list;
260} 260}
261 261
262void KDGanttSplitterHandle::paintEvent( QPaintEvent * ) 262void KDGanttSplitterHandle::paintEvent( QPaintEvent * )
263{ 263{
264 QPixmap buffer( size() ); 264 QPixmap buffer( size() );
265 QPainter p( &buffer ); 265 QPainter p( &buffer );
266 266
267 //LR 267 //LR
268 // Draw the splitter rectangle 268 // Draw the splitter rectangle
269 p.setBrush( colorGroup().background() ); 269 p.setBrush( colorGroup().background() );
270 p.setPen( colorGroup().foreground() ); 270 p.setPen( colorGroup().foreground() );
271 //p.drawRect( rect() ); 271 //p.drawRect( rect() );
272 buffer.fill( colorGroup().background() ); 272 buffer.fill( colorGroup().background() );
273 //buffer.fill( backgroundColor() ); 273 //buffer.fill( backgroundColor() );
274 // parentWidget()->style().drawPrimitive( QStyle::PE_Panel, &p, rect(), parentWidget()->colorGroup()); 274 // parentWidget()->style().drawPrimitive( QStyle::PE_Panel, &p, rect(), parentWidget()->colorGroup());
275 275
276 int sw = 8; // Hardcoded, given I didn't use styles anymore, I didn't like to use their size 276 int sw = 8; // Hardcoded, given I didn't use styles anymore, I didn't like to use their size
277 277
278 // arrow color 278 // arrow color
279 QColor col; 279 QColor col;
280 if ( _activeButton ) 280 if ( _activeButton )
281 col = colorGroup().background().dark( 250 ); 281 col = colorGroup().background().dark( 250 );
282 else { 282 else {
283 if ( mMouseDown ) 283 if ( mMouseDown )
284 col = Qt::white; 284 col = Qt::white;
285 else 285 else
286 col = colorGroup().background().dark( 150 ); 286 col = colorGroup().background().dark( 150 );
287 } 287 }
288 //QColor col = backgroundColor().dark( 130 ); 288 //QColor col = backgroundColor().dark( 130 );
289 p.setBrush( col ); 289 p.setBrush( col );
290 p.setPen( col ); 290 p.setPen( col );
291 291
292 QValueList<QPointArray> list = buttonRegions(); 292 QValueList<QPointArray> list = buttonRegions();
293 int index = 1; 293 int index = 1;
294 if ( mUseOffset ) 294 if ( mUseOffset )
295 p.translate( 0, 1 ); 295 p.translate( 0, 1 );
296 for ( QValueList<QPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) { 296 for ( QValueList<QPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) {
297 if ( index == _activeButton ) { 297 if ( index == _activeButton ) {
298 298
299 /* 299 /*
300 if ( ! _collapsed ) { 300 if ( ! _collapsed ) {
301 p.save(); 301 p.save();
302 // p.translate( parentWidget()->style().pixelMetric( QStyle::PM_ButtonShiftHorizontal ), 302 // p.translate( parentWidget()->style().pixelMetric( QStyle::PM_ButtonShiftHorizontal ),
303 // parentWidget()->style().pixelMetric( QStyle::PM_ButtonShiftVertical ) ); 303 // parentWidget()->style().pixelMetric( QStyle::PM_ButtonShiftVertical ) );
304 p.translate( -1, 0 ); 304 p.translate( -1, 0 );
305 p.drawPolygon( *it, true ); 305 p.drawPolygon( *it, true );
306 p.restore(); } else 306 p.restore(); } else
307 */ 307 */
308 p.drawPolygon( *it, true ); 308 p.drawPolygon( *it, true );
309 309
310 } 310 }
311 else { 311 else {
312 /* 312 /*
313 if ( ! _collapsed ) { 313 if ( ! _collapsed ) {
314 p.save(); 314 p.save();
315 p.translate( -1, 0 ); 315 p.translate( -1, 0 );
316 p.drawPolygon( *it, true ); 316 p.drawPolygon( *it, true );
317 p.restore(); 317 p.restore();
318 } else 318 } else
319 */ 319 */
320 p.drawPolygon( *it, true ); 320 p.drawPolygon( *it, true );
321 321
322 } 322 }
323 index++; 323 index++;
324 } 324 }
325 325
326 // Draw the lines between the arrows 326 // Draw the lines between the arrows
327 if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left || 327 if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left ||
328 s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) { 328 s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) {
329 int mid = height()/2; 329 int mid = height()/2;
330 p.drawLine ( 1, mid - sw, 1, mid + sw ); 330 p.drawLine ( 1, mid - sw, 1, mid + sw );
331 p.drawLine ( 3, mid - sw, 3, mid + sw ); 331 p.drawLine ( 3, mid - sw, 3, mid + sw );
332 } 332 }
333 else if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Up || 333 else if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Up ||
334 s->minimizeDirection() == KDGanttMinimizeSplitter::Down ) { 334 s->minimizeDirection() == KDGanttMinimizeSplitter::Down ) {
335 int mid = width()/2; 335 int mid = width()/2;
336 p.drawLine( mid -sw, 1, mid +sw, 1 ); 336 p.drawLine( mid -sw, 1, mid +sw, 1 );
337 p.drawLine( mid -sw, 3, mid +sw, 3 ); 337 p.drawLine( mid -sw, 3, mid +sw, 3 );
338 } 338 }
339 bitBlt( this, 0, 0, &buffer ); 339 bitBlt( this, 0, 0, &buffer );
340 340
341} 341}
342#endif 342#endif
343 343
344class QSplitterLayoutStruct 344class QSplitterLayoutStruct
345{ 345{
346public: 346public:
347 KDGanttMinimizeSplitter::ResizeMode mode; 347 KDGanttMinimizeSplitter::ResizeMode mode;
348 QCOORD sizer; 348 QCOORD sizer;
349 bool isSplitter; 349 bool isSplitter;
350 QWidget *wid; 350 QWidget *wid;
351}; 351};
352 352
353class QSplitterData 353class QSplitterData
354{ 354{
355public: 355public:
356 QSplitterData() : opaque( FALSE ), firstShow( TRUE ) {} 356 QSplitterData() : opaque( FALSE ), firstShow( TRUE ) {}
357 357
358 QPtrList<QSplitterLayoutStruct> list; 358 QPtrList<QSplitterLayoutStruct> list;
359 bool opaque; 359 bool opaque;
360 bool firstShow; 360 bool firstShow;
361}; 361};
362 362
363void kdganttGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos, 363void kdganttGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos,
364 int space, int spacer ); 364 int space, int spacer );
365#endif // DOXYGEN_SKIP_INTERNAL 365#endif // DOXYGEN_SKIP_INTERNAL
366 366
367 367
368/*! 368/*!
369 \class KDGanttMinimizeSplitter KDGanttMinimizeSplitter.h 369 \class KDGanttMinimizeSplitter KDGanttMinimizeSplitter.h
370 \brief The KDGanttMinimizeSplitter class implements a splitter 370 \brief The KDGanttMinimizeSplitter class implements a splitter
371 widget with minimize buttons. 371 widget with minimize buttons.
372 372
373 This class (and its documentation) is largely a copy of Qt's 373 This class (and its documentation) is largely a copy of Qt's
374 QSplitter; the copying was necessary because QSplitter is not 374 QSplitter; the copying was necessary because QSplitter is not
375 extensible at all. QSplitter and its documentation are licensed 375 extensible at all. QSplitter and its documentation are licensed
376 according to the GPL and the Qt Professional License (if you hold 376 according to the GPL and the Qt Professional License (if you hold
377 such a license) and are (C) Trolltech AS. 377 such a license) and are (C) Trolltech AS.
378 378
379 A splitter lets the user control the size of child widgets by 379 A splitter lets the user control the size of child widgets by
380 dragging the boundary between the children. Any number of widgets 380 dragging the boundary between the children. Any number of widgets
381 may be controlled. 381 may be controlled.
382 382
383 To show a QListBox, a QListView and a QTextEdit side by side: 383 To show a QListBox, a QListView and a QTextEdit side by side:
384 384
385 \code 385 \code
386 KDGanttMinimizeSplitter *split = new KDGanttMinimizeSplitter( parent ); 386 KDGanttMinimizeSplitter *split = new KDGanttMinimizeSplitter( parent );
387 QListBox *lb = new QListBox( split ); 387 QListBox *lb = new QListBox( split );
388 QListView *lv = new QListView( split ); 388 QListView *lv = new QListView( split );
389 QTextEdit *ed = new QTextEdit( split ); 389 QTextEdit *ed = new QTextEdit( split );
390 \endcode 390 \endcode
391 391
392 In KDGanttMinimizeSplitter, the boundary can be either horizontal or 392 In KDGanttMinimizeSplitter, the boundary can be either horizontal or
393 vertical. The default is horizontal (the children are side by side) 393 vertical. The default is horizontal (the children are side by side)
394 but you can use setOrientation( QSplitter::Vertical ) to set it to 394 but you can use setOrientation( QSplitter::Vertical ) to set it to
395 vertical. 395 vertical.
396 396
397 Use setResizeMode() to specify 397 Use setResizeMode() to specify
398 that a widget should keep its size when the splitter is resized. 398 that a widget should keep its size when the splitter is resized.
399 399
400 Although KDGanttMinimizeSplitter normally resizes the children only 400 Although KDGanttMinimizeSplitter normally resizes the children only
401 at the end of a resize operation, if you call setOpaqueResize( TRUE 401 at the end of a resize operation, if you call setOpaqueResize( TRUE
402 ) the widgets are resized as often as possible. 402 ) the widgets are resized as often as possible.
403 403
404 The initial distribution of size between the widgets is determined 404 The initial distribution of size between the widgets is determined
405 by the initial size of each widget. You can also use setSizes() to 405 by the initial size of each widget. You can also use setSizes() to
406 set the sizes of all the widgets. The function sizes() returns the 406 set the sizes of all the widgets. The function sizes() returns the
407 sizes set by the user. 407 sizes set by the user.
408 408
409 If you hide() a child, its space will be distributed among the other 409 If you hide() a child, its space will be distributed among the other
410 children. It will be reinstated when you show() it again. It is also 410 children. It will be reinstated when you show() it again. It is also
411 possible to reorder the widgets within the splitter using 411 possible to reorder the widgets within the splitter using
412 moveToFirst() and moveToLast(). 412 moveToFirst() and moveToLast().
413*/ 413*/
414 414
415 415
416 416
417static QSize minSize( const QWidget* /*w*/ ) 417static QSize minSize( const QWidget* /*w*/ )
418{ 418{
419 return QSize(0,0); 419 return QSize(0,0);
420} 420}
421 421
422// This is the original version of minSize 422// This is the original version of minSize
423static QSize minSizeHint( const QWidget* w ) 423static QSize minSizeHint( const QWidget* w )
424{ 424{
425 QSize min = w->minimumSize(); 425 QSize min = w->minimumSize();
426 QSize s; 426 QSize s;
427 if ( min.height() <= 0 || min.width() <= 0 ) 427 if ( min.height() <= 0 || min.width() <= 0 )
428 s = w->minimumSizeHint(); 428 s = w->minimumSizeHint();
429 if ( min.height() > 0 ) 429 if ( min.height() > 0 )
430 s.setHeight( min.height() ); 430 s.setHeight( min.height() );
431 if ( min.width() > 0 ) 431 if ( min.width() > 0 )
432 s.setWidth( min.width() ); 432 s.setWidth( min.width() );
433 return s.expandedTo(QSize(0,0)); 433 return s.expandedTo(QSize(0,0));
434} 434}
435 435
436 436
437 437
438/*! 438/*!
439 Constructs a horizontal splitter with the \a parent and \a 439 Constructs a horizontal splitter with the \a parent and \a
440 name arguments being passed on to the QFrame constructor. 440 name arguments being passed on to the QFrame constructor.
441*/ 441*/
442KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( QWidget *parent, const char *name ) 442KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( QWidget *parent, const char *name )
443 :QFrame(parent,name,WPaintUnclipped) 443 :QFrame(parent,name,WPaintUnclipped)
444{ 444{
445 mFirstHandle = 0; 445 mFirstHandle = 0;
446#if QT_VERSION >= 232 446#if QT_VERSION >= 232
447 orient = Horizontal; 447 orient = Horizontal;
448 init(); 448 init();
449#endif 449#endif
450} 450}
451 451
452/*! 452/*!
453 Constructs a splitter with orientation \a o with the \a parent 453 Constructs a splitter with orientation \a o with the \a parent
454 and \a name arguments being passed on to the QFrame constructor. 454 and \a name arguments being passed on to the QFrame constructor.
455*/ 455*/
456KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( Orientation o, QWidget *parent, const char *name ) 456KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( Orientation o, QWidget *parent, const char *name )
457 :QFrame(parent,name,WPaintUnclipped) 457 :QFrame(parent,name,WPaintUnclipped)
458{ 458{
459 mFirstHandle = 0; 459 mFirstHandle = 0;
460#if QT_VERSION >= 232 460#if QT_VERSION >= 232
461 orient = o; 461 orient = o;
462 init(); 462 init();
463#endif 463#endif
464} 464}
465 465
466/*! 466/*!
467 Destroys the splitter and any children. 467 Destroys the splitter and any children.
468*/ 468*/
469KDGanttMinimizeSplitter::~KDGanttMinimizeSplitter() 469KDGanttMinimizeSplitter::~KDGanttMinimizeSplitter()
470{ 470{
471#if QT_VERSION >= 232 471#if QT_VERSION >= 232
472 data->list.setAutoDelete( TRUE ); 472 data->list.setAutoDelete( TRUE );
473 delete data; 473 delete data;
474#endif 474#endif
475} 475}
476 476
477 477
478#if QT_VERSION >= 232 478#if QT_VERSION >= 232
479void KDGanttMinimizeSplitter::init() 479void KDGanttMinimizeSplitter::init()
480{ 480{
481 data = new QSplitterData; 481 data = new QSplitterData;
482 if ( orient == Horizontal ) 482 if ( orient == Horizontal )
483 setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum) ); 483 setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum) );
484 else 484 else
485 setSizePolicy( QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Expanding) ); 485 setSizePolicy( QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Expanding) );
486#ifndef DESKTOP_VERSION
487 setOpaqueResize( false );
488#else
489 setOpaqueResize( true );
490#endif
486} 491}
487#endif 492#endif
488 493
489 494
490void KDGanttMinimizeSplitter::toggle() 495void KDGanttMinimizeSplitter::toggle()
491{ 496{
492 if ( mFirstHandle ) 497 if ( mFirstHandle )
493 mFirstHandle->toggle(); 498 mFirstHandle->toggle();
494 else 499 else
495 qDebug("KDGanttMinimizeSplitter::toggle::sorry, handle not available "); 500 qDebug("KDGanttMinimizeSplitter::toggle::sorry, handle not available ");
496 501
497} 502}
498 503
499 504
500/*! 505/*!
501 \brief the orientation of the splitter 506 \brief the orientation of the splitter
502 507
503 By default the orientation is horizontal (the widgets are side by side). 508 By default the orientation is horizontal (the widgets are side by side).
504 The possible orientations are Qt:Vertical and Qt::Horizontal (the default). 509 The possible orientations are Qt:Vertical and Qt::Horizontal (the default).
505*/ 510*/
506void KDGanttMinimizeSplitter::setOrientation( Orientation o ) 511void KDGanttMinimizeSplitter::setOrientation( Orientation o )
507{ 512{
508#if QT_VERSION >= 232 513#if QT_VERSION >= 232
509 if ( orient == o ) 514 if ( orient == o )
510 return; 515 return;
511 orient = o; 516 orient = o;
512 517
513 if ( orient == Horizontal ) 518 if ( orient == Horizontal )
514 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); 519 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) );
515 else 520 else
516 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) ); 521 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
517 522
518 QSplitterLayoutStruct *s = data->list.first(); 523 QSplitterLayoutStruct *s = data->list.first();
519 while ( s ) { 524 while ( s ) {
520 if ( s->isSplitter ) 525 if ( s->isSplitter )
521 ((KDGanttSplitterHandle*)s->wid)->setOrientation( o ); 526 ((KDGanttSplitterHandle*)s->wid)->setOrientation( o );
522 s = data->list.next(); // ### next at end of loop, no iterator 527 s = data->list.next(); // ### next at end of loop, no iterator
523 } 528 }
524 recalc( isVisible() ); 529 recalc( isVisible() );
525#endif 530#endif
526} 531}
527 532
528 533
529#if QT_VERSION >= 232 534#if QT_VERSION >= 232
530/*! 535/*!
531 \reimp 536 \reimp
532*/ 537*/
533void KDGanttMinimizeSplitter::resizeEvent( QResizeEvent * ) 538void KDGanttMinimizeSplitter::resizeEvent( QResizeEvent * )
534{ 539{
535 doResize(); 540 doResize();
536} 541}
537 542
538 543
539/* 544/*
540 Inserts the widget \a w at the end (or at the beginning if \a first 545 Inserts the widget \a w at the end (or at the beginning if \a first
541 is TRUE) of the splitter's list of widgets. 546 is TRUE) of the splitter's list of widgets.
542 547
543 It is the responsibility of the caller of this function to make sure 548 It is the responsibility of the caller of this function to make sure
544 that \a w is not already in the splitter and to call recalcId if 549 that \a w is not already in the splitter and to call recalcId if
545 needed. (If \a first is TRUE, then recalcId is very probably 550 needed. (If \a first is TRUE, then recalcId is very probably
546 needed.) 551 needed.)
547*/ 552*/
548QSplitterLayoutStruct *KDGanttMinimizeSplitter::addWidget( QWidget *w, bool first ) 553QSplitterLayoutStruct *KDGanttMinimizeSplitter::addWidget( QWidget *w, bool first )
549{ 554{
550 QSplitterLayoutStruct *s; 555 QSplitterLayoutStruct *s;
551 KDGanttSplitterHandle *newHandle = 0; 556 KDGanttSplitterHandle *newHandle = 0;
552 if ( data->list.count() > 0 ) { 557 if ( data->list.count() > 0 ) {
553 s = new QSplitterLayoutStruct; 558 s = new QSplitterLayoutStruct;
554 s->mode = KeepSize; 559 s->mode = KeepSize;
555 QString tmp = "qt_splithandle_"; 560 QString tmp = "qt_splithandle_";
556 tmp += w->name(); 561 tmp += w->name();
557 newHandle = new KDGanttSplitterHandle( orientation(), this, tmp.latin1() ); 562 newHandle = new KDGanttSplitterHandle( orientation(), this, tmp.latin1() );
558 if ( ! mFirstHandle ) 563 if ( ! mFirstHandle )
559 mFirstHandle = newHandle; 564 mFirstHandle = newHandle;
560 s->wid = newHandle; 565 s->wid = newHandle;
561 newHandle->setId(data->list.count()); 566 newHandle->setId(data->list.count());
562 s->isSplitter = TRUE; 567 s->isSplitter = TRUE;
563 s->sizer = pick( newHandle->sizeHint() ); 568 s->sizer = pick( newHandle->sizeHint() );
564 if ( first ) 569 if ( first )
565 data->list.insert( 0, s ); 570 data->list.insert( 0, s );
566 else 571 else
567 data->list.append( s ); 572 data->list.append( s );
568 } 573 }
569 s = new QSplitterLayoutStruct; 574 s = new QSplitterLayoutStruct;
570 s->mode = Stretch; 575 s->mode = Stretch;
571 s->wid = w; 576 s->wid = w;
572 if ( !testWState( WState_Resized ) && w->sizeHint().isValid() ) 577 if ( !testWState( WState_Resized ) && w->sizeHint().isValid() )
573 s->sizer = pick( w->sizeHint() ); 578 s->sizer = pick( w->sizeHint() );
574 else 579 else
575 s->sizer = pick( w->size() ); 580 s->sizer = pick( w->size() );
576 s->isSplitter = FALSE; 581 s->isSplitter = FALSE;
577 if ( first ) 582 if ( first )
578 data->list.insert( 0, s ); 583 data->list.insert( 0, s );
579 else 584 else
580 data->list.append( s ); 585 data->list.append( s );
581 if ( newHandle && isVisible() ) 586 if ( newHandle && isVisible() )
582 newHandle->show(); //will trigger sending of post events 587 newHandle->show(); //will trigger sending of post events
583 return s; 588 return s;
584} 589}
585 590
586 591
587/*! 592/*!
588 Tells the splitter that a child widget has been inserted or removed. 593 Tells the splitter that a child widget has been inserted or removed.
589 The event is passed in \a c. 594 The event is passed in \a c.
590*/ 595*/
591void KDGanttMinimizeSplitter::childEvent( QChildEvent *c ) 596void KDGanttMinimizeSplitter::childEvent( QChildEvent *c )
592{ 597{
593 if ( c->type() == QEvent::ChildInserted ) { 598 if ( c->type() == QEvent::ChildInserted ) {
594 if ( !c->child()->isWidgetType() ) 599 if ( !c->child()->isWidgetType() )
595 return; 600 return;
596 601
597 if ( ((QWidget*)c->child())->testWFlags( WType_TopLevel ) ) 602 if ( ((QWidget*)c->child())->testWFlags( WType_TopLevel ) )
598 return; 603 return;
599 604
600 QSplitterLayoutStruct *s = data->list.first(); 605 QSplitterLayoutStruct *s = data->list.first();
601 while ( s ) { 606 while ( s ) {
602 if ( s->wid == c->child() ) 607 if ( s->wid == c->child() )
603 return; 608 return;
604 s = data->list.next(); 609 s = data->list.next();
605 } 610 }
606 addWidget( (QWidget*)c->child() ); 611 addWidget( (QWidget*)c->child() );
607 recalc( isVisible() ); 612 recalc( isVisible() );
608 613
609 } else if ( c->type() == QEvent::ChildRemoved ) { 614 } else if ( c->type() == QEvent::ChildRemoved ) {
610 QSplitterLayoutStruct *p = 0; 615 QSplitterLayoutStruct *p = 0;
611 if ( data->list.count() > 1 ) 616 if ( data->list.count() > 1 )
612 p = data->list.at(1); //remove handle _after_ first widget. 617 p = data->list.at(1); //remove handle _after_ first widget.
613 QSplitterLayoutStruct *s = data->list.first(); 618 QSplitterLayoutStruct *s = data->list.first();
614 while ( s ) { 619 while ( s ) {
615 if ( s->wid == c->child() ) { 620 if ( s->wid == c->child() ) {
616 data->list.removeRef( s ); 621 data->list.removeRef( s );
617 delete s; 622 delete s;
618 if ( p && p->isSplitter ) { 623 if ( p && p->isSplitter ) {
619 data->list.removeRef( p ); 624 data->list.removeRef( p );
620 delete p->wid; //will call childEvent 625 delete p->wid; //will call childEvent
621 delete p; 626 delete p;
622 } 627 }
623 recalcId(); 628 recalcId();
624 doResize(); 629 doResize();
625 return; 630 return;
626 } 631 }
627 p = s; 632 p = s;
628 s = data->list.next(); 633 s = data->list.next();
629 } 634 }
630 } 635 }
631} 636}
632 637
633 638
634/*! 639/*!
635 Shows a rubber band at position \a p. If \a p is negative, the 640 Shows a rubber band at position \a p. If \a p is negative, the
636 rubber band is removed. 641 rubber band is removed.
637*/ 642*/
638void KDGanttMinimizeSplitter::setRubberband( int p ) 643void KDGanttMinimizeSplitter::setRubberband( int p )
639{ 644{
640 QPainter paint( this ); 645 QPainter paint( this );
641 paint.setPen( gray ); 646 paint.setPen( gray );
642 paint.setBrush( gray ); 647 paint.setBrush( gray );
643 paint.setRasterOp( XorROP ); 648 paint.setRasterOp( XorROP );
644 QRect r = contentsRect(); 649 QRect r = contentsRect();
645 const int rBord = 3; //Themable???? 650 const int rBord = 3; //Themable????
646#if QT_VERSION >= 0x030000 651#if QT_VERSION >= 0x030000
647 int sw = style().pixelMetric(QStyle::PM_SplitterWidth, this); 652 int sw = style().pixelMetric(QStyle::PM_SplitterWidth, this);
648#else 653#else
649 int sw = style().splitterWidth(); 654 int sw = style().splitterWidth();
650#endif 655#endif
651 if ( orient == Horizontal ) { 656 if ( orient == Horizontal ) {
652 if ( opaqueOldPos >= 0 ) 657 if ( opaqueOldPos >= 0 )
653 paint.drawRect( opaqueOldPos + sw/2 - rBord , r.y(), 658 paint.drawRect( opaqueOldPos + sw/2 - rBord , r.y(),
654 2*rBord, r.height() ); 659 2*rBord, r.height() );
655 if ( p >= 0 ) 660 if ( p >= 0 )
656 paint.drawRect( p + sw/2 - rBord, r.y(), 2*rBord, r.height() ); 661 paint.drawRect( p + sw/2 - rBord, r.y(), 2*rBord, r.height() );
657 } else { 662 } else {
658 if ( opaqueOldPos >= 0 ) 663 if ( opaqueOldPos >= 0 )
659 paint.drawRect( r.x(), opaqueOldPos + sw/2 - rBord, 664 paint.drawRect( r.x(), opaqueOldPos + sw/2 - rBord,
660 r.width(), 2*rBord ); 665 r.width(), 2*rBord );
661 if ( p >= 0 ) 666 if ( p >= 0 )
662 paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord ); 667 paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
663 } 668 }
664 opaqueOldPos = p; 669 opaqueOldPos = p;
665} 670}
666 671
667 672
668/*! \reimp */ 673/*! \reimp */
669bool KDGanttMinimizeSplitter::event( QEvent *e ) 674bool KDGanttMinimizeSplitter::event( QEvent *e )
670{ 675{
671 if ( e->type() == QEvent::LayoutHint || ( e->type() == QEvent::Show && data->firstShow ) ) { 676 if ( e->type() == QEvent::LayoutHint || ( e->type() == QEvent::Show && data->firstShow ) ) {
672 recalc( isVisible() ); 677 recalc( isVisible() );
673 if ( e->type() == QEvent::Show ) 678 if ( e->type() == QEvent::Show )
674 data->firstShow = FALSE; 679 data->firstShow = FALSE;
675 } 680 }
676 return QWidget::event( e ); 681 return QWidget::event( e );
677} 682}
678 683
679 684
680/*! 685/*!
681 \obsolete 686 \obsolete
682 687
683 Draws the splitter handle in the rectangle described by \a x, \a y, 688 Draws the splitter handle in the rectangle described by \a x, \a y,
684 \a w, \a h using painter \a p. 689 \a w, \a h using painter \a p.
685 \sa QStyle::drawPrimitive() 690 \sa QStyle::drawPrimitive()
686*/ 691*/
687void KDGanttMinimizeSplitter::drawSplitter( QPainter *p, 692void KDGanttMinimizeSplitter::drawSplitter( QPainter *p,
688 QCOORD x, QCOORD y, QCOORD w, QCOORD h ) 693 QCOORD x, QCOORD y, QCOORD w, QCOORD h )
689{ 694{
690#if 0 695#if 0
691 // LR 696 // LR
692 style().drawPrimitive(QStyle::PE_Splitter, p, QRect(x, y, w, h), colorGroup(), 697 style().drawPrimitive(QStyle::PE_Splitter, p, QRect(x, y, w, h), colorGroup(),
693 (orientation() == Qt::Horizontal ? 698 (orientation() == Qt::Horizontal ?
694 QStyle::Style_Horizontal : 0)); 699 QStyle::Style_Horizontal : 0));
695#endif 700#endif
696} 701}
697 702
698 703
699/*! 704/*!
700 Returns the id of the splitter to the right of or below the widget \a w, 705 Returns the id of the splitter to the right of or below the widget \a w,
701 or 0 if there is no such splitter 706 or 0 if there is no such splitter
702 (i.e. it is either not in this KDGanttMinimizeSplitter or it is at the end). 707 (i.e. it is either not in this KDGanttMinimizeSplitter or it is at the end).
703*/ 708*/
704int KDGanttMinimizeSplitter::idAfter( QWidget* w ) const 709int KDGanttMinimizeSplitter::idAfter( QWidget* w ) const
705{ 710{
706 QSplitterLayoutStruct *s = data->list.first(); 711 QSplitterLayoutStruct *s = data->list.first();
707 bool seen_w = FALSE; 712 bool seen_w = FALSE;
708 while ( s ) { 713 while ( s ) {
709 if ( s->isSplitter && seen_w ) 714 if ( s->isSplitter && seen_w )
710 return data->list.at(); 715 return data->list.at();
711 if ( !s->isSplitter && s->wid == w ) 716 if ( !s->isSplitter && s->wid == w )
712 seen_w = TRUE; 717 seen_w = TRUE;
713 s = data->list.next(); 718 s = data->list.next();
714 } 719 }
715 return 0; 720 return 0;
716} 721}
717 722
718 723
719/*! 724/*!
720 Moves the left/top edge of the splitter handle with id \a id as 725 Moves the left/top edge of the splitter handle with id \a id as
721 close as possible to position \a p, which is the distance from the 726 close as possible to position \a p, which is the distance from the
722 left (or top) edge of the widget. 727 left (or top) edge of the widget.
723 728
724 For Arabic and Hebrew the layout is reversed, and using this 729 For Arabic and Hebrew the layout is reversed, and using this
725 function to set the position of the splitter might lead to 730 function to set the position of the splitter might lead to
726 unexpected results, since in Arabic and Hebrew the position of 731 unexpected results, since in Arabic and Hebrew the position of
727 splitter one is to the left of the position of splitter zero. 732 splitter one is to the left of the position of splitter zero.
728 733
729 \sa idAfter() 734 \sa idAfter()
730*/ 735*/
731void KDGanttMinimizeSplitter::moveSplitter( QCOORD p, int id ) 736void KDGanttMinimizeSplitter::moveSplitter( QCOORD p, int id )
732{ 737{
733 p = adjustPos( p, id ); 738 p = adjustPos( p, id );
734 QSplitterLayoutStruct *s = data->list.at(id); 739 QSplitterLayoutStruct *s = data->list.at(id);
735 int oldP = orient == Horizontal ? s->wid->x() : s->wid->y(); 740 int oldP = orient == Horizontal ? s->wid->x() : s->wid->y();
736 bool upLeft; 741 bool upLeft;
737 if ( false && orient == Horizontal ) { 742 if ( false && orient == Horizontal ) {
738 p += s->wid->width(); 743 p += s->wid->width();
739 upLeft = p > oldP; 744 upLeft = p > oldP;
740 } else 745 } else
741 upLeft = p < oldP; 746 upLeft = p < oldP;
742 747
743 moveAfter( p, id, upLeft ); 748 moveAfter( p, id, upLeft );
744 moveBefore( p-1, id-1, upLeft ); 749 moveBefore( p-1, id-1, upLeft );
745 750
746 storeSizes(); 751 storeSizes();
747} 752}
748 753
749 754
750void KDGanttMinimizeSplitter::setG( QWidget *w, int p, int s, bool isSplitter ) 755void KDGanttMinimizeSplitter::setG( QWidget *w, int p, int s, bool isSplitter )
751{ 756{
752 if ( orient == Horizontal ) { 757 if ( orient == Horizontal ) {
753 if ( false && orient == Horizontal && !isSplitter ) 758 if ( false && orient == Horizontal && !isSplitter )
754 p = contentsRect().width() - p - s; 759 p = contentsRect().width() - p - s;
755 w->setGeometry( p, contentsRect().y(), s, contentsRect().height() ); 760 w->setGeometry( p, contentsRect().y(), s, contentsRect().height() );
756 } else 761 } else
757 w->setGeometry( contentsRect().x(), p, contentsRect().width(), s ); 762 w->setGeometry( contentsRect().x(), p, contentsRect().width(), s );
758} 763}
759 764
760 765
761/* 766/*
762 Places the right/bottom edge of the widget at \a id at position \a pos. 767 Places the right/bottom edge of the widget at \a id at position \a pos.
763 768
764 \sa idAfter() 769 \sa idAfter()
765*/ 770*/
766void KDGanttMinimizeSplitter::moveBefore( int pos, int id, bool upLeft ) 771void KDGanttMinimizeSplitter::moveBefore( int pos, int id, bool upLeft )
767{ 772{
768 if( id < 0 ) 773 if( id < 0 )
769 return; 774 return;
770 QSplitterLayoutStruct *s = data->list.at(id); 775 QSplitterLayoutStruct *s = data->list.at(id);
771 if ( !s ) 776 if ( !s )
772 return; 777 return;
773 QWidget *w = s->wid; 778 QWidget *w = s->wid;
774 if ( w->isHidden() ) { 779 if ( w->isHidden() ) {
775 moveBefore( pos, id-1, upLeft ); 780 moveBefore( pos, id-1, upLeft );
776 } else if ( s->isSplitter ) { 781 } else if ( s->isSplitter ) {
777 int pos1, pos2; 782 int pos1, pos2;
778 int dd = s->sizer; 783 int dd = s->sizer;
779 if( false && orient == Horizontal ) { 784 if( false && orient == Horizontal ) {
780 pos1 = pos; 785 pos1 = pos;
781 pos2 = pos + dd; 786 pos2 = pos + dd;
782 } else { 787 } else {
783 pos2 = pos - dd; 788 pos2 = pos - dd;
784 pos1 = pos2 + 1; 789 pos1 = pos2 + 1;
785 } 790 }
786 if ( upLeft ) { 791 if ( upLeft ) {
787 setG( w, pos1, dd, TRUE ); 792 setG( w, pos1, dd, TRUE );
788 moveBefore( pos2, id-1, upLeft ); 793 moveBefore( pos2, id-1, upLeft );
789 } else { 794 } else {
790 moveBefore( pos2, id-1, upLeft ); 795 moveBefore( pos2, id-1, upLeft );
791 setG( w, pos1, dd, TRUE ); 796 setG( w, pos1, dd, TRUE );
792 } 797 }
793 } else { 798 } else {
794 int dd, newLeft, nextPos; 799 int dd, newLeft, nextPos;
795 if( false && orient == Horizontal ) { 800 if( false && orient == Horizontal ) {
796 dd = w->geometry().right() - pos; 801 dd = w->geometry().right() - pos;
797 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize()))); 802 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
798 newLeft = pos+1; 803 newLeft = pos+1;
799 nextPos = newLeft + dd; 804 nextPos = newLeft + dd;
800 } else { 805 } else {
801 dd = pos - pick( w->pos() ) + 1; 806 dd = pos - pick( w->pos() ) + 1;
802 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize()))); 807 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
803 newLeft = pos-dd+1; 808 newLeft = pos-dd+1;
804 nextPos = newLeft - 1; 809 nextPos = newLeft - 1;
805 } 810 }
806 setG( w, newLeft, dd, TRUE ); 811 setG( w, newLeft, dd, TRUE );
807 moveBefore( nextPos, id-1, upLeft ); 812 moveBefore( nextPos, id-1, upLeft );
808 } 813 }
809} 814}
810 815
811 816
812/* 817/*
813 Places the left/top edge of the widget at \a id at position \a pos. 818 Places the left/top edge of the widget at \a id at position \a pos.
814 819
815 \sa idAfter() 820 \sa idAfter()
816*/ 821*/
817void KDGanttMinimizeSplitter::moveAfter( int pos, int id, bool upLeft ) 822void KDGanttMinimizeSplitter::moveAfter( int pos, int id, bool upLeft )
818{ 823{
819 QSplitterLayoutStruct *s = id < int(data->list.count()) ? 824 QSplitterLayoutStruct *s = id < int(data->list.count()) ?
820 data->list.at(id) : 0; 825 data->list.at(id) : 0;
821 if ( !s ) 826 if ( !s )
822 return; 827 return;
823 QWidget *w = s->wid; 828 QWidget *w = s->wid;
824 if ( w->isHidden() ) { 829 if ( w->isHidden() ) {
825 moveAfter( pos, id+1, upLeft ); 830 moveAfter( pos, id+1, upLeft );
826 } else if ( pick( w->pos() ) == pos ) { 831 } else if ( pick( w->pos() ) == pos ) {
827 //No need to do anything if it's already there. 832 //No need to do anything if it's already there.
828 return; 833 return;
829 } else if ( s->isSplitter ) { 834 } else if ( s->isSplitter ) {
830 int dd = s->sizer; 835 int dd = s->sizer;
831 int pos1, pos2; 836 int pos1, pos2;
832 if( false && orient == Horizontal ) { 837 if( false && orient == Horizontal ) {
833 pos2 = pos - dd; 838 pos2 = pos - dd;
834 pos1 = pos2 + 1; 839 pos1 = pos2 + 1;
835 } else { 840 } else {
836 pos1 = pos; 841 pos1 = pos;
837 pos2 = pos + dd; 842 pos2 = pos + dd;
838 } 843 }
839 if ( upLeft ) { 844 if ( upLeft ) {
840 setG( w, pos1, dd, TRUE ); 845 setG( w, pos1, dd, TRUE );
841 moveAfter( pos2, id+1, upLeft ); 846 moveAfter( pos2, id+1, upLeft );
842 } else { 847 } else {
843 moveAfter( pos2, id+1, upLeft ); 848 moveAfter( pos2, id+1, upLeft );
844 setG( w, pos1, dd, TRUE ); 849 setG( w, pos1, dd, TRUE );
845 } 850 }
846 } else { 851 } else {
847 int left = pick( w->pos() ); 852 int left = pick( w->pos() );
848 int right, dd,/* newRight,*/ newLeft, nextPos; 853 int right, dd,/* newRight,*/ newLeft, nextPos;
849 if ( false && orient == Horizontal ) { 854 if ( false && orient == Horizontal ) {
850 dd = pos - left + 1; 855 dd = pos - left + 1;
851 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize()))); 856 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
852 newLeft = pos-dd+1; 857 newLeft = pos-dd+1;
853 nextPos = newLeft - 1; 858 nextPos = newLeft - 1;
854 } else { 859 } else {
855 right = pick( w->geometry().bottomRight() ); 860 right = pick( w->geometry().bottomRight() );
856 dd = right - pos + 1; 861 dd = right - pos + 1;
857 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize()))); 862 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
858 /*newRight = pos+dd-1;*/ 863 /*newRight = pos+dd-1;*/
859 newLeft = pos; 864 newLeft = pos;
860 nextPos = newLeft + dd; 865 nextPos = newLeft + dd;
861 } 866 }
862 setG( w, newLeft, dd, TRUE ); 867 setG( w, newLeft, dd, TRUE );
863 /*if( right != newRight )*/ 868 /*if( right != newRight )*/
864 moveAfter( nextPos, id+1, upLeft ); 869 moveAfter( nextPos, id+1, upLeft );
865 } 870 }
866} 871}
867 872
868 873
869void KDGanttMinimizeSplitter::expandPos( int id, int* min, int* max ) 874void KDGanttMinimizeSplitter::expandPos( int id, int* min, int* max )
870{ 875{
871 QSplitterLayoutStruct *s = data->list.at(id-1); 876 QSplitterLayoutStruct *s = data->list.at(id-1);
872 QWidget* w = s->wid; 877 QWidget* w = s->wid;
873 *min = pick( w->mapToParent( QPoint(0,0) ) ); 878 *min = pick( w->mapToParent( QPoint(0,0) ) );
874 879
875 if ( (uint) id == data->list.count() ) { 880 if ( (uint) id == data->list.count() ) {
876 pick( size() ); 881 pick( size() );
877 } 882 }
878 else { 883 else {
879 QSplitterLayoutStruct *s = data->list.at(id+1); 884 QSplitterLayoutStruct *s = data->list.at(id+1);
880 QWidget* w = s->wid; 885 QWidget* w = s->wid;
881 *max = pick( w->mapToParent( QPoint( w->width(), w->height() ) ) ) -8; 886 *max = pick( w->mapToParent( QPoint( w->width(), w->height() ) ) ) -8;
882 } 887 }
883} 888}
884 889
885 890
886/*! 891/*!
887 Returns the valid range of the splitter with id \a id in \a *min and \a *max. 892 Returns the valid range of the splitter with id \a id in \a *min and \a *max.
888 893
889 \sa idAfter() 894 \sa idAfter()
890*/ 895*/
891 896
892void KDGanttMinimizeSplitter::getRange( int id, int *min, int *max ) 897void KDGanttMinimizeSplitter::getRange( int id, int *min, int *max )
893{ 898{
894 int minB = 0;//before 899 int minB = 0;//before
895 int maxB = 0; 900 int maxB = 0;
896 int minA = 0; 901 int minA = 0;
897 int maxA = 0;//after 902 int maxA = 0;//after
898 int n = data->list.count(); 903 int n = data->list.count();
899 if ( id < 0 || id >= n ) 904 if ( id < 0 || id >= n )
900 return; 905 return;
901 int i; 906 int i;
902 for ( i = 0; i < id; i++ ) { 907 for ( i = 0; i < id; i++ ) {
903 QSplitterLayoutStruct *s = data->list.at(i); 908 QSplitterLayoutStruct *s = data->list.at(i);
904 if ( s->wid->isHidden() ) { 909 if ( s->wid->isHidden() ) {
905 //ignore 910 //ignore
906 } else if ( s->isSplitter ) { 911 } else if ( s->isSplitter ) {
907 minB += s->sizer; 912 minB += s->sizer;
908 maxB += s->sizer; 913 maxB += s->sizer;
909 } else { 914 } else {
910 minB += pick( minSize(s->wid) ); 915 minB += pick( minSize(s->wid) );
911 maxB += pick( s->wid->maximumSize() ); 916 maxB += pick( s->wid->maximumSize() );
912 } 917 }
913 } 918 }
914 for ( i = id; i < n; i++ ) { 919 for ( i = id; i < n; i++ ) {
915 QSplitterLayoutStruct *s = data->list.at(i); 920 QSplitterLayoutStruct *s = data->list.at(i);
916 if ( s->wid->isHidden() ) { 921 if ( s->wid->isHidden() ) {
917 //ignore 922 //ignore
918 } else if ( s->isSplitter ) { 923 } else if ( s->isSplitter ) {
919 minA += s->sizer; 924 minA += s->sizer;
920 maxA += s->sizer; 925 maxA += s->sizer;
921 } else { 926 } else {
922 minA += pick( minSize(s->wid) ); 927 minA += pick( minSize(s->wid) );
923 maxA += pick( s->wid->maximumSize() ); 928 maxA += pick( s->wid->maximumSize() );
924 } 929 }
925 } 930 }
926 QRect r = contentsRect(); 931 QRect r = contentsRect();
927 if ( orient == Horizontal && false ) { 932 if ( orient == Horizontal && false ) {
928#if QT_VERSION >= 0x030000 933#if QT_VERSION >= 0x030000
929 int splitterWidth = style().pixelMetric(QStyle::PM_SplitterWidth, this); 934 int splitterWidth = style().pixelMetric(QStyle::PM_SplitterWidth, this);
930#else 935#else
931 int splitterWidth = style().splitterWidth(); 936 int splitterWidth = style().splitterWidth();
932#endif 937#endif
933 938
934 if ( min ) 939 if ( min )
935 *min = pick(r.topRight()) - QMIN( maxB, pick(r.size())-minA ) - splitterWidth; 940 *min = pick(r.topRight()) - QMIN( maxB, pick(r.size())-minA ) - splitterWidth;
936 if ( max ) 941 if ( max )
937 *max = pick(r.topRight()) - QMAX( minB, pick(r.size())-maxA ) - splitterWidth; 942 *max = pick(r.topRight()) - QMAX( minB, pick(r.size())-maxA ) - splitterWidth;
938 } else { 943 } else {
939 if ( min ) 944 if ( min )
940 *min = pick(r.topLeft()) + QMAX( minB, pick(r.size())-maxA ); 945 *min = pick(r.topLeft()) + QMAX( minB, pick(r.size())-maxA );
941 if ( max ) 946 if ( max )
942 *max = pick(r.topLeft()) + QMIN( maxB, pick(r.size())-minA ); 947 *max = pick(r.topLeft()) + QMIN( maxB, pick(r.size())-minA );
943 } 948 }
944} 949}
945 950
946 951
947/*! 952/*!
948 Returns the closest legal position to \a p of the splitter with id \a id. 953 Returns the closest legal position to \a p of the splitter with id \a id.
949 954
950 \sa idAfter() 955 \sa idAfter()
951*/ 956*/
952 957
953int KDGanttMinimizeSplitter::adjustPos( int p, int id ) 958int KDGanttMinimizeSplitter::adjustPos( int p, int id )
954{ 959{
955 int min = 0; 960 int min = 0;
956 int max = 0; 961 int max = 0;
957 getRange( id, &min, &max ); 962 getRange( id, &min, &max );
958 p = QMAX( min, QMIN( p, max ) ); 963 p = QMAX( min, QMIN( p, max ) );
959 964
960 return p; 965 return p;
961} 966}
962 967
963 968
964void KDGanttMinimizeSplitter::doResize() 969void KDGanttMinimizeSplitter::doResize()
965{ 970{
966 QRect r = contentsRect(); 971 QRect r = contentsRect();
967 int i; 972 int i;
968 int n = data->list.count(); 973 int n = data->list.count();
969 QMemArray<QLayoutStruct> a( n ); 974 QMemArray<QLayoutStruct> a( n );
970 for ( i = 0; i< n; i++ ) { 975 for ( i = 0; i< n; i++ ) {
971 a[i].init(); 976 a[i].init();
972 QSplitterLayoutStruct *s = data->list.at(i); 977 QSplitterLayoutStruct *s = data->list.at(i);
973 if ( s->wid->isHidden() ) { 978 if ( s->wid->isHidden() ) {
974 a[i].stretch = 0; 979 a[i].stretch = 0;
975 a[i].sizeHint = a[i].minimumSize = 0; 980 a[i].sizeHint = a[i].minimumSize = 0;
976 a[i].maximumSize = 0; 981 a[i].maximumSize = 0;
977 } else if ( s->isSplitter ) { 982 } else if ( s->isSplitter ) {
978 a[i].stretch = 0; 983 a[i].stretch = 0;
979 a[i].sizeHint = a[i].minimumSize = a[i].maximumSize = s->sizer; 984 a[i].sizeHint = a[i].minimumSize = a[i].maximumSize = s->sizer;
980 a[i].empty = FALSE; 985 a[i].empty = FALSE;
981 } else if ( s->mode == KeepSize ) { 986 } else if ( s->mode == KeepSize ) {
982 a[i].stretch = 0; 987 a[i].stretch = 0;
983 a[i].minimumSize = pick( minSize(s->wid) ); 988 a[i].minimumSize = pick( minSize(s->wid) );
984 a[i].sizeHint = s->sizer; 989 a[i].sizeHint = s->sizer;
985 a[i].maximumSize = pick( s->wid->maximumSize() ); 990 a[i].maximumSize = pick( s->wid->maximumSize() );
986 a[i].empty = FALSE; 991 a[i].empty = FALSE;
987 } else if ( s->mode == FollowSizeHint ) { 992 } else if ( s->mode == FollowSizeHint ) {
988 a[i].stretch = 0; 993 a[i].stretch = 0;
989 a[i].minimumSize = a[i].sizeHint = pick( s->wid->sizeHint() ); 994 a[i].minimumSize = a[i].sizeHint = pick( s->wid->sizeHint() );
990 a[i].maximumSize = pick( s->wid->maximumSize() ); 995 a[i].maximumSize = pick( s->wid->maximumSize() );
991 a[i].empty = FALSE; 996 a[i].empty = FALSE;
992 } else { //proportional 997 } else { //proportional
993 a[i].stretch = s->sizer; 998 a[i].stretch = s->sizer;
994 a[i].maximumSize = pick( s->wid->maximumSize() ); 999 a[i].maximumSize = pick( s->wid->maximumSize() );
995 a[i].sizeHint = a[i].minimumSize = pick( minSize(s->wid) ); 1000 a[i].sizeHint = a[i].minimumSize = pick( minSize(s->wid) );
996 a[i].empty = FALSE; 1001 a[i].empty = FALSE;
997 } 1002 }
998 } 1003 }
999 1004
1000 kdganttGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 ); 1005 kdganttGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 );
1001 1006
1002 for ( i = 0; i< n; i++ ) { 1007 for ( i = 0; i< n; i++ ) {
1003 QSplitterLayoutStruct *s = data->list.at(i); 1008 QSplitterLayoutStruct *s = data->list.at(i);
1004 setG( s->wid, a[i].pos, a[i].size ); 1009 setG( s->wid, a[i].pos, a[i].size );
1005 } 1010 }
1006 1011
1007} 1012}
1008 1013
1009 1014
1010void KDGanttMinimizeSplitter::recalc( bool update ) 1015void KDGanttMinimizeSplitter::recalc( bool update )
1011{ 1016{
1012 int fi = 2*frameWidth(); 1017 int fi = 2*frameWidth();
1013 int maxl = fi; 1018 int maxl = fi;
1014 int minl = fi; 1019 int minl = fi;
1015 int maxt = QWIDGETSIZE_MAX; 1020 int maxt = QWIDGETSIZE_MAX;
1016 int mint = fi; 1021 int mint = fi;
1017 int n = data->list.count(); 1022 int n = data->list.count();
1018 bool first = TRUE; 1023 bool first = TRUE;
1019 /* 1024 /*
1020 The splitter before a hidden widget is always hidden. 1025 The splitter before a hidden widget is always hidden.
1021 The splitter before the first visible widget is hidden. 1026 The splitter before the first visible widget is hidden.
1022 The splitter before any other visible widget is visible. 1027 The splitter before any other visible widget is visible.
1023 */ 1028 */
1024 for ( int i = 0; i< n; i++ ) { 1029 for ( int i = 0; i< n; i++ ) {
1025 QSplitterLayoutStruct *s = data->list.at(i); 1030 QSplitterLayoutStruct *s = data->list.at(i);
1026 if ( !s->isSplitter ) { 1031 if ( !s->isSplitter ) {
1027 QSplitterLayoutStruct *p = (i > 0) ? p = data->list.at( i-1 ) : 0; 1032 QSplitterLayoutStruct *p = (i > 0) ? p = data->list.at( i-1 ) : 0;
1028 if ( p && p->isSplitter ) 1033 if ( p && p->isSplitter )
1029 if ( first || s->wid->isHidden() ) 1034 if ( first || s->wid->isHidden() )
1030 p->wid->hide(); //may trigger new recalc 1035 p->wid->hide(); //may trigger new recalc
1031 else 1036 else
1032 p->wid->show(); //may trigger new recalc 1037 p->wid->show(); //may trigger new recalc
1033 if ( !s->wid->isHidden() ) 1038 if ( !s->wid->isHidden() )
1034 first = FALSE; 1039 first = FALSE;
1035 } 1040 }
1036 } 1041 }
1037 1042
1038 bool empty=TRUE; 1043 bool empty=TRUE;
1039 for ( int j = 0; j< n; j++ ) { 1044 for ( int j = 0; j< n; j++ ) {
1040 QSplitterLayoutStruct *s = data->list.at(j); 1045 QSplitterLayoutStruct *s = data->list.at(j);
1041 if ( !s->wid->isHidden() ) { 1046 if ( !s->wid->isHidden() ) {
1042 empty = FALSE; 1047 empty = FALSE;
1043 if ( s->isSplitter ) { 1048 if ( s->isSplitter ) {
1044 minl += s->sizer; 1049 minl += s->sizer;
1045 maxl += s->sizer; 1050 maxl += s->sizer;
1046 } else { 1051 } else {
1047 QSize minS = minSize(s->wid); 1052 QSize minS = minSize(s->wid);
1048 minl += pick( minS ); 1053 minl += pick( minS );
1049 maxl += pick( s->wid->maximumSize() ); 1054 maxl += pick( s->wid->maximumSize() );
1050 mint = QMAX( mint, trans( minS )); 1055 mint = QMAX( mint, trans( minS ));
1051 int tm = trans( s->wid->maximumSize() ); 1056 int tm = trans( s->wid->maximumSize() );
1052 if ( tm > 0 ) 1057 if ( tm > 0 )
1053 maxt = QMIN( maxt, tm ); 1058 maxt = QMIN( maxt, tm );
1054 } 1059 }
1055 } 1060 }
1056 } 1061 }
1057 if ( empty ) { 1062 if ( empty ) {
1058 if ( parentWidget() != 0 && parentWidget()->inherits("KDGanttMinimizeSplitter") ) { 1063 if ( parentWidget() != 0 && parentWidget()->inherits("KDGanttMinimizeSplitter") ) {
1059 // nested splitters; be nice 1064 // nested splitters; be nice
1060 maxl = maxt = 0; 1065 maxl = maxt = 0;
1061 } else { 1066 } else {
1062 // KDGanttMinimizeSplitter with no children yet 1067 // KDGanttMinimizeSplitter with no children yet
1063 maxl = QWIDGETSIZE_MAX; 1068 maxl = QWIDGETSIZE_MAX;
1064 } 1069 }
1065 } else { 1070 } else {
1066 maxl = QMIN( maxl, QWIDGETSIZE_MAX ); 1071 maxl = QMIN( maxl, QWIDGETSIZE_MAX );
1067 } 1072 }
1068 if ( maxt < mint ) 1073 if ( maxt < mint )
1069 maxt = mint; 1074 maxt = mint;
1070 1075
1071 if ( orient == Horizontal ) { 1076 if ( orient == Horizontal ) {
1072 setMaximumSize( maxl, maxt ); 1077 setMaximumSize( maxl, maxt );
1073 setMinimumSize( minl, mint ); 1078 setMinimumSize( minl, mint );
1074 } else { 1079 } else {
1075 setMaximumSize( maxt, maxl ); 1080 setMaximumSize( maxt, maxl );
1076 setMinimumSize( mint, minl ); 1081 setMinimumSize( mint, minl );
1077 } 1082 }
1078 if ( update ) 1083 if ( update )
1079 doResize(); 1084 doResize();
1080} 1085}
1081 1086
1082/*! 1087/*!
1083 Sets resize mode of \a w to \a mode. 1088 Sets resize mode of \a w to \a mode.
1084 1089
1085 \sa ResizeMode 1090 \sa ResizeMode
1086*/ 1091*/
1087 1092
1088void KDGanttMinimizeSplitter::setResizeMode( QWidget *w, ResizeMode mode ) 1093void KDGanttMinimizeSplitter::setResizeMode( QWidget *w, ResizeMode mode )
1089{ 1094{
1090 processChildEvents(); 1095 processChildEvents();
1091 QSplitterLayoutStruct *s = data->list.first(); 1096 QSplitterLayoutStruct *s = data->list.first();
1092 while ( s ) { 1097 while ( s ) {
1093 if ( s->wid == w ) { 1098 if ( s->wid == w ) {
1094 s->mode = mode; 1099 s->mode = mode;
1095 return; 1100 return;
1096 } 1101 }
1097 s = data->list.next(); 1102 s = data->list.next();
1098 } 1103 }
1099 s = addWidget( w, TRUE ); 1104 s = addWidget( w, TRUE );
1100 s->mode = mode; 1105 s->mode = mode;
1101} 1106}
1102 1107
1103 1108
1104/*! 1109/*!
1105 Returns TRUE if opaque resize is on; otherwise returns FALSE. 1110 Returns TRUE if opaque resize is on; otherwise returns FALSE.
1106 1111
1107 \sa setOpaqueResize() 1112 \sa setOpaqueResize()
1108*/ 1113*/
1109 1114
1110bool KDGanttMinimizeSplitter::opaqueResize() const 1115bool KDGanttMinimizeSplitter::opaqueResize() const
1111{ 1116{
1112 return data->opaque; 1117 return data->opaque;
1113} 1118}
1114 1119
1115 1120
1116/*! 1121/*!
1117 If \a on is TRUE then opaque resizing is turned on; otherwise 1122 If \a on is TRUE then opaque resizing is turned on; otherwise
1118 opaque resizing is turned off. 1123 opaque resizing is turned off.
1119 Opaque resizing is initially turned off. 1124 Opaque resizing is initially turned off.
1120 1125
1121 \sa opaqueResize() 1126 \sa opaqueResize()
1122*/ 1127*/
1123 1128
1124void KDGanttMinimizeSplitter::setOpaqueResize( bool on ) 1129void KDGanttMinimizeSplitter::setOpaqueResize( bool on )
1125{ 1130{
1126 data->opaque = on; 1131 data->opaque = on;
1127} 1132}
1128 1133
1129 1134
1130/*! 1135/*!
1131 Moves widget \a w to the leftmost/top position. 1136 Moves widget \a w to the leftmost/top position.
1132*/ 1137*/
1133 1138
1134void KDGanttMinimizeSplitter::moveToFirst( QWidget *w ) 1139void KDGanttMinimizeSplitter::moveToFirst( QWidget *w )
1135{ 1140{
1136 processChildEvents(); 1141 processChildEvents();
1137 bool found = FALSE; 1142 bool found = FALSE;
1138 QSplitterLayoutStruct *s = data->list.first(); 1143 QSplitterLayoutStruct *s = data->list.first();
1139 while ( s ) { 1144 while ( s ) {
1140 if ( s->wid == w ) { 1145 if ( s->wid == w ) {
1141 found = TRUE; 1146 found = TRUE;
1142 QSplitterLayoutStruct *p = data->list.prev(); 1147 QSplitterLayoutStruct *p = data->list.prev();
1143 if ( p ) { // not already at first place 1148 if ( p ) { // not already at first place
1144 data->list.take(); //take p 1149 data->list.take(); //take p
1145 data->list.take(); // take s 1150 data->list.take(); // take s
1146 data->list.insert( 0, p ); 1151 data->list.insert( 0, p );
1147 data->list.insert( 0, s ); 1152 data->list.insert( 0, s );
1148 } 1153 }
1149 break; 1154 break;
1150 } 1155 }
1151 s = data->list.next(); 1156 s = data->list.next();
1152 } 1157 }
1153 if ( !found ) 1158 if ( !found )
1154 addWidget( w, TRUE ); 1159 addWidget( w, TRUE );
1155 recalcId(); 1160 recalcId();
1156} 1161}
1157 1162
1158 1163
1159/*! 1164/*!
1160 Moves widget \a w to the rightmost/bottom position. 1165 Moves widget \a w to the rightmost/bottom position.
1161*/ 1166*/
1162 1167
1163void KDGanttMinimizeSplitter::moveToLast( QWidget *w ) 1168void KDGanttMinimizeSplitter::moveToLast( QWidget *w )
1164{ 1169{
1165 processChildEvents(); 1170 processChildEvents();
1166 bool found = FALSE; 1171 bool found = FALSE;
1167 QSplitterLayoutStruct *s = data->list.first(); 1172 QSplitterLayoutStruct *s = data->list.first();
1168 while ( s ) { 1173 while ( s ) {
1169 if ( s->wid == w ) { 1174 if ( s->wid == w ) {
1170 found = TRUE; 1175 found = TRUE;
1171 data->list.take(); // take s 1176 data->list.take(); // take s
1172 QSplitterLayoutStruct *p = data->list.current(); 1177 QSplitterLayoutStruct *p = data->list.current();
1173 if ( p ) { // the splitter handle after s 1178 if ( p ) { // the splitter handle after s
1174 data->list.take(); //take p 1179 data->list.take(); //take p
1175 data->list.append( p ); 1180 data->list.append( p );
1176 } 1181 }
1177 data->list.append( s ); 1182 data->list.append( s );
1178 break; 1183 break;
1179 } 1184 }
1180 s = data->list.next(); 1185 s = data->list.next();
1181 } 1186 }
1182 if ( !found ) 1187 if ( !found )
1183 addWidget( w); 1188 addWidget( w);
1184 recalcId(); 1189 recalcId();
1185} 1190}
1186 1191
1187 1192
1188void KDGanttMinimizeSplitter::recalcId() 1193void KDGanttMinimizeSplitter::recalcId()
1189{ 1194{
1190 int n = data->list.count(); 1195 int n = data->list.count();
1191 for ( int i = 0; i < n; i++ ) { 1196 for ( int i = 0; i < n; i++ ) {
1192 QSplitterLayoutStruct *s = data->list.at(i); 1197 QSplitterLayoutStruct *s = data->list.at(i);
1193 if ( s->isSplitter ) 1198 if ( s->isSplitter )
1194 ((KDGanttSplitterHandle*)s->wid)->setId(i); 1199 ((KDGanttSplitterHandle*)s->wid)->setId(i);
1195 } 1200 }
1196} 1201}
1197 1202
1198 1203
1199/*!\reimp 1204/*!\reimp
1200*/ 1205*/
1201QSize KDGanttMinimizeSplitter::sizeHint() const 1206QSize KDGanttMinimizeSplitter::sizeHint() const
1202{ 1207{
1203 constPolish(); 1208 constPolish();
1204 int l = 0; 1209 int l = 0;
1205 int t = 0; 1210 int t = 0;
1206 if ( children() ) { 1211 if ( children() ) {
1207 const QObjectList * c = children(); 1212 const QObjectList * c = children();
1208 QObjectListIt it( *c ); 1213 QObjectListIt it( *c );
1209 QObject * o; 1214 QObject * o;
1210 1215
1211 while( (o=it.current()) != 0 ) { 1216 while( (o=it.current()) != 0 ) {
1212 ++it; 1217 ++it;
1213 if ( o->isWidgetType() && 1218 if ( o->isWidgetType() &&
1214 !((QWidget*)o)->isHidden() ) { 1219 !((QWidget*)o)->isHidden() ) {
1215 QSize s = ((QWidget*)o)->sizeHint(); 1220 QSize s = ((QWidget*)o)->sizeHint();
1216 if ( s.isValid() ) { 1221 if ( s.isValid() ) {
1217 l += pick( s ); 1222 l += pick( s );
1218 t = QMAX( t, trans( s ) ); 1223 t = QMAX( t, trans( s ) );
1219 } 1224 }
1220 } 1225 }
1221 } 1226 }
1222 } 1227 }
1223 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l ); 1228 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
1224} 1229}
1225 1230
1226 1231
1227/*! 1232/*!
1228\reimp 1233\reimp
1229*/ 1234*/
1230 1235
1231QSize KDGanttMinimizeSplitter::minimumSizeHint() const 1236QSize KDGanttMinimizeSplitter::minimumSizeHint() const
1232{ 1237{
1233 constPolish(); 1238 constPolish();
1234 int l = 0; 1239 int l = 0;
1235 int t = 0; 1240 int t = 0;
1236 if ( children() ) { 1241 if ( children() ) {
1237 const QObjectList * c = children(); 1242 const QObjectList * c = children();
1238 QObjectListIt it( *c ); 1243 QObjectListIt it( *c );
1239 QObject * o; 1244 QObject * o;
1240 1245
1241 while( (o=it.current()) != 0 ) { 1246 while( (o=it.current()) != 0 ) {
1242 ++it; 1247 ++it;
1243 if ( o->isWidgetType() && 1248 if ( o->isWidgetType() &&
1244 !((QWidget*)o)->isHidden() ) { 1249 !((QWidget*)o)->isHidden() ) {
1245 QSize s = minSizeHint((QWidget*)o); 1250 QSize s = minSizeHint((QWidget*)o);
1246 if ( s.isValid() ) { 1251 if ( s.isValid() ) {
1247 l += pick( s ); 1252 l += pick( s );
1248 t = QMAX( t, trans( s ) ); 1253 t = QMAX( t, trans( s ) );
1249 } 1254 }
1250 } 1255 }
1251 } 1256 }
1252 } 1257 }
1253 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l ); 1258 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
1254} 1259}
1255 1260
1256 1261
1257/* 1262/*
1258 Calculates stretch parameters from current sizes 1263 Calculates stretch parameters from current sizes
1259*/ 1264*/
1260 1265
1261void KDGanttMinimizeSplitter::storeSizes() 1266void KDGanttMinimizeSplitter::storeSizes()
1262{ 1267{
1263 QSplitterLayoutStruct *s = data->list.first(); 1268 QSplitterLayoutStruct *s = data->list.first();
1264 while ( s ) { 1269 while ( s ) {
1265 if ( !s->isSplitter ) 1270 if ( !s->isSplitter )
1266 s->sizer = pick( s->wid->size() ); 1271 s->sizer = pick( s->wid->size() );
1267 s = data->list.next(); 1272 s = data->list.next();
1268 } 1273 }
1269} 1274}
1270 1275
1271 1276
1272#if 0 // ### remove this code ASAP 1277#if 0 // ### remove this code ASAP
1273 1278
1274/*! 1279/*!
1275 Hides \a w if \a hide is TRUE and updates the splitter. 1280 Hides \a w if \a hide is TRUE and updates the splitter.
1276 1281
1277 \warning Due to a limitation in the current implementation, 1282 \warning Due to a limitation in the current implementation,
1278 calling QWidget::hide() will not work. 1283 calling QWidget::hide() will not work.
1279*/ 1284*/
1280 1285
1281void KDGanttMinimizeSplitter::setHidden( QWidget *w, bool hide ) 1286void KDGanttMinimizeSplitter::setHidden( QWidget *w, bool hide )
1282{ 1287{
1283 if ( w == w1 ) { 1288 if ( w == w1 ) {
1284 w1show = !hide; 1289 w1show = !hide;
1285 } else if ( w == w2 ) { 1290 } else if ( w == w2 ) {
1286 w2show = !hide; 1291 w2show = !hide;
1287 } else { 1292 } else {
1288#ifdef QT_CHECK_RANGE 1293#ifdef QT_CHECK_RANGE
1289 qWarning( "KDGanttMinimizeSplitter::setHidden(), unknown widget" ); 1294 qWarning( "KDGanttMinimizeSplitter::setHidden(), unknown widget" );
1290#endif 1295#endif
1291 return; 1296 return;
1292 } 1297 }
1293 if ( hide ) 1298 if ( hide )
1294 w->hide(); 1299 w->hide();
1295 else 1300 else
1296 w->show(); 1301 w->show();
1297 recalc( TRUE ); 1302 recalc( TRUE );
1298} 1303}
1299 1304
1300 1305
1301/*! 1306/*!
1302 Returns the hidden status of \a w 1307 Returns the hidden status of \a w
1303*/ 1308*/
1304 1309
1305bool KDGanttMinimizeSplitter::isHidden( QWidget *w ) const 1310bool KDGanttMinimizeSplitter::isHidden( QWidget *w ) const
1306{ 1311{
1307 if ( w == w1 ) 1312 if ( w == w1 )
1308 return !w1show; 1313 return !w1show;
1309 else if ( w == w2 ) 1314 else if ( w == w2 )
1310 return !w2show; 1315 return !w2show;
1311#ifdef QT_CHECK_RANGE 1316#ifdef QT_CHECK_RANGE
1312 else 1317 else
1313 qWarning( "KDGanttMinimizeSplitter::isHidden(), unknown widget" ); 1318 qWarning( "KDGanttMinimizeSplitter::isHidden(), unknown widget" );
1314#endif 1319#endif
1315 return FALSE; 1320 return FALSE;
1316} 1321}
1317#endif 1322#endif
1318 1323
1319 1324
1320/*! 1325/*!
1321 Returns a list of the size parameters of all the widgets in this 1326 Returns a list of the size parameters of all the widgets in this
1322 splitter. 1327 splitter.
1323 1328
1324 Giving the values to another splitter's setSizes() function will 1329 Giving the values to another splitter's setSizes() function will
1325 produce a splitter with the same layout as this one. 1330 produce a splitter with the same layout as this one.
1326 1331
1327 Note that if you want to iterate over the list, you should 1332 Note that if you want to iterate over the list, you should
1328 iterate over a copy, e.g. 1333 iterate over a copy, e.g.
1329 \code 1334 \code
1330 QValueList<int> list = mySplitter.sizes(); 1335 QValueList<int> list = mySplitter.sizes();
1331 QValueList<int>::Iterator it = list.begin(); 1336 QValueList<int>::Iterator it = list.begin();
1332 while( it != list.end() ) { 1337 while( it != list.end() ) {
1333 myProcessing( *it ); 1338 myProcessing( *it );
1334 ++it; 1339 ++it;
1335 } 1340 }
1336 \endcode 1341 \endcode
1337 1342
1338 \sa setSizes() 1343 \sa setSizes()
1339*/ 1344*/
1340 1345
1341QValueList<int> KDGanttMinimizeSplitter::sizes() const 1346QValueList<int> KDGanttMinimizeSplitter::sizes() const
1342{ 1347{
1343 if ( !testWState(WState_Polished) ) { 1348 if ( !testWState(WState_Polished) ) {
1344 QWidget* that = (QWidget*) this; 1349 QWidget* that = (QWidget*) this;
1345 that->polish(); 1350 that->polish();
1346 } 1351 }
1347 QValueList<int> list; 1352 QValueList<int> list;
1348 QSplitterLayoutStruct *s = data->list.first(); 1353 QSplitterLayoutStruct *s = data->list.first();
1349 while ( s ) { 1354 while ( s ) {
1350 if ( !s->isSplitter ) 1355 if ( !s->isSplitter )
1351 list.append( s->sizer ); 1356 list.append( s->sizer );
1352 s = data->list.next(); 1357 s = data->list.next();
1353 } 1358 }
1354 return list; 1359 return list;
1355} 1360}
1356 1361
1357 1362
1358 1363
1359/*! 1364/*!
1360 Sets the size parameters to the values given in \a list. 1365 Sets the size parameters to the values given in \a list.
1361 If the splitter is horizontal, the values set the sizes from 1366 If the splitter is horizontal, the values set the sizes from
1362 left to right. If it is vertical, the sizes are applied from 1367 left to right. If it is vertical, the sizes are applied from
1363 top to bottom. 1368 top to bottom.
1364 Extra values in \a list are ignored. 1369 Extra values in \a list are ignored.
1365 1370
1366 If \a list contains too few values, the result is undefined 1371 If \a list contains too few values, the result is undefined
1367 but the program will still be well-behaved. 1372 but the program will still be well-behaved.
1368 1373
1369 \sa sizes() 1374 \sa sizes()
1370*/ 1375*/
1371 1376
1372void KDGanttMinimizeSplitter::setSizes( QValueList<int> list ) 1377void KDGanttMinimizeSplitter::setSizes( QValueList<int> list )
1373{ 1378{
1374 processChildEvents(); 1379 processChildEvents();
1375 QValueList<int>::Iterator it = list.begin(); 1380 QValueList<int>::Iterator it = list.begin();
1376 QSplitterLayoutStruct *s = data->list.first(); 1381 QSplitterLayoutStruct *s = data->list.first();
1377 while ( s && it != list.end() ) { 1382 while ( s && it != list.end() ) {
1378 if ( !s->isSplitter ) { 1383 if ( !s->isSplitter ) {
1379 s->sizer = *it; 1384 s->sizer = *it;
1380 ++it; 1385 ++it;
1381 } 1386 }
1382 s = data->list.next(); 1387 s = data->list.next();
1383 } 1388 }
1384 doResize(); 1389 doResize();
1385} 1390}
1386 1391
1387 1392
1388/*! 1393/*!
1389 Gets all posted child events, ensuring that the internal state of 1394 Gets all posted child events, ensuring that the internal state of
1390 the splitter is consistent. 1395 the splitter is consistent.
1391*/ 1396*/
1392 1397
1393void KDGanttMinimizeSplitter::processChildEvents() 1398void KDGanttMinimizeSplitter::processChildEvents()
1394{ 1399{
1395 QApplication::sendPostedEvents( this, QEvent::ChildInserted ); 1400 QApplication::sendPostedEvents( this, QEvent::ChildInserted );
1396} 1401}
1397 1402
1398 1403
1399/*! 1404/*!
1400 \reimp 1405 \reimp
1401*/ 1406*/
1402 1407
1403void KDGanttMinimizeSplitter::styleChange( QStyle& old ) 1408void KDGanttMinimizeSplitter::styleChange( QStyle& old )
1404{ 1409{
1405 1410
1406#if QT_VERSION >= 0x030000 1411#if QT_VERSION >= 0x030000
1407 int sw = style().pixelMetric(QStyle::PM_SplitterWidth, this); 1412 int sw = style().pixelMetric(QStyle::PM_SplitterWidth, this);
1408#else 1413#else
1409 int sw = style().splitterWidth(); 1414 int sw = style().splitterWidth();
1410#endif 1415#endif
1411 QSplitterLayoutStruct *s = data->list.first(); 1416 QSplitterLayoutStruct *s = data->list.first();
1412 while ( s ) { 1417 while ( s ) {
1413 if ( s->isSplitter ) 1418 if ( s->isSplitter )
1414 s->sizer = sw; 1419 s->sizer = sw;
1415 s = data->list.next(); 1420 s = data->list.next();
1416 } 1421 }
1417 doResize(); 1422 doResize();
1418 QFrame::styleChange( old ); 1423 QFrame::styleChange( old );
1419} 1424}
1420 1425
1421#endif 1426#endif
1422 1427
1423/*! 1428/*!
1424 Specifies the direction of the minimize buttons. 1429 Specifies the direction of the minimize buttons.
1425 If the orientation of the splitter is horizontal then with 1430 If the orientation of the splitter is horizontal then with
1426 KDGanttMinimizeSplitter::Left or KDGanttMinimizeSplitter::Right should be used, 1431 KDGanttMinimizeSplitter::Left or KDGanttMinimizeSplitter::Right should be used,
1427 otherwise either KDGanttMinimizeSplitter::Up or KDGanttMinimizeSplitter::Down 1432 otherwise either KDGanttMinimizeSplitter::Up or KDGanttMinimizeSplitter::Down
1428 should be used. 1433 should be used.
1429*/ 1434*/
1430void KDGanttMinimizeSplitter::setMinimizeDirection( Direction direction ) 1435void KDGanttMinimizeSplitter::setMinimizeDirection( Direction direction )
1431{ 1436{
1432 _direction = direction; 1437 _direction = direction;
1433} 1438}
1434 1439
1435/*! 1440/*!
1436 Returns the direction of the minimize buttons. 1441 Returns the direction of the minimize buttons.
1437*/ 1442*/
1438KDGanttMinimizeSplitter::Direction KDGanttMinimizeSplitter::minimizeDirection() const 1443KDGanttMinimizeSplitter::Direction KDGanttMinimizeSplitter::minimizeDirection() const
1439{ 1444{
1440 return _direction; 1445 return _direction;
1441} 1446}
1442 1447
1443/* 1448/*
1444 This is a copy of qGeomCalc() in qlayoutengine.cpp which 1449 This is a copy of qGeomCalc() in qlayoutengine.cpp which
1445 unfortunately isn't exported. 1450 unfortunately isn't exported.
1446*/ 1451*/
1447static inline int toFixed( int i ) { return i * 256; } 1452static inline int toFixed( int i ) { return i * 256; }
1448static inline int fRound( int i ) { 1453static inline int fRound( int i ) {
1449 return ( i % 256 < 128 ) ? i / 256 : 1 + i / 256; 1454 return ( i % 256 < 128 ) ? i / 256 : 1 + i / 256;
1450} 1455}
1451void kdganttGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos, 1456void kdganttGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos,
1452 int space, int spacer ) 1457 int space, int spacer )
1453{ 1458{
1454 typedef int fixed; 1459 typedef int fixed;
1455 int cHint = 0; 1460 int cHint = 0;
1456 int cMin = 0; 1461 int cMin = 0;
1457 int cMax = 0; 1462 int cMax = 0;
1458 int sumStretch = 0; 1463 int sumStretch = 0;
1459 int spacerCount = 0; 1464 int spacerCount = 0;
1460 1465
1461 bool wannaGrow = FALSE; // anyone who really wants to grow? 1466 bool wannaGrow = FALSE; // anyone who really wants to grow?
1462 // bool canShrink = FALSE; // anyone who could be persuaded to shrink? 1467 // bool canShrink = FALSE; // anyone who could be persuaded to shrink?
1463 1468
1464 int i; 1469 int i;
1465 for ( i = start; i < start + count; i++ ) { 1470 for ( i = start; i < start + count; i++ ) {
1466 chain[i].done = FALSE; 1471 chain[i].done = FALSE;
1467 cHint += chain[i].sizeHint; 1472 cHint += chain[i].sizeHint;
1468 cMin += chain[i].minimumSize; 1473 cMin += chain[i].minimumSize;
1469 cMax += chain[i].maximumSize; 1474 cMax += chain[i].maximumSize;
1470 sumStretch += chain[i].stretch; 1475 sumStretch += chain[i].stretch;
1471 if ( !chain[i].empty ) 1476 if ( !chain[i].empty )
1472 spacerCount++; 1477 spacerCount++;
1473 wannaGrow = wannaGrow || chain[i].expansive; 1478 wannaGrow = wannaGrow || chain[i].expansive;
1474 } 1479 }
1475 1480
1476 int extraspace = 0; 1481 int extraspace = 0;
1477 if ( spacerCount ) 1482 if ( spacerCount )
1478 spacerCount--; // only spacers between things 1483 spacerCount--; // only spacers between things
1479 if ( space < cMin + spacerCount * spacer ) { 1484 if ( space < cMin + spacerCount * spacer ) {
1480 //qDebug("not enough space"); 1485 //qDebug("not enough space");
1481 for ( i = start; i < start+count; i++ ) { 1486 for ( i = start; i < start+count; i++ ) {
1482 chain[i].size = chain[i].minimumSize; 1487 chain[i].size = chain[i].minimumSize;
1483 chain[i].done = TRUE; 1488 chain[i].done = TRUE;
1484 } 1489 }
1485 } else if ( space < cHint + spacerCount*spacer ) { 1490 } else if ( space < cHint + spacerCount*spacer ) {
1486 // Less space than sizeHint, but more than minimum. 1491 // Less space than sizeHint, but more than minimum.
1487 // Currently take space equally from each, like in Qt 2.x. 1492 // Currently take space equally from each, like in Qt 2.x.
1488 // Commented-out lines will give more space to stretchier items. 1493 // Commented-out lines will give more space to stretchier items.
1489 int n = count; 1494 int n = count;
1490 int space_left = space - spacerCount*spacer; 1495 int space_left = space - spacerCount*spacer;
1491 int overdraft = cHint - space_left; 1496 int overdraft = cHint - space_left;
1492 //first give to the fixed ones: 1497 //first give to the fixed ones:
1493 for ( i = start; i < start+count; i++ ) { 1498 for ( i = start; i < start+count; i++ ) {
1494 if ( !chain[i].done && chain[i].minimumSize >= chain[i].sizeHint) { 1499 if ( !chain[i].done && chain[i].minimumSize >= chain[i].sizeHint) {
1495 chain[i].size = chain[i].sizeHint; 1500 chain[i].size = chain[i].sizeHint;
1496 chain[i].done = TRUE; 1501 chain[i].done = TRUE;
1497 space_left -= chain[i].sizeHint; 1502 space_left -= chain[i].sizeHint;
1498 // sumStretch -= chain[i].stretch; 1503 // sumStretch -= chain[i].stretch;
1499 n--; 1504 n--;
1500 } 1505 }
1501 } 1506 }
1502 bool finished = n == 0; 1507 bool finished = n == 0;
1503 while ( !finished ) { 1508 while ( !finished ) {
1504 finished = TRUE; 1509 finished = TRUE;
1505 fixed fp_over = toFixed( overdraft ); 1510 fixed fp_over = toFixed( overdraft );
1506 fixed fp_w = 0; 1511 fixed fp_w = 0;
1507 1512
1508 for ( i = start; i < start+count; i++ ) { 1513 for ( i = start; i < start+count; i++ ) {
1509 if ( chain[i].done ) 1514 if ( chain[i].done )
1510 continue; 1515 continue;
1511 // if ( sumStretch <= 0 ) 1516 // if ( sumStretch <= 0 )
1512 fp_w += fp_over / n; 1517 fp_w += fp_over / n;
1513 // else 1518 // else
1514 // fp_w += (fp_over * chain[i].stretch) / sumStretch; 1519 // fp_w += (fp_over * chain[i].stretch) / sumStretch;
1515 int w = fRound( fp_w ); 1520 int w = fRound( fp_w );
1516 chain[i].size = chain[i].sizeHint - w; 1521 chain[i].size = chain[i].sizeHint - w;
1517 fp_w -= toFixed( w ); //give the difference to the next 1522 fp_w -= toFixed( w ); //give the difference to the next
1518 if ( chain[i].size < chain[i].minimumSize ) { 1523 if ( chain[i].size < chain[i].minimumSize ) {
1519 chain[i].done = TRUE; 1524 chain[i].done = TRUE;
1520 chain[i].size = chain[i].minimumSize; 1525 chain[i].size = chain[i].minimumSize;
1521 finished = FALSE; 1526 finished = FALSE;
1522 overdraft -= chain[i].sizeHint - chain[i].minimumSize; 1527 overdraft -= chain[i].sizeHint - chain[i].minimumSize;
1523 // sumStretch -= chain[i].stretch; 1528 // sumStretch -= chain[i].stretch;
1524 n--; 1529 n--;
1525 break; 1530 break;
1526 } 1531 }
1527 } 1532 }
1528 } 1533 }
1529 } else { //extra space 1534 } else { //extra space
1530 int n = count; 1535 int n = count;
1531 int space_left = space - spacerCount*spacer; 1536 int space_left = space - spacerCount*spacer;
1532 // first give to the fixed ones, and handle non-expansiveness 1537 // first give to the fixed ones, and handle non-expansiveness
1533 for ( i = start; i < start + count; i++ ) { 1538 for ( i = start; i < start + count; i++ ) {
1534 if ( !chain[i].done && (chain[i].maximumSize <= chain[i].sizeHint 1539 if ( !chain[i].done && (chain[i].maximumSize <= chain[i].sizeHint
1535 || wannaGrow && !chain[i].expansive) ) { 1540 || wannaGrow && !chain[i].expansive) ) {
1536 chain[i].size = chain[i].sizeHint; 1541 chain[i].size = chain[i].sizeHint;
1537 chain[i].done = TRUE; 1542 chain[i].done = TRUE;
1538 space_left -= chain[i].sizeHint; 1543 space_left -= chain[i].sizeHint;
1539 sumStretch -= chain[i].stretch; 1544 sumStretch -= chain[i].stretch;
1540 n--; 1545 n--;
1541 } 1546 }
1542 } 1547 }
1543 extraspace = space_left; 1548 extraspace = space_left;
1544 /* 1549 /*
1545 Do a trial distribution and calculate how much it is off. 1550 Do a trial distribution and calculate how much it is off.
1546 If there are more deficit pixels than surplus pixels, give 1551 If there are more deficit pixels than surplus pixels, give
1547 the minimum size items what they need, and repeat. 1552 the minimum size items what they need, and repeat.
1548 Otherwise give to the maximum size items, and repeat. 1553 Otherwise give to the maximum size items, and repeat.
1549 1554
1550 I have a wonderful mathematical proof for the correctness 1555 I have a wonderful mathematical proof for the correctness
1551 of this principle, but unfortunately this comment is too 1556 of this principle, but unfortunately this comment is too
1552 small to contain it. 1557 small to contain it.
1553 */ 1558 */
1554 int surplus, deficit; 1559 int surplus, deficit;
1555 do { 1560 do {
1556 surplus = deficit = 0; 1561 surplus = deficit = 0;
1557 fixed fp_space = toFixed( space_left ); 1562 fixed fp_space = toFixed( space_left );
1558 fixed fp_w = 0; 1563 fixed fp_w = 0;
1559 for ( i = start; i < start+count; i++ ) { 1564 for ( i = start; i < start+count; i++ ) {
1560 if ( chain[i].done ) 1565 if ( chain[i].done )
1561 continue; 1566 continue;
1562 extraspace = 0; 1567 extraspace = 0;
1563 if ( sumStretch <= 0 ) 1568 if ( sumStretch <= 0 )
1564 fp_w += fp_space / n; 1569 fp_w += fp_space / n;
1565 else 1570 else
1566 fp_w += (fp_space * chain[i].stretch) / sumStretch; 1571 fp_w += (fp_space * chain[i].stretch) / sumStretch;
1567 int w = fRound( fp_w ); 1572 int w = fRound( fp_w );
1568 chain[i].size = w; 1573 chain[i].size = w;
1569 fp_w -= toFixed( w ); // give the difference to the next 1574 fp_w -= toFixed( w ); // give the difference to the next
1570 if ( w < chain[i].sizeHint ) { 1575 if ( w < chain[i].sizeHint ) {
1571 deficit += chain[i].sizeHint - w; 1576 deficit += chain[i].sizeHint - w;
1572 } else if ( w > chain[i].maximumSize ) { 1577 } else if ( w > chain[i].maximumSize ) {
1573 surplus += w - chain[i].maximumSize; 1578 surplus += w - chain[i].maximumSize;
1574 } 1579 }
1575 } 1580 }
1576 if ( deficit > 0 && surplus <= deficit ) { 1581 if ( deficit > 0 && surplus <= deficit ) {
1577 // give to the ones that have too little 1582 // give to the ones that have too little
1578 for ( i = start; i < start+count; i++ ) { 1583 for ( i = start; i < start+count; i++ ) {
1579 if ( !chain[i].done && 1584 if ( !chain[i].done &&
1580 chain[i].size < chain[i].sizeHint ) { 1585 chain[i].size < chain[i].sizeHint ) {
1581 chain[i].size = chain[i].sizeHint; 1586 chain[i].size = chain[i].sizeHint;
1582 chain[i].done = TRUE; 1587 chain[i].done = TRUE;
1583 space_left -= chain[i].sizeHint; 1588 space_left -= chain[i].sizeHint;
1584 sumStretch -= chain[i].stretch; 1589 sumStretch -= chain[i].stretch;
1585 n--; 1590 n--;
1586 } 1591 }
1587 } 1592 }
1588 } 1593 }
1589 if ( surplus > 0 && surplus >= deficit ) { 1594 if ( surplus > 0 && surplus >= deficit ) {
1590 // take from the ones that have too much 1595 // take from the ones that have too much
1591 for ( i = start; i < start+count; i++ ) { 1596 for ( i = start; i < start+count; i++ ) {
1592 if ( !chain[i].done && 1597 if ( !chain[i].done &&
1593 chain[i].size > chain[i].maximumSize ) { 1598 chain[i].size > chain[i].maximumSize ) {
1594 chain[i].size = chain[i].maximumSize; 1599 chain[i].size = chain[i].maximumSize;
1595 chain[i].done = TRUE; 1600 chain[i].done = TRUE;
1596 space_left -= chain[i].maximumSize; 1601 space_left -= chain[i].maximumSize;
1597 sumStretch -= chain[i].stretch; 1602 sumStretch -= chain[i].stretch;
1598 n--; 1603 n--;
1599 } 1604 }
1600 } 1605 }
1601 } 1606 }
1602 } while ( n > 0 && surplus != deficit ); 1607 } while ( n > 0 && surplus != deficit );
1603 if ( n == 0 ) 1608 if ( n == 0 )
1604 extraspace = space_left; 1609 extraspace = space_left;
1605 } 1610 }
1606 1611
1607 // as a last resort, we distribute the unwanted space equally 1612 // as a last resort, we distribute the unwanted space equally
1608 // among the spacers (counting the start and end of the chain). 1613 // among the spacers (counting the start and end of the chain).
1609 1614
1610 //### should do a sub-pixel allocation of extra space 1615 //### should do a sub-pixel allocation of extra space
1611 int extra = extraspace / ( spacerCount + 2 ); 1616 int extra = extraspace / ( spacerCount + 2 );
1612 int p = pos + extra; 1617 int p = pos + extra;
1613 for ( i = start; i < start+count; i++ ) { 1618 for ( i = start; i < start+count; i++ ) {
1614 chain[i].pos = p; 1619 chain[i].pos = p;
1615 p = p + chain[i].size; 1620 p = p + chain[i].size;
1616 if ( !chain[i].empty ) 1621 if ( !chain[i].empty )
1617 p += spacer+extra; 1622 p += spacer+extra;
1618 } 1623 }
1619} 1624}
1620 1625
1621#endif 1626#endif
1622 1627
1623/*! 1628/*!
1624 \enum KDGanttMinimizeSplitter::Direction 1629 \enum KDGanttMinimizeSplitter::Direction
1625 1630
1626 The values of this enumeration describe into which direction the 1631 The values of this enumeration describe into which direction the
1627 splitter will collapse its child widgets. By extension, it also 1632 splitter will collapse its child widgets. By extension, it also
1628 specifies the orientation of the splitter; collapsing to the left or 1633 specifies the orientation of the splitter; collapsing to the left or
1629 to the right results in a horizontal splitter, collapsing to the top 1634 to the right results in a horizontal splitter, collapsing to the top
1630 or bottom in a vertical splitter. 1635 or bottom in a vertical splitter.
1631*/ 1636*/
1632 1637
1633/*! 1638/*!
1634 \fn Orientation KDGanttMinimizeSplitter::orientation() const 1639 \fn Orientation KDGanttMinimizeSplitter::orientation() const
1635 1640
1636 Returns the orientation of the splitter. 1641 Returns the orientation of the splitter.
1637*/ 1642*/
1638 1643
1639/*! \enum KDGanttMinimizeSplitter::ResizeMode 1644/*! \enum KDGanttMinimizeSplitter::ResizeMode
1640 1645
1641 This enum type describes how KDGanttMinimizeSplitter will resize each of its child widgets. The currently defined values are: 1646 This enum type describes how KDGanttMinimizeSplitter will resize each of its child widgets. The currently defined values are:
1642 1647
1643 Stretch: the widget will be resized when the splitter 1648 Stretch: the widget will be resized when the splitter
1644 itself is resized. 1649 itself is resized.
1645 1650
1646 KeepSize: KDGanttMinimizeSplitter will try to keep this widget's size 1651 KeepSize: KDGanttMinimizeSplitter will try to keep this widget's size
1647 unchanged. 1652 unchanged.
1648 1653
1649 FollowSizeHint: KDGanttMinimizeSplitter will resize the widget when the 1654 FollowSizeHint: KDGanttMinimizeSplitter will resize the widget when the
1650 widget's size hint changes. 1655 widget's size hint changes.
1651*/ 1656*/
1652 1657