00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "KDGanttMinimizeSplitter.h"
00035 #ifndef TQT_NO_SPLITTER
00036
00037 #include "tqpainter.h"
00038 #include "tqdrawutil.h"
00039 #include "tqbitmap.h"
00040 #include "tqptrlist.h"
00041 #include "tqmemarray.h"
00042 #include "tqlayout.h"
00043 #include "tqlayoutengine_p.h"
00044 #include "tqobjectlist.h"
00045 #include "tqstyle.h"
00046 #include "tqapplication.h"
00047 #include <tqvaluelist.h>
00048 #include <tqcursor.h>
00049
00050 #include "KDGanttMinimizeSplitter.moc"
00051
00052 #ifndef DOXYGEN_SKIP_INTERNAL
00053
00054 static int mouseOffset;
00055 static int opaqueOldPos = -1;
00056
00057
00058 KDGanttSplitterHandle::KDGanttSplitterHandle( Qt::Orientation o,
00059 KDGanttMinimizeSplitter *parent, const char * name )
00060 : TQWidget( parent, name ), _activeButton( 0 ), _collapsed( false )
00061 {
00062 s = parent;
00063 setOrientation(o);
00064 setMouseTracking( true );
00065 }
00066
00067 TQSize KDGanttSplitterHandle::sizeHint() const
00068 {
00069 return TQSize(8,8);
00070 }
00071
00072 void KDGanttSplitterHandle::setOrientation( Qt::Orientation o )
00073 {
00074 orient = o;
00075 #ifndef TQT_NO_CURSOR
00076 if ( o == Qt::Horizontal )
00077 setCursor( splitHCursor );
00078 else
00079 setCursor( splitVCursor );
00080 #endif
00081 }
00082
00083
00084 void KDGanttSplitterHandle::mouseMoveEvent( TQMouseEvent *e )
00085 {
00086 updateCursor( e->pos() );
00087 if ( !(e->state()&Qt::LeftButton) )
00088 return;
00089
00090 if ( _activeButton != 0)
00091 return;
00092
00093 TQCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
00094 - mouseOffset;
00095 if ( opaque() ) {
00096 s->moveSplitter( pos, id() );
00097 } else {
00098 int min = pos; int max = pos;
00099 s->getRange( id(), &min, &max );
00100 s->setRubberband( TQMAX( min, TQMIN(max, pos )));
00101 }
00102 _collapsed = false;
00103 }
00104
00105 void KDGanttSplitterHandle::mousePressEvent( TQMouseEvent *e )
00106 {
00107 if ( e->button() == Qt::LeftButton ) {
00108 _activeButton = onButton( e->pos() );
00109 mouseOffset = s->pick(e->pos());
00110 if ( _activeButton != 0)
00111 repaint();
00112 updateCursor( e->pos() );
00113 }
00114 }
00115
00116 void KDGanttSplitterHandle::updateCursor( const TQPoint& p)
00117 {
00118 if ( onButton( p ) != 0 ) {
00119 setCursor( arrowCursor );
00120 }
00121 else {
00122 if ( orient == Qt::Horizontal )
00123 setCursor( splitHCursor );
00124 else
00125 setCursor( splitVCursor );
00126 }
00127 }
00128
00129
00130 void KDGanttSplitterHandle::mouseReleaseEvent( TQMouseEvent *e )
00131 {
00132 if ( _activeButton != 0 ) {
00133 if ( onButton( e->pos() ) == _activeButton )
00134 {
00135 int pos;
00136 int min, max;
00137 if ( !_collapsed ) {
00138 s->expandPos( id(), &min, &max );
00139 if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left
00140 || s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) {
00141 pos = min;
00142 }
00143 else {
00144 pos = max;
00145 }
00146
00147 _origPos = s->pick(mapToParent( TQPoint( 0,0 ) ));
00148 s->moveSplitter( pos, id() );
00149 _collapsed = true;
00150 }
00151 else {
00152 s->moveSplitter( _origPos, id() );
00153 _collapsed = false;
00154 }
00155
00156 }
00157 _activeButton = 0;
00158 updateCursor( e->pos() );
00159 }
00160 else {
00161 if ( !opaque() && e->button() == Qt::LeftButton ) {
00162 TQCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
00163 - mouseOffset;
00164 s->setRubberband( -1 );
00165 s->moveSplitter( pos, id() );
00166 }
00167 }
00168 repaint();
00169 }
00170
00171 int KDGanttSplitterHandle::onButton( const TQPoint& p )
00172 {
00173 TQValueList<TQPointArray> list = buttonRegions();
00174 int index = 1;
00175 for( TQValueList<TQPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) {
00176 TQRect rect = (*it).boundingRect();
00177 rect.setLeft( rect.left()- 4 );
00178 rect.setRight( rect.right() + 4);
00179 rect.setTop( rect.top()- 4 );
00180 rect.setBottom( rect.bottom() + 4);
00181 if ( rect.contains( p ) ) {
00182 return index;
00183 }
00184 index++;
00185 }
00186 return 0;
00187 }
00188
00189
00190 TQValueList<TQPointArray> KDGanttSplitterHandle::buttonRegions()
00191 {
00192 TQValueList<TQPointArray> list;
00193
00194 int sw = 8;
00195 int voffset[] = { (int) -sw*3, (int) sw*3 };
00196 for ( int i = 0; i < 2; i++ ) {
00197 TQPointArray arr;
00198 if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ||
00199 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left) {
00200 int mid = height()/2 + voffset[i];
00201 arr.setPoints( 3,
00202 1, mid - sw + 4,
00203 sw-3, mid,
00204 1, mid + sw -4);
00205 }
00206 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left ||
00207 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) {
00208 int mid = height()/2 + voffset[i];
00209 arr.setPoints( 3,
00210 sw-4, mid - sw + 4,
00211 0, mid,
00212 sw-4, mid + sw - 4);
00213 }
00214 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ||
00215 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down) {
00216 int mid = width()/2 + voffset[i];
00217 arr.setPoints( 3,
00218 mid - sw + 4, sw-4,
00219 mid, 0,
00220 mid + sw - 4, sw-4 );
00221 }
00222 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down ||
00223 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) {
00224 int mid = width()/2 + voffset[i];
00225 arr.setPoints( 3,
00226 mid - sw + 4, 1,
00227 mid, sw-3,
00228 mid + sw -4, 1);
00229 }
00230 list.append( arr );
00231 }
00232 return list;
00233 }
00234
00235 void KDGanttSplitterHandle::paintEvent( TQPaintEvent * )
00236 {
00237 TQPixmap buffer( size() );
00238 TQPainter p( &buffer );
00239
00240
00241 p.setBrush( colorGroup().background() );
00242 p.setPen( colorGroup().foreground() );
00243 p.drawRect( rect() );
00244 parentWidget()->style().tqdrawPrimitive( TQStyle::PE_Panel, &p, rect(),
00245 parentWidget()->colorGroup());
00246
00247 int sw = 8;
00248
00249
00250 TQColor col = colorGroup().background().dark( 200 );
00251 p.setBrush( col );
00252 p.setPen( col );
00253
00254 TQValueList<TQPointArray> list = buttonRegions();
00255 int index = 1;
00256 for ( TQValueList<TQPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) {
00257 if ( index == _activeButton ) {
00258 p.save();
00259 p.translate( parentWidget()->style().pixelMetric( TQStyle::PM_ButtonShiftHorizontal ),
00260 parentWidget()->style().pixelMetric( TQStyle::PM_ButtonShiftVertical ) );
00261 p.drawPolygon( *it, true );
00262 p.restore();
00263 }
00264 else {
00265 p.drawPolygon( *it, true );
00266 }
00267 index++;
00268 }
00269
00270
00271 if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left ||
00272 s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) {
00273 int mid = height()/2;
00274 p.drawLine ( 2, mid - sw, 2, mid + sw );
00275 p.drawLine ( 4, mid - sw, 4, mid + sw );
00276 }
00277 else if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Up ||
00278 s->minimizeDirection() == KDGanttMinimizeSplitter::Down ) {
00279 int mid = width()/2;
00280 p.drawLine( mid -sw, 2, mid +sw, 2 );
00281 p.drawLine( mid -sw, 4, mid +sw, 4 );
00282 }
00283 bitBlt( this, 0, 0, &buffer );
00284 }
00285
00286 class TQSplitterLayoutStruct
00287 {
00288 public:
00289 KDGanttMinimizeSplitter::ResizeMode mode;
00290 TQCOORD sizer;
00291 bool isSplitter;
00292 TQWidget *wid;
00293 };
00294
00295 class TQSplitterData
00296 {
00297 public:
00298 TQSplitterData() : opaque( FALSE ), firstShow( TRUE ) {}
00299
00300 TQPtrList<TQSplitterLayoutStruct> list;
00301 bool opaque;
00302 bool firstShow;
00303 };
00304
00305 void kdganttGeomCalc( TQMemArray<TQLayoutStruct> &chain, int start, int count, int pos,
00306 int space, int spacer );
00307 #endif // DOXYGEN_SKIP_INTERNAL
00308
00309
00359 static TQSize minSize( const TQWidget* )
00360 {
00361 return TQSize(0,0);
00362 }
00363
00364
00365 static TQSize minSizeHint( const TQWidget* w )
00366 {
00367 TQSize min = w->minimumSize();
00368 TQSize s;
00369 if ( min.height() <= 0 || min.width() <= 0 )
00370 s = w->minimumSizeHint();
00371 if ( min.height() > 0 )
00372 s.setHeight( min.height() );
00373 if ( min.width() > 0 )
00374 s.setWidth( min.width() );
00375 return s.expandedTo(TQSize(0,0));
00376 }
00377
00378
00379
00384 KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( TQWidget *parent, const char *name )
00385 :TQFrame(parent,name,WPaintUnclipped)
00386 {
00387 orient = Qt::Horizontal;
00388 init();
00389 }
00390
00395 KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( Qt::Orientation o, TQWidget *parent, const char *name )
00396 :TQFrame(parent,name,WPaintUnclipped)
00397 {
00398 orient = o;
00399 init();
00400 }
00401
00405 KDGanttMinimizeSplitter::~KDGanttMinimizeSplitter()
00406 {
00407 data->list.setAutoDelete( TRUE );
00408 delete data;
00409 }
00410
00411
00412 void KDGanttMinimizeSplitter::init()
00413 {
00414 data = new TQSplitterData;
00415 if ( orient == Qt::Horizontal )
00416 setSizePolicy( TQSizePolicy(TQSizePolicy::Expanding,TQSizePolicy::Minimum) );
00417 else
00418 setSizePolicy( TQSizePolicy(TQSizePolicy::Minimum,TQSizePolicy::Expanding) );
00419 }
00420
00421
00422
00429 void KDGanttMinimizeSplitter::setOrientation( Qt::Orientation o )
00430 {
00431 if ( orient == o )
00432 return;
00433 orient = o;
00434
00435 if ( orient == Qt::Horizontal )
00436 setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Minimum ) );
00437 else
00438 setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Expanding ) );
00439
00440 TQSplitterLayoutStruct *s = data->list.first();
00441 while ( s ) {
00442 if ( s->isSplitter )
00443 ((KDGanttSplitterHandle*)s->wid)->setOrientation( o );
00444 s = data->list.next();
00445 }
00446 recalc( isVisible() );
00447 }
00448
00449
00453 void KDGanttMinimizeSplitter::resizeEvent( TQResizeEvent * )
00454 {
00455 doResize();
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 TQSplitterLayoutStruct *KDGanttMinimizeSplitter::addWidget( TQWidget *w, bool first )
00469 {
00470 TQSplitterLayoutStruct *s;
00471 KDGanttSplitterHandle *newHandle = 0;
00472 if ( data->list.count() > 0 ) {
00473 s = new TQSplitterLayoutStruct;
00474 s->mode = KeepSize;
00475 TQString tmp = "qt_splithandle_";
00476 tmp += w->name();
00477 newHandle = new KDGanttSplitterHandle( orientation(), this, tmp.latin1() );
00478 s->wid = newHandle;
00479 newHandle->setId(data->list.count());
00480 s->isSplitter = TRUE;
00481 s->sizer = pick( newHandle->sizeHint() );
00482 if ( first )
00483 data->list.insert( 0, s );
00484 else
00485 data->list.append( s );
00486 }
00487 s = new TQSplitterLayoutStruct;
00488 s->mode = Stretch;
00489 s->wid = w;
00490 if ( !testWState( WState_Resized ) && w->sizeHint().isValid() )
00491 s->sizer = pick( w->sizeHint() );
00492 else
00493 s->sizer = pick( w->size() );
00494 s->isSplitter = FALSE;
00495 if ( first )
00496 data->list.insert( 0, s );
00497 else
00498 data->list.append( s );
00499 if ( newHandle && isVisible() )
00500 newHandle->show();
00501 return s;
00502 }
00503
00504
00509 void KDGanttMinimizeSplitter::childEvent( TQChildEvent *c )
00510 {
00511 if ( c->type() == TQEvent::ChildInserted ) {
00512 if ( !c->child()->isWidgetType() )
00513 return;
00514
00515 if ( ((TQWidget*)c->child())->testWFlags( WType_TopLevel ) )
00516 return;
00517
00518 TQSplitterLayoutStruct *s = data->list.first();
00519 while ( s ) {
00520 if ( s->wid == c->child() )
00521 return;
00522 s = data->list.next();
00523 }
00524 addWidget( (TQWidget*)c->child() );
00525 recalc( isVisible() );
00526
00527 } else if ( c->type() == TQEvent::ChildRemoved ) {
00528 TQSplitterLayoutStruct *p = 0;
00529 if ( data->list.count() > 1 )
00530 p = data->list.at(1);
00531 TQSplitterLayoutStruct *s = data->list.first();
00532 while ( s ) {
00533 if ( s->wid == c->child() ) {
00534 data->list.removeRef( s );
00535 delete s;
00536 if ( p && p->isSplitter ) {
00537 data->list.removeRef( p );
00538 delete p->wid;
00539 delete p;
00540 }
00541 recalcId();
00542 doResize();
00543 return;
00544 }
00545 p = s;
00546 s = data->list.next();
00547 }
00548 }
00549 }
00550
00551
00556 void KDGanttMinimizeSplitter::setRubberband( int p )
00557 {
00558 TQPainter paint( this );
00559 paint.setPen( gray );
00560 paint.setBrush( gray );
00561 paint.setRasterOp( XorROP );
00562 TQRect r = contentsRect();
00563 const int rBord = 3;
00564 int sw = style().pixelMetric(TQStyle::PM_SplitterWidth, this);
00565 if ( orient == Qt::Horizontal ) {
00566 if ( opaqueOldPos >= 0 )
00567 paint.drawRect( opaqueOldPos + sw/2 - rBord , r.y(),
00568 2*rBord, r.height() );
00569 if ( p >= 0 )
00570 paint.drawRect( p + sw/2 - rBord, r.y(), 2*rBord, r.height() );
00571 } else {
00572 if ( opaqueOldPos >= 0 )
00573 paint.drawRect( r.x(), opaqueOldPos + sw/2 - rBord,
00574 r.width(), 2*rBord );
00575 if ( p >= 0 )
00576 paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
00577 }
00578 opaqueOldPos = p;
00579 }
00580
00581
00583 bool KDGanttMinimizeSplitter::event( TQEvent *e )
00584 {
00585 if ( e->type() == TQEvent::LayoutHint || ( e->type() == TQEvent::Show && data->firstShow ) ) {
00586 recalc( isVisible() );
00587 if ( e->type() == TQEvent::Show )
00588 data->firstShow = FALSE;
00589 }
00590 return TQWidget::event( e );
00591 }
00592
00593
00601 void KDGanttMinimizeSplitter::drawSplitter( TQPainter *p,
00602 TQCOORD x, TQCOORD y, TQCOORD w, TQCOORD h )
00603 {
00604 style().tqdrawPrimitive(TQStyle::PE_Splitter, p, TQRect(x, y, w, h), colorGroup(),
00605 (orientation() == Qt::Horizontal ?
00606 TQStyle::Style_Horizontal : 0));
00607 }
00608
00609
00615 int KDGanttMinimizeSplitter::idAfter( TQWidget* w ) const
00616 {
00617 TQSplitterLayoutStruct *s = data->list.first();
00618 bool seen_w = FALSE;
00619 while ( s ) {
00620 if ( s->isSplitter && seen_w )
00621 return data->list.at();
00622 if ( !s->isSplitter && s->wid == w )
00623 seen_w = TRUE;
00624 s = data->list.next();
00625 }
00626 return 0;
00627 }
00628
00629
00642 void KDGanttMinimizeSplitter::moveSplitter( TQCOORD p, int id )
00643 {
00644 p = adjustPos( p, id );
00645
00646 TQSplitterLayoutStruct *s = data->list.at(id);
00647 int oldP = orient == Qt::Horizontal ? s->wid->x() : s->wid->y();
00648 bool upLeft;
00649 if ( TQApplication::reverseLayout() && orient == Qt::Horizontal ) {
00650 p += s->wid->width();
00651 upLeft = p > oldP;
00652 } else
00653 upLeft = p < oldP;
00654
00655 moveAfter( p, id, upLeft );
00656 moveBefore( p-1, id-1, upLeft );
00657
00658 storeSizes();
00659 }
00660
00661
00662 void KDGanttMinimizeSplitter::setG( TQWidget *w, int p, int s, bool isSplitter )
00663 {
00664 if ( orient == Qt::Horizontal ) {
00665 if ( TQApplication::reverseLayout() && orient == Qt::Horizontal && !isSplitter )
00666 p = contentsRect().width() - p - s;
00667 w->setGeometry( p, contentsRect().y(), s, contentsRect().height() );
00668 } else
00669 w->setGeometry( contentsRect().x(), p, contentsRect().width(), s );
00670 }
00671
00672
00673
00674
00675
00676
00677
00678 void KDGanttMinimizeSplitter::moveBefore( int pos, int id, bool upLeft )
00679 {
00680 if( id < 0 )
00681 return;
00682 TQSplitterLayoutStruct *s = data->list.at(id);
00683 if ( !s )
00684 return;
00685 TQWidget *w = s->wid;
00686 if ( w->isHidden() ) {
00687 moveBefore( pos, id-1, upLeft );
00688 } else if ( s->isSplitter ) {
00689 int pos1, pos2;
00690 int dd = s->sizer;
00691 if( TQApplication::reverseLayout() && orient == Qt::Horizontal ) {
00692 pos1 = pos;
00693 pos2 = pos + dd;
00694 } else {
00695 pos2 = pos - dd;
00696 pos1 = pos2 + 1;
00697 }
00698 if ( upLeft ) {
00699 setG( w, pos1, dd, TRUE );
00700 moveBefore( pos2, id-1, upLeft );
00701 } else {
00702 moveBefore( pos2, id-1, upLeft );
00703 setG( w, pos1, dd, TRUE );
00704 }
00705 } else {
00706 int dd, newLeft, nextPos;
00707 if( TQApplication::reverseLayout() && orient == Qt::Horizontal ) {
00708 dd = w->geometry().right() - pos;
00709 dd = TQMAX( pick(minSize(w)), TQMIN(dd, pick(w->maximumSize())));
00710 newLeft = pos+1;
00711 nextPos = newLeft + dd;
00712 } else {
00713 dd = pos - pick( w->pos() ) + 1;
00714 dd = TQMAX( pick(minSize(w)), TQMIN(dd, pick(w->maximumSize())));
00715 newLeft = pos-dd+1;
00716 nextPos = newLeft - 1;
00717 }
00718 setG( w, newLeft, dd, TRUE );
00719 moveBefore( nextPos, id-1, upLeft );
00720 }
00721 }
00722
00723
00724
00725
00726
00727
00728
00729 void KDGanttMinimizeSplitter::moveAfter( int pos, int id, bool upLeft )
00730 {
00731 TQSplitterLayoutStruct *s = id < int(data->list.count()) ?
00732 data->list.at(id) : 0;
00733 if ( !s )
00734 return;
00735 TQWidget *w = s->wid;
00736 if ( w->isHidden() ) {
00737 moveAfter( pos, id+1, upLeft );
00738 } else if ( pick( w->pos() ) == pos ) {
00739
00740 return;
00741 } else if ( s->isSplitter ) {
00742 int dd = s->sizer;
00743 int pos1, pos2;
00744 if( TQApplication::reverseLayout() && orient == Qt::Horizontal ) {
00745 pos2 = pos - dd;
00746 pos1 = pos2 + 1;
00747 } else {
00748 pos1 = pos;
00749 pos2 = pos + dd;
00750 }
00751 if ( upLeft ) {
00752 setG( w, pos1, dd, TRUE );
00753 moveAfter( pos2, id+1, upLeft );
00754 } else {
00755 moveAfter( pos2, id+1, upLeft );
00756 setG( w, pos1, dd, TRUE );
00757 }
00758 } else {
00759 int left = pick( w->pos() );
00760 int right, dd, newLeft, nextPos;
00761 if ( TQApplication::reverseLayout() && orient == Qt::Horizontal ) {
00762 dd = pos - left + 1;
00763 dd = TQMAX( pick(minSize(w)), TQMIN(dd, pick(w->maximumSize())));
00764 newLeft = pos-dd+1;
00765 nextPos = newLeft - 1;
00766 } else {
00767 right = pick( w->geometry().bottomRight() );
00768 dd = right - pos + 1;
00769 dd = TQMAX( pick(minSize(w)), TQMIN(dd, pick(w->maximumSize())));
00770
00771 newLeft = pos;
00772 nextPos = newLeft + dd;
00773 }
00774 setG( w, newLeft, dd, TRUE );
00775
00776 moveAfter( nextPos, id+1, upLeft );
00777 }
00778 }
00779
00780
00781 void KDGanttMinimizeSplitter::expandPos( int id, int* min, int* max )
00782 {
00783 TQSplitterLayoutStruct *s = data->list.at(id-1);
00784 TQWidget* w = s->wid;
00785 *min = pick( w->mapToParent( TQPoint(0,0) ) );
00786
00787 if ( (uint) id == data->list.count() ) {
00788 pick( size() );
00789 }
00790 else {
00791 TQSplitterLayoutStruct *s = data->list.at(id+1);
00792 TQWidget* w = s->wid;
00793 *max = pick( w->mapToParent( TQPoint( w->width(), w->height() ) ) ) -8;
00794 }
00795 }
00796
00797
00804 void KDGanttMinimizeSplitter::getRange( int id, int *min, int *max )
00805 {
00806 int minB = 0;
00807 int maxB = 0;
00808 int minA = 0;
00809 int maxA = 0;
00810 int n = data->list.count();
00811 if ( id < 0 || id >= n )
00812 return;
00813 int i;
00814 for ( i = 0; i < id; i++ ) {
00815 TQSplitterLayoutStruct *s = data->list.at(i);
00816 if ( s->wid->isHidden() ) {
00817
00818 } else if ( s->isSplitter ) {
00819 minB += s->sizer;
00820 maxB += s->sizer;
00821 } else {
00822 minB += pick( minSize(s->wid) );
00823 maxB += pick( s->wid->maximumSize() );
00824 }
00825 }
00826 for ( i = id; i < n; i++ ) {
00827 TQSplitterLayoutStruct *s = data->list.at(i);
00828 if ( s->wid->isHidden() ) {
00829
00830 } else if ( s->isSplitter ) {
00831 minA += s->sizer;
00832 maxA += s->sizer;
00833 } else {
00834 minA += pick( minSize(s->wid) );
00835 maxA += pick( s->wid->maximumSize() );
00836 }
00837 }
00838 TQRect r = contentsRect();
00839 if ( orient == Qt::Horizontal && TQApplication::reverseLayout() ) {
00840 int splitterWidth = style().pixelMetric(TQStyle::PM_SplitterWidth, this);
00841 if ( min )
00842 *min = pick(r.topRight()) - TQMIN( maxB, pick(r.size())-minA ) - splitterWidth;
00843 if ( max )
00844 *max = pick(r.topRight()) - TQMAX( minB, pick(r.size())-maxA ) - splitterWidth;
00845 } else {
00846 if ( min )
00847 *min = pick(r.topLeft()) + TQMAX( minB, pick(r.size())-maxA );
00848 if ( max )
00849 *max = pick(r.topLeft()) + TQMIN( maxB, pick(r.size())-minA );
00850 }
00851 }
00852
00853
00860 int KDGanttMinimizeSplitter::adjustPos( int p, int id )
00861 {
00862 int min = 0;
00863 int max = 0;
00864 getRange( id, &min, &max );
00865 p = TQMAX( min, TQMIN( p, max ) );
00866
00867 return p;
00868 }
00869
00870
00871 void KDGanttMinimizeSplitter::doResize()
00872 {
00873 TQRect r = contentsRect();
00874 int i;
00875 int n = data->list.count();
00876 TQMemArray<TQLayoutStruct> a( n );
00877 for ( i = 0; i< n; i++ ) {
00878 a[i].init();
00879 TQSplitterLayoutStruct *s = data->list.at(i);
00880 if ( s->wid->isHidden() ) {
00881 a[i].stretch = 0;
00882 a[i].sizeHint = a[i].minimumSize = 0;
00883 a[i].maximumSize = 0;
00884 } else if ( s->isSplitter ) {
00885 a[i].stretch = 0;
00886 a[i].sizeHint = a[i].minimumSize = a[i].maximumSize = s->sizer;
00887 a[i].empty = FALSE;
00888 } else if ( s->mode == KeepSize ) {
00889 a[i].stretch = 0;
00890 a[i].minimumSize = pick( minSize(s->wid) );
00891 a[i].sizeHint = s->sizer;
00892 a[i].maximumSize = pick( s->wid->maximumSize() );
00893 a[i].empty = FALSE;
00894 } else if ( s->mode == FollowSizeHint ) {
00895 a[i].stretch = 0;
00896 a[i].minimumSize = a[i].sizeHint = pick( s->wid->sizeHint() );
00897 a[i].maximumSize = pick( s->wid->maximumSize() );
00898 a[i].empty = FALSE;
00899 } else {
00900 a[i].stretch = s->sizer;
00901 a[i].maximumSize = pick( s->wid->maximumSize() );
00902 a[i].sizeHint = a[i].minimumSize = pick( minSize(s->wid) );
00903 a[i].empty = FALSE;
00904 }
00905 }
00906
00907 kdganttGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 );
00908
00909 for ( i = 0; i< n; i++ ) {
00910 TQSplitterLayoutStruct *s = data->list.at(i);
00911 setG( s->wid, a[i].pos, a[i].size );
00912 }
00913
00914 }
00915
00916
00917 void KDGanttMinimizeSplitter::recalc( bool update )
00918 {
00919 int fi = 2*frameWidth();
00920 int maxl = fi;
00921 int minl = fi;
00922 int maxt = TQWIDGETSIZE_MAX;
00923 int mint = fi;
00924 int n = data->list.count();
00925 bool first = TRUE;
00926
00927
00928
00929
00930
00931 for ( int i = 0; i< n; i++ ) {
00932 TQSplitterLayoutStruct *s = data->list.at(i);
00933 if ( !s->isSplitter ) {
00934 TQSplitterLayoutStruct *p = (i > 0) ? data->list.at( i-1 ) : 0;
00935 if ( p && p->isSplitter )
00936 if ( first || s->wid->isHidden() )
00937 p->wid->hide();
00938 else
00939 p->wid->show();
00940 if ( !s->wid->isHidden() )
00941 first = FALSE;
00942 }
00943 }
00944
00945 bool empty=TRUE;
00946 for ( int j = 0; j< n; j++ ) {
00947 TQSplitterLayoutStruct *s = data->list.at(j);
00948 if ( !s->wid->isHidden() ) {
00949 empty = FALSE;
00950 if ( s->isSplitter ) {
00951 minl += s->sizer;
00952 maxl += s->sizer;
00953 } else {
00954 TQSize minS = minSize(s->wid);
00955 minl += pick( minS );
00956 maxl += pick( s->wid->maximumSize() );
00957 mint = TQMAX( mint, trans( minS ));
00958 int tm = trans( s->wid->maximumSize() );
00959 if ( tm > 0 )
00960 maxt = TQMIN( maxt, tm );
00961 }
00962 }
00963 }
00964 if ( empty ) {
00965 if ( parentWidget() != 0 && parentWidget()->inherits("KDGanttMinimizeSplitter") ) {
00966
00967 maxl = maxt = 0;
00968 } else {
00969
00970 maxl = TQWIDGETSIZE_MAX;
00971 }
00972 } else {
00973 maxl = TQMIN( maxl, TQWIDGETSIZE_MAX );
00974 }
00975 if ( maxt < mint )
00976 maxt = mint;
00977
00978 if ( orient == Qt::Horizontal ) {
00979 setMaximumSize( maxl, maxt );
00980 setMinimumSize( minl, mint );
00981 } else {
00982 setMaximumSize( maxt, maxl );
00983 setMinimumSize( mint, minl );
00984 }
00985 if ( update )
00986 doResize();
00987 }
00988
00995 void KDGanttMinimizeSplitter::setResizeMode( TQWidget *w, ResizeMode mode )
00996 {
00997 processChildEvents();
00998 TQSplitterLayoutStruct *s = data->list.first();
00999 while ( s ) {
01000 if ( s->wid == w ) {
01001 s->mode = mode;
01002 return;
01003 }
01004 s = data->list.next();
01005 }
01006 s = addWidget( w, TRUE );
01007 s->mode = mode;
01008 }
01009
01010
01017 bool KDGanttMinimizeSplitter::opaqueResize() const
01018 {
01019 return data->opaque;
01020 }
01021
01022
01031 void KDGanttMinimizeSplitter::setOpaqueResize( bool on )
01032 {
01033 data->opaque = on;
01034 }
01035
01036
01041 void KDGanttMinimizeSplitter::moveToFirst( TQWidget *w )
01042 {
01043 processChildEvents();
01044 bool found = FALSE;
01045 TQSplitterLayoutStruct *s = data->list.first();
01046 while ( s ) {
01047 if ( s->wid == w ) {
01048 found = TRUE;
01049 TQSplitterLayoutStruct *p = data->list.prev();
01050 if ( p ) {
01051 data->list.take();
01052 data->list.take();
01053 data->list.insert( 0, p );
01054 data->list.insert( 0, s );
01055 }
01056 break;
01057 }
01058 s = data->list.next();
01059 }
01060 if ( !found )
01061 addWidget( w, TRUE );
01062 recalcId();
01063 }
01064
01065
01070 void KDGanttMinimizeSplitter::moveToLast( TQWidget *w )
01071 {
01072 processChildEvents();
01073 bool found = FALSE;
01074 TQSplitterLayoutStruct *s = data->list.first();
01075 while ( s ) {
01076 if ( s->wid == w ) {
01077 found = TRUE;
01078 data->list.take();
01079 TQSplitterLayoutStruct *p = data->list.current();
01080 if ( p ) {
01081 data->list.take();
01082 data->list.append( p );
01083 }
01084 data->list.append( s );
01085 break;
01086 }
01087 s = data->list.next();
01088 }
01089 if ( !found )
01090 addWidget( w);
01091 recalcId();
01092 }
01093
01094
01095 void KDGanttMinimizeSplitter::recalcId()
01096 {
01097 int n = data->list.count();
01098 for ( int i = 0; i < n; i++ ) {
01099 TQSplitterLayoutStruct *s = data->list.at(i);
01100 if ( s->isSplitter )
01101 ((KDGanttSplitterHandle*)s->wid)->setId(i);
01102 }
01103 }
01104
01105
01108 TQSize KDGanttMinimizeSplitter::sizeHint() const
01109 {
01110 constPolish();
01111 int l = 0;
01112 int t = 0;
01113 if ( !childrenListObject().isEmpty() ) {
01114 const TQObjectList c = childrenListObject();
01115 TQObjectListIt it( c );
01116 TQObject * o;
01117
01118 while( (o=it.current()) != 0 ) {
01119 ++it;
01120 if ( o->isWidgetType() &&
01121 !((TQWidget*)o)->isHidden() ) {
01122 TQSize s = ((TQWidget*)o)->sizeHint();
01123 if ( s.isValid() ) {
01124 l += pick( s );
01125 t = TQMAX( t, trans( s ) );
01126 }
01127 }
01128 }
01129 }
01130 return orientation() == Qt::Horizontal ? TQSize( l, t ) : TQSize( t, l );
01131 }
01132
01133
01138 TQSize KDGanttMinimizeSplitter::minimumSizeHint() const
01139 {
01140 constPolish();
01141 int l = 0;
01142 int t = 0;
01143 if ( !childrenListObject().isEmpty() ) {
01144 const TQObjectList c = childrenListObject();
01145 TQObjectListIt it( c );
01146 TQObject * o;
01147
01148 while( (o=it.current()) != 0 ) {
01149 ++it;
01150 if ( o->isWidgetType() &&
01151 !((TQWidget*)o)->isHidden() ) {
01152 TQSize s = minSizeHint((TQWidget*)o);
01153 if ( s.isValid() ) {
01154 l += pick( s );
01155 t = TQMAX( t, trans( s ) );
01156 }
01157 }
01158 }
01159 }
01160 return orientation() == Qt::Horizontal ? TQSize( l, t ) : TQSize( t, l );
01161 }
01162
01163
01164
01165
01166
01167
01168 void KDGanttMinimizeSplitter::storeSizes()
01169 {
01170 TQSplitterLayoutStruct *s = data->list.first();
01171 while ( s ) {
01172 if ( !s->isSplitter )
01173 s->sizer = pick( s->wid->size() );
01174 s = data->list.next();
01175 }
01176 }
01177
01178
01179 #if 0 // ### remove this code ASAP
01180
01188 void KDGanttMinimizeSplitter::setHidden( TQWidget *w, bool hide )
01189 {
01190 if ( w == w1 ) {
01191 w1show = !hide;
01192 } else if ( w == w2 ) {
01193 w2show = !hide;
01194 } else {
01195 #ifdef TQT_CHECK_RANGE
01196 qWarning( "KDGanttMinimizeSplitter::setHidden(), unknown widget" );
01197 #endif
01198 return;
01199 }
01200 if ( hide )
01201 w->hide();
01202 else
01203 w->show();
01204 recalc( TRUE );
01205 }
01206
01207
01212 bool KDGanttMinimizeSplitter::isHidden( TQWidget *w ) const
01213 {
01214 if ( w == w1 )
01215 return !w1show;
01216 else if ( w == w2 )
01217 return !w2show;
01218 #ifdef TQT_CHECK_RANGE
01219 else
01220 qWarning( "KDGanttMinimizeSplitter::isHidden(), unknown widget" );
01221 #endif
01222 return FALSE;
01223 }
01224 #endif
01225
01226
01248 TQValueList<int> KDGanttMinimizeSplitter::sizes() const
01249 {
01250 if ( !testWState(WState_Polished) ) {
01251 TQWidget* that = (TQWidget*) this;
01252 that->polish();
01253 }
01254 TQValueList<int> list;
01255 TQSplitterLayoutStruct *s = data->list.first();
01256 while ( s ) {
01257 if ( !s->isSplitter )
01258 list.append( s->sizer );
01259 s = data->list.next();
01260 }
01261 return list;
01262 }
01263
01264
01265
01279 void KDGanttMinimizeSplitter::setSizes( TQValueList<int> list )
01280 {
01281 processChildEvents();
01282 TQValueList<int>::Iterator it = list.begin();
01283 TQSplitterLayoutStruct *s = data->list.first();
01284 while ( s && it != list.end() ) {
01285 if ( !s->isSplitter ) {
01286 s->sizer = *it;
01287 ++it;
01288 }
01289 s = data->list.next();
01290 }
01291 doResize();
01292 }
01293
01294
01300 void KDGanttMinimizeSplitter::processChildEvents()
01301 {
01302 TQApplication::sendPostedEvents( this, TQEvent::ChildInserted );
01303 }
01304
01305
01310 void KDGanttMinimizeSplitter::styleChange( TQStyle& old )
01311 {
01312 int sw = style().pixelMetric(TQStyle::PM_SplitterWidth, this);
01313 TQSplitterLayoutStruct *s = data->list.first();
01314 while ( s ) {
01315 if ( s->isSplitter )
01316 s->sizer = sw;
01317 s = data->list.next();
01318 }
01319 doResize();
01320 TQFrame::styleChange( old );
01321 }
01322
01330 void KDGanttMinimizeSplitter::setMinimizeDirection( Direction direction )
01331 {
01332 _direction = direction;
01333 }
01334
01338 KDGanttMinimizeSplitter::Direction KDGanttMinimizeSplitter::minimizeDirection() const
01339 {
01340 return _direction;
01341 }
01342
01343
01344
01345
01346
01347 static inline int toFixed( int i ) { return i * 256; }
01348 static inline int fRound( int i ) {
01349 return ( i % 256 < 128 ) ? i / 256 : 1 + i / 256;
01350 }
01351 void kdganttGeomCalc( TQMemArray<TQLayoutStruct> &chain, int start, int count, int pos,
01352 int space, int spacer )
01353 {
01354 typedef int fixed;
01355 int cHint = 0;
01356 int cMin = 0;
01357 int cMax = 0;
01358 int sumStretch = 0;
01359 int spacerCount = 0;
01360
01361 bool wannaGrow = FALSE;
01362
01363
01364 int i;
01365 for ( i = start; i < start + count; i++ ) {
01366 chain[i].done = FALSE;
01367 cHint += chain[i].sizeHint;
01368 cMin += chain[i].minimumSize;
01369 cMax += chain[i].maximumSize;
01370 sumStretch += chain[i].stretch;
01371 if ( !chain[i].empty )
01372 spacerCount++;
01373 wannaGrow = wannaGrow || chain[i].expansive;
01374 }
01375
01376 int extraspace = 0;
01377 if ( spacerCount )
01378 spacerCount--;
01379 if ( space < cMin + spacerCount * spacer ) {
01380
01381 for ( i = start; i < start+count; i++ ) {
01382 chain[i].size = chain[i].minimumSize;
01383 chain[i].done = TRUE;
01384 }
01385 } else if ( space < cHint + spacerCount*spacer ) {
01386
01387
01388
01389 int n = count;
01390 int space_left = space - spacerCount*spacer;
01391 int overdraft = cHint - space_left;
01392
01393 for ( i = start; i < start+count; i++ ) {
01394 if ( !chain[i].done && chain[i].minimumSize >= chain[i].sizeHint) {
01395 chain[i].size = chain[i].sizeHint;
01396 chain[i].done = TRUE;
01397 space_left -= chain[i].sizeHint;
01398
01399 n--;
01400 }
01401 }
01402 bool finished = n == 0;
01403 while ( !finished ) {
01404 finished = TRUE;
01405 fixed fp_over = toFixed( overdraft );
01406 fixed fp_w = 0;
01407
01408 for ( i = start; i < start+count; i++ ) {
01409 if ( chain[i].done )
01410 continue;
01411
01412 fp_w += fp_over / n;
01413
01414
01415 int w = fRound( fp_w );
01416 chain[i].size = chain[i].sizeHint - w;
01417 fp_w -= toFixed( w );
01418 if ( chain[i].size < chain[i].minimumSize ) {
01419 chain[i].done = TRUE;
01420 chain[i].size = chain[i].minimumSize;
01421 finished = FALSE;
01422 overdraft -= chain[i].sizeHint - chain[i].minimumSize;
01423
01424 n--;
01425 break;
01426 }
01427 }
01428 }
01429 } else {
01430 int n = count;
01431 int space_left = space - spacerCount*spacer;
01432
01433 for ( i = start; i < start + count; i++ ) {
01434 if ( !chain[i].done && (chain[i].maximumSize <= chain[i].sizeHint
01435 || wannaGrow && !chain[i].expansive) ) {
01436 chain[i].size = chain[i].sizeHint;
01437 chain[i].done = TRUE;
01438 space_left -= chain[i].sizeHint;
01439 sumStretch -= chain[i].stretch;
01440 n--;
01441 }
01442 }
01443 extraspace = space_left;
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454 int surplus, deficit;
01455 do {
01456 surplus = deficit = 0;
01457 fixed fp_space = toFixed( space_left );
01458 fixed fp_w = 0;
01459 for ( i = start; i < start+count; i++ ) {
01460 if ( chain[i].done )
01461 continue;
01462 extraspace = 0;
01463 if ( sumStretch <= 0 )
01464 fp_w += fp_space / n;
01465 else
01466 fp_w += (fp_space * chain[i].stretch) / sumStretch;
01467 int w = fRound( fp_w );
01468 chain[i].size = w;
01469 fp_w -= toFixed( w );
01470 if ( w < chain[i].sizeHint ) {
01471 deficit += chain[i].sizeHint - w;
01472 } else if ( w > chain[i].maximumSize ) {
01473 surplus += w - chain[i].maximumSize;
01474 }
01475 }
01476 if ( deficit > 0 && surplus <= deficit ) {
01477
01478 for ( i = start; i < start+count; i++ ) {
01479 if ( !chain[i].done &&
01480 chain[i].size < chain[i].sizeHint ) {
01481 chain[i].size = chain[i].sizeHint;
01482 chain[i].done = TRUE;
01483 space_left -= chain[i].sizeHint;
01484 sumStretch -= chain[i].stretch;
01485 n--;
01486 }
01487 }
01488 }
01489 if ( surplus > 0 && surplus >= deficit ) {
01490
01491 for ( i = start; i < start+count; i++ ) {
01492 if ( !chain[i].done &&
01493 chain[i].size > chain[i].maximumSize ) {
01494 chain[i].size = chain[i].maximumSize;
01495 chain[i].done = TRUE;
01496 space_left -= chain[i].maximumSize;
01497 sumStretch -= chain[i].stretch;
01498 n--;
01499 }
01500 }
01501 }
01502 } while ( n > 0 && surplus != deficit );
01503 if ( n == 0 )
01504 extraspace = space_left;
01505 }
01506
01507
01508
01509
01510
01511 int extra = extraspace / ( spacerCount + 2 );
01512 int p = pos + extra;
01513 for ( i = start; i < start+count; i++ ) {
01514 chain[i].pos = p;
01515 p = p + chain[i].size;
01516 if ( !chain[i].empty )
01517 p += spacer+extra;
01518 }
01519 }
01520
01521 #endif
01522