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