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