This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Bug Report : egcs internal compiler error


Problem: egcs internal compiler error
Background: While attempting to compile Qt 2.1.0 (free version)
the make stopped while compiling src/widgets/qmainwindow.cpp
with error number 550 - internal compiler error.  Screen output is
shown below:

cd src/moc; make
make[1]: Entering directory `/usr/local/qt-2.1.0/src/moc'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/usr/local/qt-2.1.0/src/moc'
mkdir bin
mkdir: cannot make directory `bin': File exists
make: [moc] Error 1 (ignored)
rm -f bin/moc
cp src/moc/moc bin/moc
cd src; make
make[1]: Entering directory `/usr/local/qt-2.1.0/src'
g++ -c -I/usr/local/qt/include -I/usr/X11R6/include -pipe -O2 -fPIC
-I/usr/local/qt/src/3rdparty/zlib -I/usr/local/qt/src/3rdparty/libpng
   -o widgets/qmainwindow.o widgets/qmainwindow.cpp
widgets/qmainwindow.cpp: In method
`int QToolLayout::layoutItems(const class QRect &, bool = FALSE)':
widgets/qmainwindow.cpp:550: Internal compiler error.
widgets/qmainwindow.cpp:550:
Please submit a full bug report to `egcs-bugs@cygnus.com'.
cpp: output pipe has been closed
make[1]: *** [widgets/qmainwindow.o] Error 1
make[1]: Leaving directory `/usr/local/qt-2.1.0/src'
make: *** [src] Error 2

This was obtained by running make again after the initial failure

Other background: I was using these versions of gcc, egcs and Linux;

gcc version 2.7.2.3
egcs-2.90.29 980515 (egcs-1.0.3 release)
(fails on egcs-1.0.2 release as well)
Red Hat Linux release 5.1 (Manhattan)
Kernel 2.0.33pl1 on a m68k

Hardware:
Amiga with Blizzard 2060 68060 50MHz accelerator, 32Mb RAM

Other:
Compiler was installed from the Red Hat m68k binary RPMs,
  I don't know how it is configured (it usually works...)
I have made no changes to compiler source or any config files
for the compiler. Everything is exactly as I received it on the
distribution

The error is repeatable, happens on 1st attempt to make Qt 2.1.0
and on subsequent attempts.  Occurs with both 1.0.2 and 1.0.3
releases of egcs.  Same symptoms using 2.2.10 kernel.

I include a copy of qmainwindow.cpp as an attachment - sorry that I
can`t include standalone version.

Any suggestions?

Regards, John Connor

________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com
/****************************************************************************
** $Id: qt/src/widgets/qmainwindow.cpp   2.1.0   edited 2000-04-07 $
**
** Implementation of QMainWindow class
**
** Created : 980312
**
** Copyright (C) 1992-2000 Troll Tech AS.  All rights reserved.
**
** This file is part of the Qt GUI Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Troll Tech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** Licensees holding valid Qt Professional Edition licenses may use this
** file in accordance with the Qt Professional Edition License Agreement
** provided with the Qt Professional Edition.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com 
for
** information about the Professional Edition licensing, or see
** http://www.trolltech.com/qpl/ for QPL licensing information.
**
*****************************************************************************/

#include "qmainwindow.h"

#include "qtimer.h"
#include "qlayout.h"
#include "qobjectlist.h"
#include "qobjectdict.h"
#include "qapplication.h"
#include "qlist.h"
#include "qmap.h"
#include "qcursor.h"
#include "qpainter.h"
#include "qmenubar.h"
#include "qtoolbar.h"
#include "qstatusbar.h"
#include "qscrollview.h"
#include "qtooltip.h"
#include "qdatetime.h"
#include "qtooltip.h"
#include "qwhatsthis.h"
#include "qbitmap.h"

//#define QMAINWINDOW_DEBUG

//****************************************************************************
// -------------------------- static convenience functions 
-------------------
//****************************************************************************

bool operator<( const QRect &r1, const QRect &r2 )
{
    return ( r1.x() < r2.x() ||
	     r1.y() < r2.y() );
}

static Qt::Orientation swap_orientation( Qt::Orientation o )
{
    if ( o == Qt::Horizontal )
	return Qt::Vertical;
    else
	return Qt::Horizontal;
}

static int tb_pos( QToolBar *t, Qt::Orientation o, bool swap = FALSE )
{
    if ( swap )
	o = swap_orientation( o );
    if ( o == Qt::Horizontal )
	return t->x();
    else
	return t->y();
}

static int tb_extend( QToolBar *t, Qt::Orientation o, bool swap = FALSE )
{
    if ( swap )
	o = swap_orientation( o );
    if ( o == Qt::Horizontal )
	return t->width();
    else
	return t->height();
}

static int rect_pos( const QRect &r, Qt::Orientation o, bool swap = FALSE )
{
    if ( swap )
	o = swap_orientation( o );
    if ( o == Qt::Horizontal )
	return r.x();
    else
	return r.y();
}

static int rect_extend( const QRect &r, Qt::Orientation o, bool swap = FALSE 
)
{
    if ( swap )
	o = swap_orientation( o );
    if ( o == Qt::Horizontal )
	return r.width();
    else
	return r.height();
}

static int size_extend( const QSize &s, Qt::Orientation o, bool swap = FALSE 
)
{
    if ( swap )
	o = swap_orientation( o );
    if ( o == Qt::Horizontal )
	return s.width();
    else
	return s.height();
}

static QSize size_hint( QToolBar *tb )
{
    if ( !tb || !tb->isVisibleTo( tb->parentWidget() ) )
	return QSize( 0, 0 );
    QSize s = tb->sizeHint();
    if ( tb->minimumWidth() > s.width() )
	s.setWidth( tb->minimumWidth() );
    if ( tb->minimumHeight() > s.height() )
	s.setHeight( tb->minimumHeight() );
    return s;
}

//************************************************************************************************
// ------------------------ QMainWindowPrivate  -----------------------
//************************************************************************************************
class QHideDock;
class QToolLayout;
class QMainWindowPrivate {
public:
    struct ToolBar {
	ToolBar() : t(0), nl(FALSE) {}
	ToolBar( QToolBar * tb, bool n=FALSE )
	    : t( tb ), hiddenBefore( 0 ), hiddenAfter( 0 ), nl( n ),
	      oldDock( QMainWindow::Top ), oldIndex( 0 ), extraOffset( -1 )  {}
	bool isStretchable( Qt::Orientation o ) const
	    { return o == Qt::Horizontal ? t->isHorizontalStretchable() : 
t->isVerticalStretchable(); }

	QToolBar * t;
	ToolBar *hiddenBefore;
	ToolBar *hiddenAfter;
	bool nl;
	QValueList<int> disabledDocks;
	QMainWindow::ToolBarDock oldDock;
	int oldIndex;
	int extraOffset;
    };

    typedef QList<ToolBar> ToolBarDock;
    enum InsertPos { Before, After, Above, Below, SameIndex };

    QMainWindowPrivate()
	:  tornOff(0), unmanaged(0), hidden( 0 ),
	  mb(0), sb(0), ttg(0), mc(0), timer(0), tll(0), ubp( FALSE ), utl( FALSE 
),
	  justify( FALSE )
    {
	top = new ToolBarDock;
	left = new ToolBarDock;
	right = new ToolBarDock;
	bottom = new ToolBarDock;
	hidden = new ToolBarDock;
	unmanaged = new ToolBarDock;
	tornOff = new ToolBarDock;
	rectPainter = 0;
	dockable[ (int)QMainWindow::Left ] = TRUE;
	dockable[ (int)QMainWindow::Right ] = TRUE;
	dockable[ (int)QMainWindow::Top ] = TRUE;
	dockable[ (int)QMainWindow::Bottom ] = TRUE;
	dockable[ (int)QMainWindow::Unmanaged ] = TRUE;
	dockable[ (int)QMainWindow::Minimized ] = TRUE;
	dockable[ (int)QMainWindow::TornOff ] = TRUE;
	lLeft = lRight = lTop = lBottom = 0;
	lastTopHeight = -1;
	movable = TRUE;
	inMovement = FALSE;
	dockMenu = TRUE;
	oldCursor = ArrowCursor;
    }

    ToolBar *findToolbar( QToolBar *t, QMainWindowPrivate::ToolBarDock 
*&dock );
    ToolBar *takeToolBarFromDock( QToolBar * t, bool remember = FALSE );

    ~QMainWindowPrivate()
    {
	if ( top ) {
	    top->setAutoDelete( TRUE );
	    delete top;
	}
	if ( left ) {
	    left->setAutoDelete( TRUE );
	    delete left;
	}
	if ( right ) {
	    right->setAutoDelete( TRUE );
	    delete right;
	}
	if ( bottom ) {
	    bottom->setAutoDelete( TRUE );
	    delete bottom;
	}
	if ( tornOff ) {
	    tornOff->setAutoDelete( TRUE );
	    delete tornOff;
	}
	if ( unmanaged ) {
	    unmanaged->setAutoDelete( TRUE );
	    delete unmanaged;
	}
	if ( hidden ) {
	    hidden->setAutoDelete( TRUE );
	    delete hidden;
	}
    }

    ToolBarDock * top, * left, * right, * bottom, * tornOff, * unmanaged, 
*hidden;
    QToolLayout *lLeft, *lRight, *lTop, *lBottom;

    QMenuBar * mb;
    QStatusBar * sb;
    QToolTipGroup * ttg;

    QWidget * mc;

    QTimer * timer;

    QBoxLayout * tll;

    bool ubp;
    bool utl;
    bool justify;

    QPoint pos;
    QPoint offset;

    QPainter *rectPainter;
    QRect oldPosRect;
    QRect origPosRect;
    bool oldPosRectValid, movedEnough;
    QMainWindow::ToolBarDock oldDock, origDock;
    QHideDock *hideDock;
    QPoint cursorOffset;
    int lastTopHeight;

    bool movable;
    bool opaque;
    bool inMovement;
    bool dockMenu;

    QCursor oldCursor;

    QMap< int, bool > dockable;
};

QMainWindowPrivate::ToolBar * QMainWindowPrivate::findToolbar( QToolBar * t,
							       QMainWindowPrivate::ToolBarDock *&dock )
{
    QMainWindowPrivate::ToolBarDock* docks[] = {
	left, right, top, bottom, unmanaged, tornOff, hidden
    };


    QMainWindowPrivate::ToolBarDock *l = 0;

    for ( unsigned int i = 0; i < 7; ++i ) {
	l = docks[ i ];
	if ( !l )
	    continue;
	QMainWindowPrivate::ToolBar * ct = l->first();
	do {
	    if ( ct && ct->t == t ) {
		dock = l;
		return ct;
	    }
	} while( ( ct = l->next() ) != 0 );
    }

    dock = 0;
    return 0;
}

QMainWindowPrivate::ToolBar * QMainWindowPrivate::takeToolBarFromDock( 
QToolBar * t, bool remember )
{
    QMainWindowPrivate::ToolBarDock *l;
    QMainWindowPrivate::ToolBar *tb = findToolbar( t, l );
    if ( tb && l ) {
	int p = l->findRef( tb );
	if ( remember ) {
	    if ( p < (int)l->count() - 1 && !l->at( p + 1 )->nl ) {
		l->at( p + 1 )->hiddenBefore = tb;
#ifdef QMAINWINDOW_DEBUG
		qDebug( "remember toolbar before me" );
#endif
	    } else if ( p > 0 && !tb->nl ) {
		l->at( p - 1 )->hiddenAfter = tb;
#ifdef QMAINWINDOW_DEBUG
		qDebug( "remember toolbar after me" );
#endif
	    }
	    if ( p < (int)l->count() - 1 && tb->nl )
		l->at( p + 1 )->nl = TRUE;
	    tb->oldIndex = p;
	}
	return l->take( p );
    }
    return 0;
}

//************************************************************************************************
// --------------------------------- QToolLayout 
---------------------------------
//************************************************************************************************

/*
  This layout class does not work very well for vertical toolbars yet
*/

class QToolLayout : public QLayout
{
public:
    QToolLayout( QLayout* parent, QMainWindowPrivate::ToolBarDock *d,
		 QBoxLayout::Direction dd, bool justify,
		 int space=-1, const char *name=0 )
	: QLayout( parent, space, name ), dock(d), dir(dd), fill(justify)
	{ init(); }

    ~QToolLayout();

    void addItem( QLayoutItem *item);
    bool hasHeightForWidth() const;
    int heightForWidth( int ) const;
    int widthForHeight( int ) const;
    QSize sizeHint() const;
    QSize minimumSize() const;
    QLayoutIterator iterator();
    QSizePolicy::ExpandData expanding() const { return 
QSizePolicy::NoDirection; }
    void setDirection( QBoxLayout::Direction d ) { dir = d; }
    QBoxLayout::Direction direction() const { return dir; }
    void newLine();
    void setRightJustified( bool on ) { fill = on; }
    bool rightJustified() const { return fill; }
    void invalidate();

protected:
    void setGeometry( const QRect& );

private:
    void init();
    int layoutItems( const QRect&, bool testonly = FALSE );
    QMainWindowPrivate::ToolBarDock *dock;
    QBoxLayout::Direction dir;
    bool fill;
    int cached_width, cached_height;
    int cached_hfw, cached_wfh;

    friend class QMainWindowLayout;
};


QSize QToolLayout::sizeHint() const
{
    if ( !dock || !dock->first() )
	return QSize(0,0);

    int w = 0;
    int h = 0;
    QListIterator<QMainWindowPrivate::ToolBar> it(*dock);
    QMainWindowPrivate::ToolBar *tb;
    it.toFirst();
    int y = -1;
    int x = -1;
    int ph = 0;
    int pw = 0;
    while ( (tb=it.current()) != 0 ) {
	int plush = 0, plusw = 0;
	++it;
	if ( hasHeightForWidth() ) {
	    if ( y != tb->t->y() )
		plush = ph;
	    y = tb->t->y();
	    ph = tb->t->height();
	} else {
	    if ( x != tb->t->x() )
		plusw = pw;
	    x = tb->t->x();
	    pw = tb->t->width();
	}
	h = QMAX( h, tb->t->height() + plush );
	w = QMAX( w, tb->t->width() + plusw );
    }

    if ( hasHeightForWidth() )
	return QSize( 0, h );
    return QSize( w, 0 );
}

bool QToolLayout::hasHeightForWidth() const
{
    //direction is the dock's direction, which is perpendicular to the 
layout
    return dir == QBoxLayout::Up || dir == QBoxLayout::Down;
}

void QToolLayout::init()
{
    cached_width = 0;
    cached_height = 0;
}

QToolLayout::~QToolLayout()
{
}

QSize QToolLayout::minimumSize() const
{
    if ( !dock )
	return QSize(0,0);
    QSize s;

    QListIterator<QMainWindowPrivate::ToolBar> it(*dock);
    QMainWindowPrivate::ToolBar *tb;
    while ( (tb=it.current()) != 0 ) {
	++it;
	s = s.expandedTo( tb->t->minimumSizeHint() )
	    .expandedTo(tb->t->minimumSize());
    }

    if ( s.width() < 0 )
	s.setWidth( 0 );
    if ( s.height() < 0 )
	s.setHeight( 0 );

    return s;
}

void QToolLayout::invalidate()
{
    cached_width = 0;
    cached_height = 0;
}

int QToolLayout::layoutItems( const QRect &r, bool testonly )
{
    int n = dock->count();
    if ( n == 0 )
	return 0;

    Qt::Orientation o = dock->first()->t->orientation();

    QMainWindowPrivate::ToolBar *t = dock->first(), *t2 = 0;

    QList<QMainWindowPrivate::ToolBar> row;
    row.setAutoDelete( FALSE );
    int stretchs = 0;
    int e = 0;
    int pos = rect_pos( r, o, TRUE );
    int lineExtend = 0;
    while ( TRUE ) {
	QSize sh = t ? size_hint( t->t ) : QSize();
	int nx = e;
	if ( t && t->extraOffset != -1 && t->extraOffset > e )
	    nx = t->extraOffset;
	if ( nx + size_extend( sh, o ) > rect_extend( r, o ) )
	    nx = QMAX( e, rect_extend( r, o ) - size_extend( sh, o ) );
	if ( !t || t->nl || nx + size_extend( sh, o ) > rect_extend( r, o ) ) {
	    QValueList<QRect> rects;
	    int s = stretchs > 0 ? ( rect_extend( r, o ) - e + rect_pos( r, o ) ) / 
stretchs : 0;
	    int p = rect_pos( r, o );
	    QMainWindowPrivate::ToolBar *tmp = 0;
	    for ( t2 = row.first(); t2; t2= row.next() ) {
		QRect g;
		int oldPos = p;
		int space = 0;
		if ( t2->extraOffset > p ) {
		    space = t2->extraOffset - p;
		    p = t2->extraOffset;
		}
		if ( o == Qt::Horizontal ) {
		    int ext = size_hint( t2->t ).width();
		    if ( p + ext > r.width() && p == t2->extraOffset )
			p = QMAX( p - space, r.width() - ext );
		    if ( p > oldPos && tmp && ( tmp->t->isHorizontalStretchable() || fill 
) ) {
			QRect r = rects.last();
			int d = p - ( r.x() + r.width() );
			rects.last().setWidth( r.width() + d );
		    }
		    if ( t2->t->isHorizontalStretchable() || fill )
			ext += QMAX( 0, ( t2->t->isHorizontalStretchable() || fill ? s : 0 ) );
		    if ( p + ext > r.width() && ( t2->t->isHorizontalStretchable() || fill 
) )
			ext = r.width() - p;
		    g = QRect( p, pos, ext , lineExtend );
		} else {
		    int ext = size_hint( t2->t ).height();
		    if ( p + ext > r.y() + r.height() && p == t2->extraOffset )
			p = QMAX( p - space, ( r.y() + r.height() ) - ext );
		    if ( p > oldPos && tmp && ( tmp->t->isVerticalStretchable() || fill ) 
) {
			QRect r = rects.last();
			int d = p - ( r.y() + r.height() );
			rects.last().setHeight( r.height() + d );
		    }
		    if ( t2->t->isVerticalStretchable() || fill )
			ext += QMAX( 0, ( t2->t->isVerticalStretchable() || fill ? s : 0 ) );
		    if ( p + ext > r.y() + r.height() && ( t2->t->isVerticalStretchable() 
|| fill ) )
			ext = ( r.y() + r.height() ) - p;
		    g = QRect( pos, p, lineExtend, ext );
		}
		rects.append( g );
		p = rect_pos( g, o ) + rect_extend( g, o );
		tmp = t2;
	    }
	    if ( !testonly ) {
		QValueList<QRect>::Iterator it = rects.begin();
		for ( t2 = row.first(); t2; t2= row.next(), ++it ) {
		    QRect tr = *it;
		    if ( o == Qt::Horizontal ) {
			if ( tr.width() > r.width() )
			    tr.setWidth( r.width() );
		    } else {
			if ( tr.height() > r.height() )
			    tr.setHeight( r.height() );
		    }
		    t2->t->setGeometry( tr );
		}
	    }
	    stretchs = 0;
	    e = 0;
	    pos += lineExtend;
	    lineExtend = 0;
	    row.clear();
	    nx = 0;
	    if ( t && t->extraOffset != -1 && t->extraOffset > e )
		nx = t->extraOffset;
	}

	if ( !t )
	    break;

	e = nx + size_extend( sh, o );
	lineExtend = QMAX( lineExtend, size_extend( sh, o, TRUE ) );
	row.append( t );
	if ( ( o == Qt::Horizontal && t->t->isHorizontalStretchable() ||
	       o == Qt::Vertical && t->t->isVerticalStretchable() ) || fill )
	    ++stretchs;
	t = dock->next();
    }

    return pos - rect_pos( r, o, TRUE ) - spacing();
}


int QToolLayout::heightForWidth( int w ) const
{
    if ( cached_width != w ) {
	//Not all C++ compilers support "mutable" yet:
	QToolLayout * mthis = (QToolLayout*)this;
	mthis->cached_width = w;
	int h = mthis->layoutItems( QRect(0,0,w,0), TRUE );
	mthis->cached_hfw = h;
	return h;
    }
    return cached_hfw;
}

int QToolLayout::widthForHeight( int h ) const
{
    if ( cached_height != h ) {
	//Not all C++ compilers support "mutable" yet:
	QToolLayout * mthis = (QToolLayout*)this;
	mthis->cached_height = h;
	int w = mthis->layoutItems( QRect( 0, 0, 0, h ), TRUE );
	mthis->cached_wfh = w;
	return w;
    }
    return cached_wfh;
}

void QToolLayout::addItem( QLayoutItem * /*item*/ )
{
    //evil
    //    list.append( item );
}


class QToolLayoutIterator :public QGLayoutIterator
{
public:
    QToolLayoutIterator( QList<QLayoutItem> *l ) :idx(0), list(l)  {}
    uint count() const { return list ? list->count() : 0; }
    QLayoutItem *current() { return list && idx < (int)count() ? 
list->at(idx) : 0;  }
    QLayoutItem *next() { idx++; return current(); }
    QLayoutItem *takeCurrent() { return list ? list->take( idx ) : 0; }
private:
    int idx;
    QList<QLayoutItem> *list;
};

QLayoutIterator QToolLayout::iterator()
{
    //This is evil. Pretend you didn't see this.
    return QLayoutIterator( new QToolLayoutIterator( 0/*&list*/ ) );
}

void QToolLayout::setGeometry( const QRect &r )
{
    QLayout::setGeometry( r );
    layoutItems( r );
}

//************************************************************************************************
// --------------------------------- QMainWindowLayout 
-----------------------
//************************************************************************************************

class QMainWindowLayout : public QLayout
{
public:
    QMainWindowLayout( QLayout* parent = 0 );
    ~QMainWindowLayout() {}

    void addItem( QLayoutItem *item);
    void setLeftDock( QToolLayout *l );
    void setRightDock( QToolLayout *r );
    void setCentralWidget( QWidget *w );
    bool hasHeightForWidth() const { return FALSE; }
    QSize sizeHint() const;
    QSize minimumSize() const;
    QLayoutIterator iterator();
    QSizePolicy::ExpandData expanding() const { return 
QSizePolicy::BothDirections; }
    void invalidate() {}

protected:
    void setGeometry( const QRect &r ) {
	QLayout::setGeometry( r );
	layoutItems( r );
    }

private:
    int layoutItems( const QRect&, bool testonly = FALSE );
    int cached_height;
    int cached_wfh;
    QToolLayout *left, *right;
    QWidget *central;

};

QSize QMainWindowLayout::sizeHint() const
{
    if ( !left && !right && !central )
	return QSize( 0, 0 );

    int w = 0, h = 0;
    if ( left ) {
	w = QMAX( w, left->sizeHint().width() );
	h = QMAX( h, left->sizeHint().height() );
    }
    if ( right ) {
	w = QMAX( w, right->sizeHint().width() );
	h = QMAX( h, right->sizeHint().height() );
    }
    if ( central ) {
	w = QMAX( w, central->sizeHint().width() );
	h = QMAX( h, central->sizeHint().height() );
    }

    return QSize( w, h );
}

QSize QMainWindowLayout::minimumSize() const
{
    if ( !left && !right && !central )
	return QSize( 0, 0 );

    int w = 0, h = 0;
    if ( left ) {
	w = QMAX( w, left->minimumSize().width() );
	h = QMAX( h, left->minimumSize().height() );
    }
    if ( right ) {
	w = QMAX( w, right->minimumSize().width() );
	h = QMAX( h, right->minimumSize().height() );
    }
    if ( central ) {
	w = QMAX( w, QMAX( central->minimumSize().width(), 
central->minimumSizeHint().width() ) );
	h = QMAX( h, QMAX( central->minimumSize().height(), 
central->minimumSizeHint().height() ) );
    }

    return QSize( w, h );
}

QMainWindowLayout::QMainWindowLayout( QLayout* parent )
    : QLayout( parent ), left( 0 ), right( 0 ), central( 0 )
{
    cached_height = -1; cached_wfh = -1;
}

void QMainWindowLayout::setLeftDock( QToolLayout *l )
{
    left = l;
}

void QMainWindowLayout::setRightDock( QToolLayout *r )
{
    right = r;
}

void QMainWindowLayout::setCentralWidget( QWidget *w )
{
    central = w;
}

int QMainWindowLayout::layoutItems( const QRect &r, bool testonly )
{
    if ( !left && !central && !right )
	return 0;

    int wl = 0, wr = 0;
    if ( left )
	wl = left->widthForHeight( r.height() );
    if ( right )
	wr = right->widthForHeight( r.height() );
    int w = r.width() - wr - wl;
    if ( w < 0 )
	w = 0;

    if ( !testonly ) {
	QRect g( geometry() );
	if ( left )
	    left->setGeometry( QRect( g.x(), g.y(), wl, r.height() ) );
	if ( right )
	    right->setGeometry( QRect( g.x() + g.width() - wr, g.y(), wr, 
r.height() ) );
	if ( central )
	    central->setGeometry( g.x() + wl, g.y(), w, r.height() );
    }

    w = wl + wr;
    if ( central )
	w += central->minimumSize().width();
    return w;
}

void QMainWindowLayout::addItem( QLayoutItem * /*item*/ )
{
}


class QMainWindowLayoutIterator : public QGLayoutIterator
{
public:
    QMainWindowLayoutIterator( QList<QLayoutItem> *l ) :idx(0), list(l)  {}
    uint count() const { return list ? list->count() : 0; }
    QLayoutItem *current() { return list && idx < (int)count() ? 
list->at(idx) : 0;  }
    QLayoutItem *next() { idx++; return current(); }
    QLayoutItem *takeCurrent() { return list ? list->take( idx ) : 0; }
private:
    int idx;
    QList<QLayoutItem> *list;
};

QLayoutIterator QMainWindowLayout::iterator()
{
    //This is evil. Pretend you didn't see this.
    return QLayoutIterator( new QMainWindowLayoutIterator( 0/*&list*/ ) );
}

/*************************************************************************************************
--------------------------------- Minimized Dock -----------------------
************************************************************************************************/


class QHideToolTip : public QToolTip
{
public:
    QHideToolTip( QWidget *parent ) : QToolTip( parent ) {}

    void maybeTip( const QPoint &pos );
};


class QHideDock : public QWidget
{
public:
    QHideDock( QMainWindow *parent, QMainWindowPrivate *p ) : QWidget( 
parent ) {
	hide();
	setFixedHeight( style().toolBarHandleExtend() );
	d = p;
	pressedHandle = -1;
	pressed = FALSE;
	setMouseTracking( TRUE );
	win = parent;
	tip = new QHideToolTip( this );
    }
    ~QHideDock() { delete tip; }

protected:
    void paintEvent( QPaintEvent *e ) {
	if ( !d->hidden || d->hidden->isEmpty() )
	    return;
	QPainter p( this );
	p.setClipRegion( e->rect() );
	p.fillRect( e->rect(), colorGroup().brush( QColorGroup::Background ) );
	QMainWindowPrivate::ToolBar *tb;
	int x = 0;
	int i = 0;
	for ( tb = d->hidden->first(); tb; tb = d->hidden->next(), ++i ) {
	    if ( !tb->t->isVisible() )
		continue;
	    style().drawToolBarHandle( &p, QRect( x, 0, 30, 10 ), Qt::Vertical,
				       i == pressedHandle, colorGroup(), TRUE );
	    x += 30;
	}
    }

    void mousePressEvent( QMouseEvent *e ) {
	pressed = TRUE;
	if ( !d->hidden || d->hidden->isEmpty() )
	    return;
	mouseMoveEvent( e );

	if ( e->button() == RightButton && win->isDockMenuEnabled() ) {
	    if ( pressedHandle != -1 ) {
		QMainWindowPrivate::ToolBar *tb = d->hidden->at( pressedHandle );
		QPopupMenu menu( this );
		int left = menu.insertItem( QMainWindow::tr( "&Left" ) );
		menu.setItemEnabled( left, win->isDockEnabled( QMainWindow::Left )
				     && win->isDockEnabled( tb->t, QMainWindow::Left ) );
		int right = menu.insertItem( QMainWindow::tr( "&Right" ) );
		menu.setItemEnabled( left, win->isDockEnabled( QMainWindow::Right )
				     && win->isDockEnabled( tb->t, QMainWindow::Right ) );
		int top = menu.insertItem( QMainWindow::tr( "&Top" ) );
		menu.setItemEnabled( left, win->isDockEnabled( QMainWindow::Top )
				     && win->isDockEnabled( tb->t, QMainWindow::Top ) );
		int bottom = menu.insertItem( QMainWindow::tr( "&Bottom" ) );
		menu.setItemEnabled( left, win->isDockEnabled( QMainWindow::Bottom )
				     && win->isDockEnabled( tb->t, QMainWindow::Bottom ) );
		menu.insertSeparator();
		int hide = menu.insertItem( QMainWindow::tr( "R&estore" ) );
		QMainWindow::ToolBarDock dock = tb->oldDock;
		menu.setItemEnabled( left, win->isDockEnabled( dock )
				     && win->isDockEnabled( tb->t, dock ) );
		int res = menu.exec( e->globalPos() );
		pressed = FALSE;
		pressedHandle = -1;
		repaint( TRUE );
		if ( res == left )
		    win->moveToolBar( tb->t, QMainWindow::Left );
		else if ( res == right )
		    win->moveToolBar( tb->t, QMainWindow::Right );
		else if ( res == top )
		    win->moveToolBar( tb->t, QMainWindow::Top );
		else if ( res == bottom )
		    win->moveToolBar( tb->t, QMainWindow::Bottom );
		else if ( res == hide )
		    win->moveToolBar( tb->t, tb->oldDock, tb->nl, tb->oldIndex, 
tb->extraOffset );
		else
		    return;
		tb->t->show();
	    } else {
		win->rightMouseButtonMenu( e->globalPos() );
	    }
	}
    }

    void mouseMoveEvent( QMouseEvent *e ) {
	if ( !d->hidden || d->hidden->isEmpty() )
	    return;
	if ( !pressed )
	    return;
	QMainWindowPrivate::ToolBar *tb;
	int x = 0;
	int i = 0;
	if ( e->y() >= 0 && e->y() <= height() ) {
	    for ( tb = d->hidden->first(); tb; tb = d->hidden->next(), ++i ) {
		if ( !tb->t->isVisible() )
		    continue;
		if ( e->x() >= x && e->x() <= x + 30 ) {
		    int old = pressedHandle;
		    pressedHandle = i;
		    if ( pressedHandle != old )
			repaint( TRUE );
		    return;
		}
		x += 30;
	    }
	}
	int old = pressedHandle;
	pressedHandle = -1;
	if ( old != -1 )
	    repaint( TRUE );
    }

    void mouseReleaseEvent( QMouseEvent *e ) {
	pressed = FALSE;
	if ( pressedHandle == -1 )
	    return;
       	if ( !d->hidden || d->hidden->isEmpty() )
	    return;
	if ( e->button() == LeftButton ) {
	    if ( e->y() >= 0 && e->y() <= height() ) {
		QMainWindowPrivate::ToolBar *tb = d->hidden->at( pressedHandle );
		tb->t->show();
		win->moveToolBar( tb->t, tb->oldDock, tb->nl, tb->oldIndex, 
tb->extraOffset );
	    }
	}
	pressedHandle = -1;
	repaint( TRUE );
    }

private:
    QMainWindowPrivate *d;
    QMainWindow *win;
    int pressedHandle;
    bool pressed;
    QHideToolTip *tip;

    friend class QHideToolTip;

};

void QHideToolTip::maybeTip( const QPoint &pos )
{
    if ( !parentWidget() )
	return;
    QHideDock *dock = (QHideDock*)parentWidget();

    if ( !dock->d->hidden || dock->d->hidden->isEmpty() )
	return;
    QMainWindowPrivate::ToolBar *tb;
    int x = 0;
    int i = 0;
    for ( tb = dock->d->hidden->first(); tb; tb = dock->d->hidden->next(), 
++i ) {
	if ( !tb->t->isVisible() )
	    continue;
	if ( pos.x() >= x && pos.x() <= x + 30 ) {
	    if ( !tb->t->label().isEmpty() )
		tip( QRect( x, 0, 30, dock->height() ), tb->t->label() );
	    return;
	}
	x += 30;
    }
}


//************************************************************************************************
// ------------------------ static internal functions  
-----------------------
//************************************************************************************************

static QRect findRectInDockingArea( QMainWindowPrivate *d, 
QMainWindow::ToolBarDock dock,
				    const QPoint &pos, QToolBar *tb )
{
    Qt::Orientation o = dock == QMainWindow::Top || dock == 
QMainWindow::Bottom ?
			Qt::Horizontal : Qt::Vertical;
    bool swap = o != tb->orientation();
    QPoint offset( 0, 0 );
    if ( swap ) {
	if ( o == Qt::Horizontal )
	    offset = QPoint( tb->height() / 2, 0 );
	else
	    offset = QPoint( 0, tb->width() / 2 );
    }
    return QRect( pos - d->cursorOffset - offset,
		  swap ? QSize( tb->height(), tb->width() ) : tb->size() );
}

static void saveToolLayout( QMainWindowPrivate *d, QMainWindow::ToolBarDock 
dock, QToolBar *tb )
{
    QMainWindowPrivate::ToolBarDock * dl = 0;
    switch ( dock ) {
    case QMainWindow::Left:
	dl = d->left;
	break;
    case QMainWindow::Right:
	dl = d->right;
	break;
    case QMainWindow::Top:
	dl = d->top;
	break;
    case QMainWindow::Bottom:
	dl = d->bottom;
	break;
    case QMainWindow::Unmanaged:
	dl = d->unmanaged;
	break;
    case QMainWindow::Minimized:
	dl = d->hidden;
	break;
    case QMainWindow::TornOff:
	dl = d->tornOff;
	break;
    }

    if ( !dl )
	return;

    QMainWindowPrivate::ToolBarDock *dummy;
    QMainWindowPrivate::ToolBar *t = 0;
    t = d->findToolbar( tb, dummy );
    int i = dl->findRef( t );
    if ( i == -1 )
	return;
    if ( i + 1 < (int)dl->count() )
	dl->at( i + 1 )->nl = TRUE;
}

static void findNewToolbarPlace( QMainWindowPrivate *d, QToolBar *tb, 
QMainWindow::ToolBarDock dock,
				 const QRect &dockArea, QToolBar *&relative, int &ipos )
{
    relative = 0;
    Qt::Orientation o = dock == QMainWindow::Top || dock == 
QMainWindow::Bottom ?
			Qt::Horizontal : Qt::Vertical;
    QMainWindowPrivate::ToolBarDock * dl = 0;
    int dy = 0;
    switch ( dock ) {
    case QMainWindow::Left:
	dl = d->left;
	if ( d->lLeft )
	    dy = d->lLeft->geometry().y() + ( d->top && !d->top->isEmpty() ? 8 : 0 
);
	if ( d->lLeft && d->lastTopHeight != -1 && !dy )
	    dy = d->lastTopHeight;
	else
	    d->lastTopHeight = dy;
	break;
    case QMainWindow::Right:
	dl = d->right;
	if ( d->lRight )
	    dy = d->lRight->geometry().y() + ( d->top && !d->top->isEmpty() ? 8 : 0 
);
	if ( d->lRight && d->lastTopHeight != -1 && !dy )
	    dy = d->lastTopHeight;
	else
	    d->lastTopHeight = dy;
	break;
    case QMainWindow::Top:
	dl = d->top;
	dy = -9;
	break;
    case QMainWindow::Bottom:
	dl = d->bottom;
	dy = -9;
	break;
    case QMainWindow::Unmanaged:
	dl = d->unmanaged;
	break;
    case QMainWindow::Minimized:
	dl = d->hidden;
	break;
    case QMainWindow::TornOff:
	dl = d->tornOff;
	break;
    }

    QList<QMainWindowPrivate::ToolBar> bars;
    QMap<QRect, QList<QMainWindowPrivate::ToolBar> > rows;
    QMainWindowPrivate::ToolBar *first = 0, *last = 0;

    QMainWindowPrivate::ToolBar *t = dl->first();
    int oldPos = dl->first() ? tb_pos( dl->first()->t, o, TRUE ) : 0;
    bool makeNextNl = FALSE;
    bool hadNl = FALSE;
    while ( t ) {
	if ( !t->t->isVisibleTo( t->t->parentWidget() ) ) {
	    t = dl->next();
	    continue;
	}
	if ( t->t == tb )
	    hadNl = t->nl;
	else
	    last = t;
	if ( !first && t->t != tb )
	    first = t;
	int pos = tb_pos( t->t, o, TRUE );

	if ( pos != oldPos ) {
	    QRect r;
	    if ( o == Qt::Horizontal ) {
		r = QRect( dockArea.x(), QMAX( oldPos, dockArea.y() ),
			   dockArea.width(),
			   bars.last() ? bars.last()->t->height() : pos - oldPos - dockArea.y() 
);
	    } else {
		r = QRect( QMAX( oldPos, dockArea.x() ), dockArea.y(),
			   bars.last() ? bars.last()->t->width() : pos - oldPos - dockArea.x(),
			   dockArea.height() );
	    }
	    rows[ r ] = bars;
	    bars.clear();
	    bars.append( t );
	    if ( t->t == tb ) {
		makeNextNl = TRUE;
		t->nl = FALSE;
	    } else {
		makeNextNl = FALSE;
		t->nl = TRUE;
	    }
	    oldPos = pos;
	} else {
	    if ( !makeNextNl ) {
		t->nl = FALSE;
	    } else {
		t->nl = TRUE;
	    }
	    makeNextNl = FALSE;
	    bars.append( t );
	}
	t = dl->next();
    }
    if ( !bars.isEmpty() ) {
	    QRect r;
	    if ( o == Qt::Horizontal ) {
		r = QRect( dockArea.x(), bars.last()->t->y(), dockArea.width(), 
bars.last()->t->height() );
	    } else {
		r = QRect( bars.last()->t->x(), dockArea.y(), bars.last()->t->width(), 
dockArea.height() );
	    }
	    rows[ r ] = bars;
	    bars.clear();
    }

    QMainWindowPrivate::ToolBarDock *dummy;
    t = d->findToolbar( tb, dummy );
    QMainWindowPrivate::ToolBar *me = t;
    t->extraOffset = rect_pos( d->oldPosRect, o ) + rect_pos( dockArea, o ) 
- dy;
    if ( rows.isEmpty() ) {

	relative = 0;
    } else {
	QMap<QRect, QList<QMainWindowPrivate::ToolBar> >::Iterator it = 
rows.begin();
#ifdef QMAINWINDOW_DEBUG
	qDebug( "compare (%d, %d, %d, %d) ...",
		d->oldPosRect.x(), d->oldPosRect.y(),
		d->oldPosRect.width(), d->oldPosRect.height() );
#endif
	for ( ; it != rows.end(); ++it ) {
#ifdef QMAINWINDOW_DEBUG
	    qDebug( "  ... width (%d, %d, %d, %d)",
		    it.key().x(), it.key().y(),
		    it.key().width(), it.key().height() );
#endif
	    if ( it.key().intersects( d->oldPosRect ) ) {
		QRect ir = it.key().intersect( d->oldPosRect );
		if ( rect_extend( ir, o, TRUE ) < 3 )
		    continue;
		int div = 4;
		int mul = 3;
		if ( d->opaque ) {
		    mul = 2;
		    div = 5;
		}
		bool contains = it.key().contains( d->oldPosRect );
		if ( !contains && rect_extend( d->oldPosRect, o, TRUE ) > rect_extend( 
it.key(), o, TRUE ) &&
		     rect_pos( d->oldPosRect, o, TRUE ) < rect_pos( it.key(), o, TRUE ) &&
		     rect_pos( d->oldPosRect, o, TRUE ) + rect_extend( d->oldPosRect, o, 
TRUE ) >
		     rect_pos( it.key(), o, TRUE ) + rect_extend( it.key(), o, TRUE ) )
		    contains = TRUE;
		if ( !contains && rect_extend( ir, o, TRUE ) < ( mul * rect_extend( 
it.key(), o, TRUE ) ) / div ) {
		    if ( rect_pos( ir, o, TRUE ) <= rect_pos( it.key(), o, TRUE ) ) {
#ifdef QMAINWINDOW_DEBUG
			qDebug( "above" );
#endif
			relative = ( *it ).first()->t;
			ipos = QMainWindowPrivate::Above;
			QMainWindowPrivate::ToolBar *l = ( *it ).first();
			if ( relative == tb && ( *it ).next() ) {
			    relative = ( *it ).current()->t;
			} else if ( relative == tb ) {
			    ipos = QMainWindowPrivate::SameIndex;
			    l->nl = TRUE;
			}
		    } else {
#ifdef QMAINWINDOW_DEBUG
			qDebug( "below" );
#endif
			relative = ( *it ).first()->t;
			ipos = QMainWindowPrivate::Below;
			QMainWindowPrivate::ToolBar *l = ( *it ).first();
			if ( relative == tb && ( *it ).next() ) {
			    relative = ( *it ).current()->t;
			} else if ( relative == tb ) {
			    ipos = QMainWindowPrivate::SameIndex;
			    l->nl = TRUE;
			}
		    }
		} else {
#ifdef QMAINWINDOW_DEBUG
		    qDebug( "insinde" );
#endif
		    bars = *it;
		    t = bars.first();
		    QMainWindowPrivate::ToolBar *b = 0, *last = 0;
		    bool hasMyself = FALSE;
		    while ( t ) {
			if ( t->t == tb ) {
			    hasMyself = TRUE;
			    t = bars.next();
			    continue;
			}
			if ( tb_pos( t->t, o ) + tb_extend( t->t, o ) / 2 < rect_pos( 
d->oldPosRect, o ) ) {
			    b = t;
			    t = bars.next();
			    continue;
			}
			last = t;
			break;
		    }

		    if ( !b && hadNl && me )
			me->nl = TRUE;

		    if ( !b && last ) {
			relative = last->t;
			ipos = QMainWindowPrivate::Before;
#ifdef QMAINWINDOW_DEBUG
			qDebug( "...before" );
#endif
		    } else if ( b ) {
			relative = b->t;
			ipos = QMainWindowPrivate::After;
#ifdef QMAINWINDOW_DEBUG
			qDebug( "...after" );
#endif
		    }
		    if ( !relative && hasMyself ) {
#ifdef QMAINWINDOW_DEBUG
			qDebug( "...no relative and have myself => self index" );
#endif
			relative = tb;
			ipos = QMainWindowPrivate::SameIndex;
		    } else if ( !relative ) {
#ifdef QMAINWINDOW_DEBUG
			qDebug( "AUTSCH!!!!!!!!!!" );
#endif
		    }
		}
		return;
	    }
	}
    }
    if ( rect_pos( d->oldPosRect, o, TRUE ) < rect_pos( dockArea, o, TRUE ) 
&& first ) {
	relative = first->t;
	ipos = QMainWindowPrivate::Above;
    } else if ( rect_pos( d->oldPosRect, o, TRUE ) + rect_extend( 
d->oldPosRect, o, TRUE ) >
		rect_pos( dockArea, o, TRUE ) + rect_extend( d->oldPosRect, o, TRUE ) && 
last ) {
	relative = last->t;
	ipos = QMainWindowPrivate::Below;
    } else {
	relative = 0;
	ipos = QMainWindowPrivate::Before;
    }
}






// NOT REVISED
/*! \class QMainWindow qmainwindow.h

  \brief The QMainWindow class provides a typical application window,
  with a menu bar, some tool bars and a status bar.

  \ingroup application

  In addition, you need the large central widget, which you supply and
  tell QMainWindow about using setCentralWidget(), and perhaps a few
  tool bars, which you can add using addToolBar().

  The central widget is not touched by QMainWindow.  QMainWindow
  manages its geometry, and that is all.  For example, the
  application/application.cpp example (an editor) sets a QMultiLineEdit
  to be the central widget.

  QMainWindow automatically detects the creation of a menu bar or
  status bar if you specify the QMainWindow as parent, or you can use
  the provided menuBar() and statusBar() functions.  menuBar() and
  statusBar() create a suitable widget if one doesn't exist, and
  updates the window's layout to make space.

  QMainWindow also provides a QToolTipGroup connected to the status
  bar.  toolTipGroup() provides access to the QToolTipGroup, but there
  is no way to set the tool tip group.

  The QMainWindow allows by default toolbars in all docking areas.
  You can use setDockEnabled() to enable and disable docking areas
  for toolbars. Currently, only \c Top, \c Left, \c Right, \c Bottom
  and \c Minimized are meaningful.

  Several functions let you change the appearance of a QMainWindow
  globally: <ul>
  <li> setRightJustification() determines whether QMainWindow
  should ensure that the toolbars fill the available space
  (see also QToolBar::setHorizontalStretchable() and 
QToolBar::setVerticalStretchable()),
  <li>  setUsesBigPixmaps() determines whether QToolButton (and other
  classes) should draw small or large pixmaps (see QIconSet for more
  about that),
  <li> setUsesTextLabel() determines whether the toolbar buttons (and
  other classes), should display a textlabel in addition to pixmaps (see
  QToolButton for more about that).
  </ul>

  Toolbars can be dragged by the user into each enabled docking area
  and inside each docking area to change the order of the toolbars
  there. This feature can be enabled and disabled using 
setToolBarsMovable().
  By default this feature is enabled. If the \c Minimized dock is enabled 
the user
  can hide(minimize)/show(restore) a toolbar with a click on the toolbar 
handle. The handles of
  all minimized toolbars are drawn below the menu bar in one row, and if the 
user
  moves the mouse cursor onto such a handle, the label of the toolbar
  is displayed in a tool tip (see QToolBar::label()). So if you enable the 
Minimized dock,
  you should specify a meaningful label for each toolbar.

  Normally toolbars are moved transparently (this means while the user
  drags one, a rectangle is drawn on the screen). With setOpaqueMoving()
  it's possible to switch betrween opaque and transparent moving
  of toolbars.

  The main window's menubar is static (on the top) by default. If you want a 
movable
  menubar, create a QMenuBar as stretchable widget inside its
  own movable toolbar and restrict this toolbar to only live within the
  Top or Bottom dock:
  \code
  QToolBar *tb = new QToolBar( this );
  addToolBar( tb, tr( "Menubar" ), Top, FALSE );
  QMenuBar *mb = new QMenuBar( tb );
  mb->setFrameStyle( QFrame::NoFrame );
  tb->setStretchableWidget( mb );
  setDockEnabled( tb, Left, FALSE );
  setDockEnabled( tb, Right, FALSE );
  \endcode

  An application with multiple toolbars can choose to save the current
  toolbar layout in order to restore it in the next session. To do so,
  use getLocation() on each toolbar, store the data and restore the
  layout using moveToolBar() on each toolbar again. When restoring,
  ensure to move the toolbars in exactly the same order in which you
  got the information.

  For multidocument interfaces (MDI), use a QWorkspace as central
  widget.

  <img src=qmainwindow-m.png> <img src=qmainwindow-w.png>

  \sa QToolBar QStatusBar QMenuBar QToolTipGroup QDialog
*/

/*!
  \enum QMainWindow::ToolBarDock

  Each toolbar can be in one of the following positions:
  <ul>
    <li>\c Top - above the central widget, below the menubar.
    <li>\c Bottom - below the central widget, above the status bar.
    <li>\c Left - to the left of the central widget.
    <li>\c Right - to the left of the central widget.
    <li>\c Minimized - the toolbar is not shown - all handles of minimized 
toolbars
    are drawn in one row below the menu bar.
  </ul>

  Other values are also defined for future expansion.
*/

/*!  Constructs an empty main window. */

QMainWindow::QMainWindow( QWidget * parent, const char * name, WFlags f )
    : QWidget( parent, name, f )
{
    d = new QMainWindowPrivate;
    d->hideDock = new QHideDock( this, d );
    d->opaque = FALSE;
    installEventFilter( this );
}


/*! Destructs the object and frees any allocated resources.

*/

QMainWindow::~QMainWindow()
{
    delete d;
}


/*!  Sets this main window to use the menu bar \a newMenuBar.

  The old menu bar, if there was any, is deleted along with its
  contents.

  \sa menuBar()
*/

void QMainWindow::setMenuBar( QMenuBar * newMenuBar )
{
    if ( !newMenuBar )
	return;
    if ( d->mb )
	delete d->mb;
    d->mb = newMenuBar;
    d->mb->installEventFilter( this );
    triggerLayout();
}


/*!  Returns the menu bar for this window.  If there isn't any,
  menuBar() creates an empty menu bar on the fly.

  \sa statusBar()
*/

QMenuBar * QMainWindow::menuBar() const
{
    if ( d->mb )
	return d->mb;

    QObjectList * l
	= ((QObject*)this)->queryList( "QMenuBar", 0, FALSE, FALSE );
    QMenuBar * b;
    if ( l && l->count() ) {
	b = (QMenuBar *)l->first();
    } else {
	b = new QMenuBar( (QMainWindow *)this, "automatic menu bar" );
	b->show();
    }
    delete l;
    d->mb = b;
    d->mb->installEventFilter( this );
    ((QMainWindow *)this)->triggerLayout();
    return b;
}


/*!  Sets this main window to use the status bar \a newStatusBar.

  The old status bar, if there was any, is deleted along with its
  contents.

  Note that \a newStatusBar must be a child of this main window, and
  that it is not automatically displayed.  If you call this function
  after show(), you probably also need to call \a
  newStatusBar->show().

  \sa setMenuBar() statusBar()
*/

void QMainWindow::setStatusBar( QStatusBar * newStatusBar )
{
    if ( !newStatusBar || newStatusBar == d->sb )
	return;
    if ( d->sb )
	delete d->sb;
    d->sb = newStatusBar;
    // ### this code can cause unnecessary creation of a tool tip group
    connect( toolTipGroup(), SIGNAL(showTip(const QString&)),
	     d->sb, SLOT(message(const QString&)) );
    connect( toolTipGroup(), SIGNAL(removeTip()),
	     d->sb, SLOT(clear()) );
    d->sb->installEventFilter( this );
    triggerLayout();
}


/*!  Returns the status bar for this window.  If there isn't any,
  statusBar() creates an empty status bar on the fly, and if necessary
  a tool tip group too.

  \sa  menuBar() toolTipGroup()
*/

QStatusBar * QMainWindow::statusBar() const
{
    if ( d->sb )
	return d->sb;

    QObjectList * l
	= ((QObject*)this)->queryList( "QStatusBar", 0, FALSE, FALSE );
    QStatusBar * s;
    if ( l && l->count() ) {
	s = (QStatusBar *)l->first();
    } else {
	s = new QStatusBar( (QMainWindow *)this, "automatic status bar" );
	s->show();
    }
    delete l;
    ((QMainWindow *)this)->setStatusBar( s );
    return s;
}


/*!  Sets this main window to use the tool tip group \a newToolTipGroup.

  The old tool tip group, if there was any, is deleted along with its
  contents.  All the tool tips connected to it lose the ability to
  display the group texts.

  \sa menuBar() toolTipGroup()
*/

void QMainWindow::setToolTipGroup( QToolTipGroup * newToolTipGroup )
{
    if ( !newToolTipGroup || newToolTipGroup == d->ttg )
	return;
    if ( d->ttg )
	delete d->ttg;
    d->ttg = newToolTipGroup;

    connect( toolTipGroup(), SIGNAL(showTip(const QString&)),
	     statusBar(), SLOT(message(const QString&)) );
    connect( toolTipGroup(), SIGNAL(removeTip()),
	     statusBar(), SLOT(clear()) );
    //###    triggerLayout();
}


/*!  Returns the tool tip group for this window.  If there isn't any,
  toolTipGroup() creates an empty tool tip group on the fly.

  \sa menuBar() statusBar()
*/

QToolTipGroup * QMainWindow::toolTipGroup() const
{
    if ( d->ttg )
	return d->ttg;

    QToolTipGroup * t = new QToolTipGroup( (QMainWindow*)this,
					   "automatic tool tip group" );
    ((QMainWindowPrivate*)d)->ttg = t;
    //###    ((QMainWindow *)this)->triggerLayout();
    return t;
}


/*!  Sets \a dock to be available if \a enable is TRUE, and not
  available if \a enable is FALSE.

  The user can drag a toolbar to any enabled dock.
*/

void QMainWindow::setDockEnabled( ToolBarDock dock, bool enable )
{
    if ( enable ) {
	switch ( dock ) {
	case Top:
	    if ( !d->top )
		d->top = new QMainWindowPrivate::ToolBarDock();
	    break;
	case Left:
	    if ( !d->left )
		d->left = new QMainWindowPrivate::ToolBarDock();
	    break;
	case Right:
	    if ( !d->right )
		d->right = new QMainWindowPrivate::ToolBarDock();
	    break;
	case Bottom:
	    if ( !d->bottom )
		d->bottom = new QMainWindowPrivate::ToolBarDock();
	    break;
	case TornOff:
	    if ( !d->tornOff )
		d->tornOff = new QMainWindowPrivate::ToolBarDock();
	    break;
	case Unmanaged:
	    if ( !d->unmanaged )
		d->unmanaged = new QMainWindowPrivate::ToolBarDock();
	    break;
	case Minimized:
	    if ( !d->hidden )
		d->hidden = new QMainWindowPrivate::ToolBarDock();
	    break;
	}
	d->dockable[ (int)dock ] = TRUE;
    } else {
	d->dockable[ (int)dock ] = FALSE;
    }
}


/*!  Returns TRUE if \a dock is enabled, or FALSE if it is not.

  \sa setDockEnabled()
*/

bool QMainWindow::isDockEnabled( ToolBarDock dock ) const
{
    switch ( dock ) {
    case Top:
	return d->dockable[ (int)dock ];
    case Left:
	return d->dockable[ (int)dock ];
    case Right:
	return d->dockable[ (int)dock ];
    case Bottom:
	return  d->dockable[ (int)dock ];
    case TornOff:
	return d->dockable[ (int)dock ];
    case Unmanaged:
	return d->dockable[ (int)dock ];
    case Minimized:
	return d->dockable[ (int)dock ];
    }
    return FALSE; // for illegal values of dock
}

/*!
  Sets \a dock to be available for the toolbar \a tb if \a enable is TRUE, 
and not
  available if \a enable is FALSE.

  The user can drag the toolbar to any enabled dock.
*/


void QMainWindow::setDockEnabled( QToolBar *tb, ToolBarDock dock, bool 
enable )
{
    QMainWindowPrivate::ToolBarDock *dummy;
    QMainWindowPrivate::ToolBar *t = d->findToolbar( tb, dummy );
    if ( !t )
	return;

    if ( enable ) {
	if ( t->disabledDocks.contains( (int)dock ) )
	    t->disabledDocks.remove( (int)dock );
    } else {
	if ( !t->disabledDocks.contains( (int)dock ) )
	    t->disabledDocks.append( (int)dock );
    }
}

/*!
  Returns TRUE if \a dock is enabled for the toolbar \a tb , or FALSE if it 
is not.

  \sa setDockEnabled()
*/

bool QMainWindow::isDockEnabled( QToolBar *tb, ToolBarDock dock ) const
{
    QMainWindowPrivate::ToolBarDock *dummy;
    QMainWindowPrivate::ToolBar *t = d->findToolbar( tb, dummy );
    if ( !t )
	return FALSE;

    return !(bool)t->disabledDocks.contains( (int)dock );
}



/*!  Adds \a toolBar to this the end of \a edge and makes it start a
new line of tool bars if \a nl is TRUE.

If \a toolBar is already managed by some main window, it is first
removed from that window.
*/

void QMainWindow::addToolBar( QToolBar * toolBar,
			      ToolBarDock edge, bool newLine )
{
    if ( !toolBar )
	return;

    if ( toolBar->mw ) {
	toolBar->mw->removeToolBar( toolBar );
	toolBar->mw = this;
    }

    setDockEnabled( edge, TRUE );
    setDockEnabled( toolBar, edge, TRUE );

    QMainWindowPrivate::ToolBarDock * dl = 0;
    if ( edge == Top ) {
	dl = d->top;
	toolBar->setOrientation( QToolBar::Horizontal );
	toolBar->installEventFilter( this );
    } else if ( edge == Left ) {
	dl = d->left;
	toolBar->setOrientation( QToolBar::Vertical );
	toolBar->installEventFilter( this );
    } else if ( edge == Bottom ) {
	dl = d->bottom;
	toolBar->setOrientation( QToolBar::Horizontal );
	toolBar->installEventFilter( this );
    } else if ( edge == Right ) {
	dl = d->right;
	toolBar->setOrientation( QToolBar::Vertical );
	toolBar->installEventFilter( this );
    } else if ( edge == TornOff ) {
	dl = d->tornOff;
    } else if ( edge == Unmanaged ) {
	dl = d->unmanaged;
    } else if ( edge == Minimized ) {
	dl = d->hidden;
    }

    if ( !dl )
	return;

    QMainWindowPrivate::ToolBar *tb = new QMainWindowPrivate::ToolBar( 
toolBar, newLine );
    dl->append( tb );
    if ( tb && edge != Minimized ) {
	tb->oldDock = edge;
	tb->oldIndex = dl->findRef( tb );
    }
    triggerLayout();
}


/*!  Adds \a toolBar to this the end of \a edge, labelling it \a label
and makes it start a new line of tool bars if \a newLine is TRUE.

If \a toolBar is already managed by some main window, it is first
removed from that window.
*/

void QMainWindow::addToolBar( QToolBar * toolBar, const QString &label,
			      ToolBarDock edge, bool newLine )
{
    if ( toolBar ) {
	toolBar->setLabel( label );
	addToolBar( toolBar, edge, newLine );
    }
}

/*!
  Moves \a toolBar before the tollbar \a relative if \a after is FALSE, or 
after
  \a relative if \a after is TRUE.

  If \a toolBar is already managed by some main window, it is moved from
  that window to this.
*/

void QMainWindow::moveToolBar( QToolBar *toolBar, ToolBarDock edge, QToolBar 
*relative, int ipos )
{
    if ( !toolBar )
	return;

    // if the toolbar is just moved a bit (offset change), but the order in 
the dock doesn't change,
    // then don't do the hard work
    if ( relative == toolBar || ipos == QMainWindowPrivate::SameIndex ) {
#ifdef QMAINWINDOW_DEBUG
	QMainWindowPrivate::ToolBarDock *dummy;
	QMainWindowPrivate::ToolBar *t = d->findToolbar( toolBar, dummy );
	qDebug( "move to same index, offset: %d", t ? t->extraOffset : -2 );
#endif
	triggerLayout();
	emit toolBarPositionChanged( toolBar );
	return;
    }

    bool nl = FALSE;
    QValueList<int> dd;
    QMainWindowPrivate::ToolBarDock *oldDock;
    QMainWindowPrivate::ToolBar *tb = d->findToolbar( toolBar, oldDock );

    // if the toolbar is moved here from a different mainwindow, remove it 
from the old one
    if ( toolBar->mw && toolBar->mw != this ) {
	if ( tb ) {
	    nl = tb->nl;
	    dd = tb->disabledDocks;
	}
	toolBar->mw->removeToolBar( toolBar );
    }

    // Now take the toolbar from the dock
    QMainWindowPrivate::ToolBar * ct;
    ct = d->takeToolBarFromDock( toolBar, edge == Minimized );

    Qt::Orientation o;
    if ( edge == QMainWindow::Top || edge == QMainWindow::Bottom )
	o = Qt::Horizontal;
    else
	o = Qt::Vertical;

    bool recalc = FALSE;
    // if the toolbar is valid
    if ( ct ) {
	// enable the dock where it will be moved to
	setDockEnabled( edge, TRUE );
	setDockEnabled( toolBar, edge, TRUE );

	// find the data struct of the dock
	QMainWindowPrivate::ToolBarDock * dl = 0;
	if ( edge == Top ) {
	    dl = d->top;
	    toolBar->setOrientation( QToolBar::Horizontal );
	    toolBar->installEventFilter( this );
	} else if ( edge == Left ) {
	    dl = d->left;
	    toolBar->setOrientation( QToolBar::Vertical );
	    toolBar->installEventFilter( this );
	} else if ( edge == Bottom ) {
	    dl = d->bottom;
	    toolBar->setOrientation( QToolBar::Horizontal );
	    toolBar->installEventFilter( this );
	} else if ( edge == Right ) {
	    dl = d->right;
	    toolBar->setOrientation( QToolBar::Vertical );
	    toolBar->installEventFilter( this );
	} else if ( edge == TornOff ) {
	    dl = d->tornOff;
	} else if ( edge == Unmanaged ) {
	    dl = d->unmanaged;
	} else if ( edge == Minimized ) {
	    dl = d->hidden;
	}

	// if the dock couldn't be dound
	if ( !dl ) {
	    if ( edge != Minimized ) {
		ct->oldDock = edge;
		ct->oldIndex = dl->findRef( ct );
	    } else
		recalc = TRUE;
	    delete ct;
	    return;
	}

	if ( oldDock != d->hidden ) {
	    ct->hiddenBefore = 0;
	    ct->hiddenAfter = 0;
	}

	// if the toolbar is restored from the minimized dock,
	// try to find exactly the place and move it there
	if ( oldDock == d->hidden ) {
	    QMainWindowPrivate::ToolBar *t = dl->first();
	    int i = 0;
	    bool found = FALSE;
	    for ( ; t; t = dl->next(), ++i ) {
		if ( t->hiddenBefore == ct ) {
#ifdef QMAINWINDOW_DEBUG
		    qDebug( "insert minimized toolbar before %s", t->t->label().latin1() 
);
#endif
		    dl->insert( i, ct );
		    if ( !ct->nl && t->nl )
			ct->nl = TRUE;
		    t->nl = FALSE;
		    t->hiddenBefore = 0;
		    found = TRUE;
		    break;
		}
		if ( t->hiddenAfter == ct ) {
#ifdef QMAINWINDOW_DEBUG
		    qDebug( "insert minimized toolbar after %s", t->t->label().latin1() );
#endif
		    dl->insert( i + 1, ct );
		    if ( !t->nl && ct->nl )
			t->nl = TRUE;
		    ct->nl = FALSE;
		    t->hiddenAfter = 0;
		    found = TRUE;
		    break;
		}
	    }
	    if ( found ) {
		triggerLayout();
		// update, so that the line below the menubar may be drawn/earsed
		update();
		emit toolBarPositionChanged( toolBar );
		return;
	    }
	}


	if ( !relative ) { // no relative toolbar, so just append it
	    dl->append( ct );
	} else {
	    QMainWindowPrivate::ToolBar *t = dl->first();
	    int i = 0;
	    // find index for moving the toolbar before or after the relative one
	    if ( ipos != QMainWindowPrivate::Above && ipos != 
QMainWindowPrivate::Below ) {
		for ( ; t; t = dl->next(), ++i ) {
		    if ( t->t == relative )
			break;
		}
		if ( ipos == QMainWindowPrivate::After )
		    ++i;
	    } else if ( ipos == QMainWindowPrivate::Below ) {
		// find the index for moving it below relative
		int ry = 0;
		bool doIt = FALSE;
		for ( ; t; t = dl->next(), ++i ) {
		    if ( t->t == relative ) {
			ry = tb_pos( t->t, o, TRUE );
			doIt = TRUE;
		    }
		    if ( doIt && tb_pos( t->t, o, TRUE ) > ry ) {
			break;
		    }
		}
	    } else if ( ipos == QMainWindowPrivate::Above ) {
		// find index for moving it above relative
		int ry = 0;
		bool doIt = FALSE;
		t = dl->last();
		i = dl->count();
		for ( ; t; t = dl->prev(), --i ) {
		    if ( t->t == relative ) {
			ry = tb_pos( t->t, o, TRUE );
			doIt = TRUE;
		    }
		    if ( doIt && tb_pos( t->t, o, TRUE ) < ry ) {
			break;
		    }
		}
	    }

	    // sanity chek
	    if ( i > (int)dl->count() )
		i = dl->count();

	    // and finally move the toolbar to the calculated index
	    dl->insert( i, ct );

	    // do some new-line corrections
	    if ( oldDock != d->hidden ) {
		bool after = ipos == QMainWindowPrivate::After;
		if ( ipos == QMainWindowPrivate::Before &&
		     (int)dl->count() > i + 1 && dl->at( i + 1 )->nl ) {
		    dl->at( i + 1 )->nl = FALSE;
		    dl->at( i )->nl = TRUE;
		}
		if ( after && ct->nl ) {
		    ct->nl = FALSE;
		}
		if ( ipos == QMainWindowPrivate::Below ) {
		    dl->at( i )->nl = TRUE;
		    if ( (int)dl->count() > i + 1 ) {
			dl->at( i + 1 )->nl = TRUE;
		    }
		}
		if ( ipos == QMainWindowPrivate::Above ) {
		    dl->at( i )->nl = TRUE;
		    if ( (int)dl->count() > i + 1 ) {
			dl->at( i + 1 )->nl = TRUE;
		    }
		}
	    }
	}

	if ( edge != Minimized ) {
	    ct->oldDock = edge;
	    ct->oldIndex = dl->findRef( ct );
	} else
	    recalc = TRUE;
    } else {
	addToolBar( toolBar, edge, nl );
	QMainWindowPrivate::ToolBarDock *dummy;
	QMainWindowPrivate::ToolBar *tb = d->findToolbar( toolBar, dummy );
	if ( tb )
	    tb->disabledDocks = dd;
	if ( tb && edge != Minimized ) {
	    tb->oldDock = edge;
	    tb->oldIndex = 0;
	}
    }

    triggerLayout();
    // update, so that the line below the menubar may be drawn/earsed
    update();
    emit toolBarPositionChanged( toolBar );
}

/*!
  Moves \a toolBar to this the end of \a edge.

  If \a toolBar is already managed by some main window, it is moved from
  that window to this.
*/

void QMainWindow::moveToolBar( QToolBar * toolBar, ToolBarDock edge )
{
    moveToolBar( toolBar, edge, (QToolBar*)0, TRUE );
}

/*!
  Moves \a toolBar to the position \a index of \a edge.

  If \a toolBar is already managed by some main window, it is moved from
  that window to this.
*/

void QMainWindow::moveToolBar( QToolBar * toolBar, ToolBarDock edge, bool 
nl, int index, int extraOffset )
{
    QMainWindowPrivate::ToolBarDock * dl = 0;
    switch ( edge ) {
    case Left:
	dl = d->left;
	break;
    case Right:
	dl = d->right;
	break;
    case Top:
	dl = d->top;
	break;
    case Bottom:
	dl = d->bottom;
	break;
    case Unmanaged:
	dl = d->unmanaged;
	break;
    case Minimized:
	dl = d->hidden;
	break;
    case TornOff:
	dl = d->tornOff;
	break;
    }

    QMainWindowPrivate::ToolBarDock *dummy;
    QMainWindowPrivate::ToolBar *tt = d->findToolbar( toolBar, dummy );
    tt->extraOffset = extraOffset;
    if ( nl && tt )
	tt->nl = nl;
    if ( !dl ) {
	moveToolBar( toolBar, edge, (QToolBar*)0, QMainWindowPrivate::After );
    } else {
	QMainWindowPrivate::ToolBar *tb = 0;
	bool after = FALSE;
	if ( index >= (int)dl->count() ) {
	    tb = 0;
	} else {
	    if ( index > 0 && !nl ) {
		after = TRUE;
		tb = dl->at( index - 1 );
	    } else {
		tb = dl->at( index );
	    }
	}

	if ( !tb )
	    moveToolBar( toolBar, edge, (QToolBar*)0, QMainWindowPrivate::After );
	else
	    moveToolBar( toolBar, edge, tb->t,
			 after ? QMainWindowPrivate::After : QMainWindowPrivate::Before );
    }
}

/*!
  Removes \a toolBar from this main window, if \a toolBar is
  non-null and known by this main window.
*/

void QMainWindow::removeToolBar( QToolBar * toolBar )
{
    if ( !toolBar )
	return;
    QMainWindowPrivate::ToolBar * ct;
    ct = d->takeToolBarFromDock( toolBar );
    if ( ct ) {
	toolBar->mw = 0;
	delete ct;
	triggerLayout();
    }
}

/*!  Sets up the geometry management of this window.  Called
  automatically when needed, so you should never need to call this.
*/

void QMainWindow::setUpLayout()
{
    //### Must rewrite!
    if ( !d->mb ) {
	// slightly evil hack here.  reconsider this after 2.0
	QObjectList * l
	    = ((QObject*)this)->queryList( "QMenuBar", 0, FALSE, FALSE );
	if ( l && l->count() )
	    d->mb = menuBar();
	delete l;
    }
    if ( !d->sb ) {
	// as above.
	QObjectList * l
	    = ((QObject*)this)->queryList( "QStatusBar", 0, FALSE, FALSE );
	if ( l && l->count() )
	    d->sb = statusBar();
	delete l;
    }

    delete d->tll;
    d->tll = new QBoxLayout( this, QBoxLayout::Down );

    if ( d->mb && d->mb->isVisibleTo( this ) ) {
	d->tll->setMenuBar( d->mb );
    }

    d->hideDock->setFixedHeight( style().toolBarHandleExtend() );

    if ( d->hidden && !d->hidden->isEmpty() ) {
	if ( style() == WindowsStyle )
	    d->tll->addSpacing( 2 );
	int visibles = 0;
	d->hideDock->show();
	QMainWindowPrivate::ToolBar *tb;
	for ( tb = d->hidden->first(); tb; tb = d->hidden->next() ) {
	    if ( tb->t->isVisibleTo( this ) )
		visibles++;
	    tb->t->resize( 0, 0 );
	    tb->t->move( -tb->t->width() - 2, -tb->t->height() - 2 );
	    d->hideDock->raise();
	    if ( d->mb )
		d->mb->raise();
	}
	if ( !visibles ) {
	    d->hideDock->hide();
	} else {
	    d->hideDock->repaint( TRUE );
	    update();
	}
    } else {
	d->hideDock->hide();
    }
    d->tll->addWidget( d->hideDock );

    if ( d->top && !d->top->isEmpty() && style() == WindowsStyle )
	d->tll->addSpacing( d->movable ? 1  : 2 );
    d->lTop = new QToolLayout( d->tll, d->top, QBoxLayout::Down, d->justify 
);

    QMainWindowLayout *mwl = new QMainWindowLayout( d->tll );

    d->tll->setStretchFactor( mwl, 100 );
    d->lLeft = new QToolLayout( mwl, d->left, QBoxLayout::LeftToRight, 
d->justify );
    mwl->setLeftDock( d->lLeft );

    if ( centralWidget() )
	mwl->setCentralWidget( centralWidget() );
    d->lRight = new QToolLayout( mwl, d->right, QBoxLayout::LeftToRight, 
d->justify );
    mwl->setRightDock( d->lRight );

    d->lBottom = new QToolLayout( d->tll, d->bottom, QBoxLayout::Down, 
d->justify );

    if ( d->sb && d->sb->isVisibleTo( this ) ) {
	d->tll->addWidget( d->sb, 0 );
	// make the sb stay on top of tool bars if there isn't enough space
	d->sb->raise();
    }
}


/*!  \reimp */
void QMainWindow::show()
{
    if ( !d->tll)
	setUpLayout();
    QWidget::show();
}


/*!  \reimp */
QSize QMainWindow::sizeHint() const
{
    if ( !d->tll ) {
	QMainWindow* that = (QMainWindow*) this;
	that->setUpLayout();
    }
    return d->tll->totalSizeHint();
}

/*!  \reimp */
QSize QMainWindow::minimumSizeHint() const
{
    if ( !d->tll ) {
	QMainWindow* that = (QMainWindow*) this;
	that->setUpLayout();
    }
    return d->tll->totalMinimumSize();
}

/*!  Sets the central widget for this window to \a w.  The central
  widget is the one around which the toolbars etc. are arranged.
*/

void QMainWindow::setCentralWidget( QWidget * w )
{
    if ( d->mc )
	d->mc->removeEventFilter( this );
    d->mc = w;
    if ( d->mc ) {
	d->mc->show();
	d->mc->installEventFilter( this );
    }
    triggerLayout();
}


/*!  Returns a pointer to the main child of this main widget.  The
  main child is the big widget around which the tool bars are
  arranged.

  \sa setCentralWidget()
*/

QWidget * QMainWindow::centralWidget() const
{
    return d->mc;
}


/*! \reimp */

void QMainWindow::paintEvent( QPaintEvent * )
{
    if ( style() == WindowsStyle && d->mb &&
	 ( ( d->top && !d->top->isEmpty() ) || ( d->hidden && !d->hidden->isEmpty() 
) ) ) {
	QPainter p( this );
	int y = d->mb->height() + 1;
	style().drawSeparator( &p, 0, y, width(), y, colorGroup() );
    }
}


/*!
  \reimp
*/

bool QMainWindow::eventFilter( QObject* o, QEvent *e )
{
    if ( d->dockMenu && e->type() == QEvent::MouseButtonPress &&
	 o == this && !d->inMovement &&
	 ( (QMouseEvent*)e )->button() == RightButton ) {
	QMouseEvent *me = (QMouseEvent*)e;
	rightMouseButtonMenu( me->globalPos() );
	return TRUE;
    } else if ( ( e->type() == QEvent::MouseButtonPress ||
	   e->type() == QEvent::MouseMove ||
	   e->type() == QEvent::MouseButtonRelease )
	 && o && o->inherits( "QToolBar" )  ) {
	QMouseEvent *me = (QMouseEvent*)e;
	if ( d->movable && ( ( me->button() & LeftButton || me->state() & 
LeftButton ) ||
	     ( ( me->button() & RightButton ) && d->dockMenu ) ) ) {
	    moveToolBar( (QToolBar *)o, me );
	    return TRUE;
	}
    } else if ( e->type() == QEvent::LayoutHint && o->inherits( "QToolBar" ) 
) {
	if ( isVisible() && ( (QToolBar*)o )->isVisible() )
	    QTimer::singleShot( 0, (QToolBar*)o, SLOT( updateArrowStuff() ) );
    }
    return QWidget::eventFilter( o, e );
}


/*!
  Monitors events to ensure layout is updated.
*/
void QMainWindow::resizeEvent( QResizeEvent* )
{
    //    setUpLayout(); // #####
}

/*!
  Monitors events to ensure layout is updated.
*/
void QMainWindow::childEvent( QChildEvent* e)
{
    if ( e->type() == QEvent::ChildRemoved ) {
	if ( e->child() == 0 ||
	     !e->child()->isWidgetType() ||
	     ((QWidget*)e->child())->testWFlags( WType_TopLevel ) ) {
	    // nothing
	} else if ( e->child() == d->sb ) {
	    d->sb = 0;
	    triggerLayout();
	} else if ( e->child() == d->mb ) {
	    d->mb = 0;
	    triggerLayout();
	} else if ( e->child() == d->mc ) {
	    d->mc = 0;
	    triggerLayout();
	} else if ( e->child()->isWidgetType() ) {
	    removeToolBar( (QToolBar *)(e->child()) );
	    triggerLayout();
	}
    }
}

/*!\reimp
*/

bool QMainWindow::event( QEvent * e ) //### remove 3.0
{
    if ( e->type() == QEvent::ChildRemoved && ( (QChildEvent*)e )->child() 
== d->mc ) {
	d->mc->removeEventFilter( this );
	d->mc = 0;
    }

    return QWidget::event( e );
}


/*!  Returns the state last set by setUsesBigPixmaps().  The initial
  state is FALSE.
  \sa setUsesBigPixmaps();
*/

bool QMainWindow::usesBigPixmaps() const
{
    return d->ubp;
}


/*!  Sets tool buttons in this main windows to use big pixmaps if \a
  enable is TRUE, and small pixmaps if \a enable is FALSE.

  The default is FALSE.

  Tool buttons and other interested widgets are responsible for
  reading the correct state on startup, and for connecting to this
  widget's pixmapSizeChanged() signal.

  \sa QToolButton::setUsesBigPixmap()
*/

void QMainWindow::setUsesBigPixmaps( bool enable )
{
    if ( d->ubp == enable )
	return;

    d->ubp = enable;
    emit pixmapSizeChanged( enable );
}

/*!  Returns the state last set by setUsesTextLabel().  The initial
  state is FALSE.
  \sa setUsesTextLabel();
*/

bool QMainWindow::usesTextLabel() const
{
    return d->utl;
}


/*!  Sets tool buttons in this main windows to use text labels if \a
  enable is TRUE, and no text labels otherwise.

  The default is FALSE.

  Tool buttons and other interested widgets are responsible for
  reading the correct state on startup, and for connecting to this
  widget's usesTextLabelChanged() signal.

  \sa QToolButton::setUsesTextLabel()
*/

void QMainWindow::setUsesTextLabel( bool enable )
{
    if ( d->utl == enable )
	return;

    d->utl = enable;
    emit usesTextLabelChanged( enable );
}


/*! \fn void QMainWindow::pixmapSizeChanged( bool )

  This signal is called whenever the setUsesBigPixmaps() is called
  with a value which is different from the current setting.  All
  relevant widgets must connect to this signal.
*/

/*! \fn void QMainWindow::usesTextLabelChanged( bool )

  This signal is called whenever the setUsesTextLabel() is called
  with a value which is different from the current setting.  All
  relevant widgets must connect to this signal.
*/

/*!
  \fn void QMainWindow::startMovingToolBar( QToolBar *toolbar )

  This signal is emitted when the \a toolbar starts moving because
  the user started dragging it.
*/

/*!
  \fn void QMainWindow::endMovingToolBar( QToolBar *toolbar )

  This signal is emitted if the \a toolbar has been moved by
  the user and he/she released the mouse button now, so he/she
  stopped the moving.
*/

/*!
  \fn void QMainWindow::toolBarPositionChanged( QToolBar *toolbar )

  This signal is emitted when the \a toolbar has changed its position.
  This means it has been moved to another dock or inside the dock.

  \sa getLocation()
*/

/*!
  Sets this main window to right-justifies its toolbars if \a enable
  is TRUE. If enable is FALSE, only stretchable toolbars are expanded,
  while non-stretchable toolbars get just the space they need. Given
  that most toolbars are not stretchable, this usually results in a
  ragged right edge.

  The default is FALSE.

  \sa rightJustification(), QToolBar::setVerticalStretchable(), 
QToolBar::setHorizontalStretchable()
*/

void QMainWindow::setRightJustification( bool enable )
{
    if ( enable == d->justify )
	return;
    d->justify = enable;
    triggerLayout( TRUE );
}


/*!  Returns TRUE if this main windows right-justifies its toolbars, and
  FALSE if it uses a ragged right edge.

  The default is to use a ragged right edge.

  ("Right edge" sometimes means "bottom edge".)

  \sa setRightJustification()
*/

bool QMainWindow::rightJustification() const
{
    return d->justify;
}


void QMainWindow::triggerLayout( bool deleteLayout )
{
    if ( !deleteLayout ) {
	if ( d->hidden && !d->hidden->isEmpty() ) {
	    int visibles = 0;
	    d->hideDock->show();
	    QMainWindowPrivate::ToolBar *tb;
	    for ( tb = d->hidden->first(); tb; tb = d->hidden->next() ) {
		if ( tb->t->isVisibleTo( this ) )
		    visibles++;
		tb->t->resize( 0, 0 );
		tb->t->move( -tb->t->width() - 2, -tb->t->height() - 2 );
		d->hideDock->raise();
		if ( d->mb )
		    d->mb->raise();
	    }
	    if ( !visibles ) {
		d->hideDock->hide();
	    } else {
		d->hideDock->repaint( TRUE );
		update();
	    }
	} else {
	    d->hideDock->hide();
	}
	// for some strange reason...
	if ( d->lLeft )
	    d->lLeft->activate();
	if ( d->lRight )
	    d->lRight->activate();
    } else {
	delete d->tll;
	d->tll = 0;
	if ( isVisibleTo(0) )
	    setUpLayout();
    }
    QApplication::postEvent( this, new QEvent( QEvent::LayoutHint) );
}

/*!
  \internal
  Finds the docking area for the toolbar \a tb. \a pos has to be the 
position of the mouse
  inside the QMainWindow. \a rect is set to the docking area into which the 
toolbar should
  be moved if the position of the mouse is \a pos. This method returns the 
identifier of
  the docking area, which is described by \a rect.

  If the mouse is not in any docking area, Unmanaged is returned as docking 
area.
*/

QMainWindow::ToolBarDock QMainWindow::findDockArea( const QPoint &pos, QRect 
&rect,
						    QToolBar *tb, QRect *r2 )
{
    // calculate some values for docking areas
    int left, right, top, bottom;
    left = right = top = bottom = 30;
    int h1 = d->mb ? d->mb->height() : 0;
    if ( d->mb && style() == WindowsStyle )
	h1++;
    h1 += d->hideDock->isVisible() ? d->hideDock->height() + 1 : 0;
    int h2 = d->sb ? d->sb->height() : 0;
    bool hasTop, hasBottom, hasLeft, hasRight;
    hasTop = hasBottom = hasLeft= hasRight = FALSE;
    if ( d->mc ) {
	if ( d->mc->x() > 0 ) {
	    hasLeft = TRUE;
	    left = d->mc->x();
	}
	if ( d->mc->x() + d->mc->width() < width() ) {
	    hasRight = TRUE;
	    right = width() - ( d->mc->x() + d->mc->width() );
	}
	if ( d->mc->y() > h1 ) {
	    hasTop = TRUE;
	    top = d->mc->y() - h1;
	}
	if ( d->mc->y() + d->mc->height() < height() - h2  ) {
	    hasBottom = TRUE;
	    bottom = height() - ( d->mc->y() + d->mc->height() ) - h2;
	}
    }

    // some checks...
    if ( left < 20 ) {
	hasLeft = FALSE;
	left = 10;
    }
    if ( right < 20 ) {
	hasRight = FALSE;
	right = 10;
    }
    if ( top < 20 ) {
	hasTop = FALSE;
	top = 10;
    }
    if ( bottom < 20 ) {
	hasBottom = FALSE;
	bottom = 10;
    }

    // calculate the docking areas
    QRect leftArea( -10, h1, left + 20, height() - h1 - h2 );
    QRect topArea( -10, h1 - 10, width() + 20, top + 20 );
    QRect rightArea( width() - right - 10, h1, right + 20, height() - h1 - 
h2 );
    QRect bottomArea( -10, height() - bottom - h2 - 10, width() + 20, bottom 
+ 20 );
    QRect leftTop = leftArea.intersect( topArea );
    QRect leftBottom = leftArea.intersect( bottomArea );
    QRect rightTop = rightArea.intersect( topArea );
    QRect rightBottom = rightArea.intersect( bottomArea );

    // now polish the docking areas a bit... (subtract interstections)
    if ( hasTop )
	leftArea = QRegion( leftArea ).subtract( leftTop ).boundingRect();
    if ( hasBottom )
	leftArea = QRegion( leftArea ).subtract( leftBottom ).boundingRect();
    if ( hasTop )
	rightArea = QRegion( rightArea ).subtract( rightTop ).boundingRect();
    if ( hasBottom )
	rightArea = QRegion( rightArea ).subtract( rightBottom ).boundingRect();

    // find the docking area into which the toolbar should/could be moved

    // if the mouse is in a rect which belongs to two docking areas 
(intersection),
    // find the one with higher priority (that's depending on the original 
position)
    if ( leftTop.contains( pos ) ) {
	if ( tb->orientation() == Vertical && !hasTop ) {
	    rect = findRectInDockingArea( d, Left, pos, tb );
	    if ( r2 )
		*r2 = leftArea;
	    return Left;
	}
	rect = findRectInDockingArea( d, Top, pos, tb );
	if ( r2 )
	    *r2 = topArea;
	return Top;
    }
    if ( leftBottom.contains( pos ) ) {
	if ( tb->orientation() == Vertical && !hasBottom ) {
	    rect = findRectInDockingArea( d, Left, pos, tb );
	    if ( r2 )
		*r2 = leftArea;
	    return Left;
	}
	rect = findRectInDockingArea( d, Bottom, pos, tb );
	if ( r2 )
	    *r2 = bottomArea;
	return Bottom;
    }
    if ( rightTop.contains( pos ) ) {
	if ( tb->orientation() == Vertical && !hasTop ) {
	    rect = findRectInDockingArea( d, Right, pos, tb );
	    if ( r2 )
		*r2 = rightArea;
	    return Right;
	}
	rect = findRectInDockingArea( d, Top, pos, tb );
	if ( r2 )
	    *r2 = topArea;
	return Top;
    }
    if ( rightBottom.contains( pos ) ) {
	if ( tb->orientation() == Vertical && !hasBottom ) {
	    rect = findRectInDockingArea( d, Right, pos, tb );
	    if ( r2 )
		*r2 = rightArea;
	    return Right;
	}
	rect = findRectInDockingArea( d, Bottom, pos, tb );
	if ( r2 )
	    *r2 = bottomArea;
	return Bottom;
    }

    // if the mouse is not in an intersection, it's easy....
    if ( leftArea.contains( pos ) ) {
	rect = findRectInDockingArea( d, Left, pos, tb );
	if ( r2 )
	    *r2 = leftArea;
	return Left;
    }
    if ( topArea.contains( pos ) ) {
	rect = findRectInDockingArea( d, Top, pos, tb );
	if ( r2 )
	    *r2 = topArea;
	return Top;
    }
    if ( rightArea.contains( pos ) ) {
	rect = findRectInDockingArea( d, Right, pos, tb );
	if ( r2 )
	    *r2 = rightArea;
	return Right;
    }
    if ( bottomArea.contains( pos ) ) {
	rect = findRectInDockingArea( d, Bottom, pos, tb );
	if ( r2 )
	    *r2 = bottomArea;
	return Bottom;
    }

    rect = QRect( pos - d->cursorOffset, tb->size() );

    // mouse pos outside of any docking area
    return Unmanaged;
}


/*!
  Handles mouse event \a e on behalf of tool bar \a t and does all
  the funky docking.
*/

void QMainWindow::moveToolBar( QToolBar* t , QMouseEvent * e )
{
    if ( e->type() == QEvent::MouseButtonPress && !d->inMovement ) {
	if ( t->orientation() == Horizontal ) {
	    if ( e->x() > 10 )
		return;
	}

	if ( t->orientation() == Vertical ) {
	    if ( e->y() > 10 )
		return;
	}

	if ( ( e->button() & RightButton ) ) {
	    if ( !isDockMenuEnabled() )
		return;
	    emit startMovingToolBar( t );
	    d->inMovement = TRUE;
	    QPopupMenu menu( this );
	    int left = menu.insertItem( tr( "&Left" ) );
	    menu.setItemEnabled( left, isDockEnabled( Left ) && isDockEnabled( t, 
Left ) );
	    int right = menu.insertItem( tr( "&Right" ) );
	    menu.setItemEnabled( left, isDockEnabled( Right ) && isDockEnabled( t, 
Right ) );
	    int top = menu.insertItem( tr( "&Top" ) );
	    menu.setItemEnabled( left, isDockEnabled( Top ) && isDockEnabled( t, 
Top ) );
	    int bottom = menu.insertItem( tr( "&Bottom" ) );
	    menu.setItemEnabled( left, isDockEnabled( Bottom ) && isDockEnabled( t, 
Bottom ) );
	    menu.insertSeparator();
	    int hide = menu.insertItem( tr( "&Hide" ) );
	    menu.setItemEnabled( left, isDockEnabled( Minimized ) && isDockEnabled( 
t, Minimized ) );
	    int res = menu.exec( e->globalPos() );
	    if ( res == left )
		moveToolBar( t, Left );
	    else if ( res == right )
		moveToolBar( t, Right );
	    else if ( res == top )
		moveToolBar( t, Top );
	    else if ( res == bottom )
		moveToolBar( t, Bottom );
	    else if ( res == hide )
		moveToolBar( t,  Minimized );
	    emit endMovingToolBar( t );
	    d->inMovement = FALSE;
	    return;
	}
	if ( ( e->button() & MidButton ) ) {
	    return;
	}
	emit startMovingToolBar( t );
	d->inMovement = TRUE;

	// don't allow repaints of the central widget as this may be a problem for 
our rects
	if ( d->mc && !d->opaque ) {
	    if ( d->mc->inherits( "QScrollView" ) )
		( (QScrollView*)d->mc )->viewport()->setUpdatesEnabled( FALSE );
	    else
		d->mc->setUpdatesEnabled( FALSE );
	}

	// create the painter for our rects
	if ( !d->opaque ) {
	    bool unclipped = testWFlags( WPaintUnclipped );
	    setWFlags( WPaintUnclipped );
	    d->rectPainter = new QPainter;
	    d->rectPainter->begin( this );
	    if ( !unclipped )
		clearWFlags( WPaintUnclipped );
	    d->rectPainter->setPen( QPen( color0, 2 ) );
	    d->rectPainter->setRasterOp( NotROP );
	}

	// init some stuff
	QPoint pos = mapFromGlobal( e->globalPos() );
	QRect r;
	QMainWindow::ToolBarDock dock = findDockArea( pos, r, t );
	r = QRect( t->pos(), t->size() );
	d->oldPosRect = r;
	d->origPosRect = r;
	d->oldPosRectValid = FALSE;
	d->pos = mapFromGlobal( e->globalPos() );
	d->movedEnough = FALSE;
	d->origDock = d->oldDock = dock;
	d->cursorOffset = t->mapFromGlobal( e->globalPos() );

	return;
    } else if ( e->type() == QEvent::MouseButtonRelease && d->inMovement ) {
	if ( ( e->button() & RightButton ) ) {
	    return;
	}
	if ( ( e->button() & MidButton ) ) {
	    return;
	}

	// finally really move the toolbar, if the mouse was moved...
	if ( d->movedEnough ) {
	    if ( t->cursor().shape() == ForbiddenCursor )
		t->setCursor( d->oldCursor );
	    if ( !d->opaque ) {
		ToolBarDock dock = d->oldDock;
		if ( dock != Unmanaged && isDockEnabled( dock ) &&
		     isDockEnabled( t, dock ) ) {
		    if ( d->oldPosRectValid )
			d->rectPainter->drawRect( d->oldPosRect );
		    int ipos;
		    QToolBar *relative;
		    QPoint pos = mapFromGlobal( e->globalPos() );
		    QRect r, r2;
		    findDockArea( pos, r, t, &r2 );
		    if ( dock != d->origDock ) {
			saveToolLayout( d, d->origDock, t );
		    }
		    findNewToolbarPlace( d, t, dock, r2, relative, ipos );
		    moveToolBar( t, dock, relative, ipos );
		} else {
		    QPoint op = t->pos();
		    QRect r = d->oldPosRect;
		    if ( r.width() > r.height() && t->width() < t->height() ||
			 r.width() < r.height() && t->width() > t->height() ) {
			d->rectPainter->drawRect( r );
			r.setRect( e->x(), e->y(), t->width(), t->height() );
			d->rectPainter->drawRect( r );
		    }
		    int a = r.x() - op.x();
		    int b = r.y() - op.y();
		    int ap = a / 20;
		    int bp = b / 20;
		    QTime time;
		    time.start();
		    int i = 0;
		    while ( TRUE ) {
			if ( time.elapsed() > 10 ) {
			    ++i;
			    d->rectPainter->drawRect( r );
			    r.moveBy( -ap, -bp );
			    d->rectPainter->drawRect( r );
			    qApp->processEvents();
			    if ( i == 20 )
				break;
			    time.start();
			}
		    }
		    d->oldPosRect = r;
		    if ( d->oldPosRectValid )
			d->rectPainter->drawRect( d->oldPosRect );
		}
	    }
	} else { // ... or hide it if it was only a click
	    if ( isDockEnabled( Minimized ) && isDockEnabled( t, Minimized ) )
		moveToolBar( t, Minimized );
	}

	// delete the rect painter
	if ( d->rectPainter ) {
	    d->rectPainter->end();
	    delete d->rectPainter;
	    d->rectPainter = 0;
	}

	if ( !d->opaque ) {
	    if ( d->hideDock && d->hideDock->isVisible() )
		d->hideDock->repaint( TRUE );
	}

	// allow repaints in central widget again
	if ( d->mc && !d->opaque ) {
	    if ( d->mc->inherits( "QScrollView" ) )
		( (QScrollView*)d->mc )->viewport()->setUpdatesEnabled( TRUE );
	    else
		d->mc->setUpdatesEnabled( TRUE );
	}

	emit endMovingToolBar( t );
	d->inMovement = FALSE;

	return;
    } else if ( e->type() == QMouseEvent::MouseMove ) {
	if ( ( e->state() & LeftButton ) != LeftButton || !d->inMovement )
	    return;
    }

    // find out if the mouse had been moved yet...
    QPoint p( e->globalPos() );
    QPoint pos = mapFromGlobal( p );
    if ( !d->movedEnough && pos != d->pos ) {
    	d->movedEnough = TRUE;
    }

    // if no mouse movement yet, don't do anything
    if ( !d->movedEnough )
	return;

    // find the dock, rect, etc. for the current mouse pos
    d->pos = pos;
    QRect r;
    ToolBarDock dock = findDockArea( pos, r, t );

    // draw the new rect where the toolbar would be moved
    if ( d->rectPainter && !d->opaque ) {
	if ( d->oldPosRectValid && d->oldPosRect != r )
	    d->rectPainter->drawRect( d->oldPosRect );
	if ( dock == Unmanaged || !isDockEnabled( dock ) ||
	     !isDockEnabled( t, dock ) ) {
	    if ( t->cursor().shape() != ForbiddenCursor ) {
		d->oldCursor = t->cursor();
		t->setCursor( ForbiddenCursor );
	    }
	} else {
	    if ( t->cursor().shape() != d->oldCursor.shape() ) {
		t->setCursor( d->oldCursor );
	    }
	}
	if ( !d->oldPosRectValid || d->oldPosRect != r )
	    d->rectPainter->drawRect( r );
    } else if ( d->opaque ) {
	if ( dock == Unmanaged ) {
	    dock = d->origDock;
	} else {
	    int ipos;
	    QToolBar *relative;
	    QRect r, r2;
	    findDockArea( pos, r, t, &r2 );
	    if ( dock != d->origDock ) {
		saveToolLayout( d, d->origDock, t );
	    }
	    findNewToolbarPlace( d, t, dock, r2, relative, ipos );
	    moveToolBar( t, dock, relative, ipos );
	}
    }
    d->oldPosRect = r;
    d->oldPosRectValid = TRUE;
    d->oldDock = dock;
}

/*!
    Enters What's This? question mode and returns immediately.

    This is the same as QWhatsThis::enterWhatsThisMode(), but as a slot of 
of a
    main window object. This way it can be easily used for popup menus
    as in the code fragment:

  \code
    QPopupMenu * help = new QPopupMenu( this );
    help->insertItem( "What's &This", this , SLOT(whatsThis()), 
SHIFT+Key_F1);
  \endcode

  \sa QWhatsThis::enterWhatsThisMode()

*/
void QMainWindow::whatsThis()
{
    QWhatsThis::enterWhatsThisMode();
}


/*!
  \reimp
*/

void QMainWindow::styleChange( QStyle& old )
{
    QWidget::styleChange( old );
}

/*!
  Finds and gives back the \a dock and the \a index there of the toolbar \a 
tb. \a dock is
  set to the dock of the mainwindow in which \a tb is and \a index is set to 
the
  position of the toolbar in this dock. If the toolbar has a new line, \a nl 
is set to TRUE,
  else to FALSE.

  This method returns TRUE if the information could be found out, otherwise 
FALSE
  (e.g. because the toolbar \a tb was not found in this mainwindow)
*/

bool QMainWindow::getLocation( QToolBar *tb, ToolBarDock &dock, int &index, 
bool &nl, int &extraOffset ) const
{
    if ( !tb )
	return FALSE;

    QMainWindowPrivate::ToolBarDock *td;
    QMainWindowPrivate::ToolBar *t = d->findToolbar( tb, td );

    if ( !td || !t )
	return FALSE;

    if ( td == d->left )
	dock = Left;
    else if ( td == d->right )
	dock = Right;
    else if ( td == d->top )
	dock = Top;
    else if ( td == d->bottom )
	dock = Bottom;
    else if ( td == d->unmanaged )
	dock = Unmanaged;
    else if ( td == d->tornOff )
	dock = TornOff;
    else if ( td == d->hidden )
	dock = Minimized;

    index = td->findRef( t );
    nl = t->nl;
    extraOffset = t->extraOffset;

    return TRUE;
}

/*!
  Returns a list of all toolbars which are placed in \a dock.
*/

QList<QToolBar> QMainWindow::toolBars( ToolBarDock dock ) const
{
    QList<QToolBar> lst;
    QMainWindowPrivate::ToolBarDock *tdock = 0;
    switch ( dock ) {
    case Left:
	tdock = d->left;
	break;
    case Right:
	tdock = d->right;
	break;
    case Top:
	tdock = d->top;
	break;
    case Bottom:
	tdock = d->bottom;
	break;
    case Unmanaged:
	tdock = d->unmanaged;
	break;
    case Minimized:
	tdock = d->hidden;
	break;
    case TornOff:
	tdock = d->tornOff;
	break;
    }

    if ( tdock ) {
	QMainWindowPrivate::ToolBar *t = tdock->first();
	for ( ; t; t = tdock->next() )
	    lst.append( t->t );
    }

    return lst;
}

/*!
  Sets the toolbars to be movable if \a enable is TRUE, or static
  otherwise.

  Movable toolbars can be dragged around between and within the
  different toolbar docks by the user. By default toolbars are moved
  transparent, but this setting can be changed by setOpaqueMoving().

  The default is TRUE.

  \sa setDockEnabled(), toolbarsMovable(), setOpaqueMoving()
*/

void QMainWindow::setToolBarsMovable( bool enable )
{
    d->movable = enable;
    QObjectList *l = queryList( "QToolBar" );
    if ( l ) {
	for ( QObject *o = l->first(); o; o = l->next() )
	    ( (QToolBar*)o )->update();
    }
    delete l;
    triggerLayout( TRUE );
}

/*!
  Returns whether or not the toolbars of this main window are movable.

  \sa setToolbarsMovable()
*/

bool QMainWindow::toolBarsMovable() const
{
    return d->movable;
}

/*!
  If you set \a b to TRUE, the use can move the
  toolbars opaque, otherwise this is done transparent. This
  setting makes only sense, if toolBarsMovable() is set to TRUE.

  \sa setToolbarsMovable()
*/

void QMainWindow::setOpaqueMoving( bool b )
{
    d->opaque = b;
}

/*!
  Returns whether the toolbars of the mainwindow can
  be moved opaque or transparent.

  \sa setOpaqueMoving()
*/

bool QMainWindow::opaqueMoving() const
{
    return d->opaque;
}

/*!
  As toolbars can be freely moved inside docks, it's possible to line them
  up nicely with this method to get rid of all the unused space. If \a 
keepNewLines
  is TRUE, all toolbars stay in the line in which they are, else they are 
packed
  together as compact as possible.

  The method only works if movable() returns TRUE.
*/

void QMainWindow::lineUpToolBars( bool keepNewLines )
{
    if ( !d->movable )
	return;

    QMainWindowPrivate::ToolBarDock* docks[] = {
	d->left, d->right, d->top, d->bottom, d->unmanaged, d->tornOff, d->hidden
    };

    QMainWindowPrivate::ToolBarDock *l = 0;

    for ( unsigned int i = 0; i < 7; ++i ) {
	l = docks[ i ];
	if ( !l || l->isEmpty() )
	    continue;
	QMainWindowPrivate::ToolBar *t = 0;
	for ( t = l->first(); t; t = l->next() ) {
	    t->extraOffset = -1;
	    if ( !keepNewLines )
		t->nl = FALSE;
	}
    }

    triggerLayout();
}

/*!
  \internal
*/

void QMainWindow::rightMouseButtonMenu( const QPoint &p )
{
    if ( !d->movable || !d->dockMenu )
	return;

    QMainWindowPrivate::ToolBarDock* docks[] = {
	d->left, d->right, d->top, d->bottom, d->unmanaged, d->tornOff, d->hidden
    };

    QMainWindowPrivate::ToolBarDock *l = 0;
    QIntDict<QMainWindowPrivate::ToolBar> ids;
    bool sep;
    QPopupMenu m;
    m.setCheckable( TRUE );
    for ( unsigned int i = 0; i < 7; ++i ) {
	sep = FALSE;
	l = docks[ i ];
	if ( !l || l->isEmpty() )
	    continue;
	QMainWindowPrivate::ToolBar *t = 0;
	for ( t = l->first(); t; t = l->next() ) {
	    if ( !t->t->label().isEmpty() ) {
		int id = m.insertItem( t->t->label() );
		ids.insert( id, t );
		if ( l != d->hidden )
		    m.setItemChecked( id, TRUE );
		sep = TRUE;
	    }
	}
	if ( sep )
	    m.insertSeparator();
    }
    int lineUp1 = m.insertItem( tr( "Line Up Toolbars (compact)" ) );
    int lineUp2 = m.insertItem( tr( "Line Up Toolbars (normal)" ) );

    int id = m.exec( p );
    if ( id == lineUp1 ) {
	lineUpToolBars( FALSE );
    } else if ( id == lineUp2 ) {
	lineUpToolBars( TRUE );
    } else if ( ids.find( id ) ) {
	QMainWindowPrivate::ToolBar *t = ids[ id ];
	if ( m.isItemChecked( id ) ) {
	    if ( isDockEnabled( Minimized ) && isDockEnabled( t->t, Minimized ) )
		moveToolBar( t->t, Minimized );
	} else {
	    t->t->show();
	    moveToolBar( t->t, t->oldDock, t->nl, t->oldIndex, t->extraOffset );
	}
    }
}

/*!
  Returns TRUE, if rightclicking on an empty space on a toolbar dock
  or rightclicking on a toolbar handle opens a popup menu which allows
  lining up toolbars and hiding/showing toolbars.

  \sa setDockEnabled(), lineUpToolBars()
*/

bool QMainWindow::isDockMenuEnabled() const
{
    return d->dockMenu;
}

/*!
  When passing TRUE for \a b here, rightclicking on an empty space on a 
toolbar dock
  or rightclicking on a toolbar handle opens a popup menu which allows 
lining up toolbars
  and hiding/showing toolbars.

  \sa lineUpToolBars(), isDockMenuEnabled()
*/

void QMainWindow::setDockMenuEnabled( bool b )
{
    d->dockMenu = b;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]