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