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