2011-04-27 10:05:43 +00:00
/****************************************************************************
* *
2013-01-02 11:13:29 +00:00
* * Copyright ( C ) 2013 Digia Plc and / or its subsidiary ( - ies ) .
2012-09-19 12:28:29 +00:00
* * Contact : http : //www.qt-project.org/legal
2011-04-27 10:05:43 +00:00
* *
* * This file is part of the test suite of the Qt Toolkit .
* *
* * $ QT_BEGIN_LICENSE : LGPL $
2012-09-19 12:28:29 +00:00
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
* * a written agreement between you and Digia . For licensing terms and
* * conditions see http : //qt.digia.com/licensing. For further information
* * use the contact form at http : //qt.digia.com/contact-us.
* *
2011-04-27 10:05:43 +00:00
* * GNU Lesser General Public License Usage
2012-09-19 12:28:29 +00:00
* * Alternatively , this file may be used under the terms of the GNU Lesser
* * General Public License version 2.1 as published by the Free Software
* * Foundation and appearing in the file LICENSE . LGPL included in the
* * packaging of this file . Please review the following information to
* * ensure the GNU Lesser General Public License version 2.1 requirements
* * will be met : http : //www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
2011-04-27 10:05:43 +00:00
* *
2012-09-19 12:28:29 +00:00
* * In addition , as a special exception , Digia gives you certain additional
* * rights . These rights are described in the Digia Qt LGPL Exception
2011-04-27 10:05:43 +00:00
* * version 1.1 , included in the file LGPL_EXCEPTION . txt in this package .
* *
2011-05-24 09:34:08 +00:00
* * GNU General Public License Usage
2012-09-19 12:28:29 +00:00
* * Alternatively , this file may be used under the terms of the GNU
* * General Public License version 3.0 as published by the Free Software
* * Foundation and appearing in the file LICENSE . GPL included in the
* * packaging of this file . Please review the following information to
* * ensure the GNU General Public License version 3.0 requirements will be
* * met : http : //www.gnu.org/copyleft/gpl.html.
2011-04-27 10:05:43 +00:00
* *
2012-01-24 06:17:24 +00:00
* *
2011-04-27 10:05:43 +00:00
* * $ QT_END_LICENSE $
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <QtTest/QtTest>
# include <QtGui>
2011-09-16 12:07:05 +00:00
# include <QtWidgets>
2011-04-27 10:05:43 +00:00
2012-12-28 16:35:54 +00:00
static inline void setFrameless ( QWidget * w )
{
Qt : : WindowFlags flags = w - > windowFlags ( ) ;
flags | = Qt : : FramelessWindowHint ;
flags & = ~ ( Qt : : WindowTitleHint | Qt : : WindowSystemMenuHint | Qt : : WindowMinMaxButtonsHint | Qt : : WindowCloseButtonHint ) ;
w - > setWindowFlags ( flags ) ;
}
2011-04-27 10:05:43 +00:00
class tst_QBoxLayout : public QObject
{
Q_OBJECT
public :
tst_QBoxLayout ( ) ;
virtual ~ tst_QBoxLayout ( ) ;
public slots :
void initTestCase ( ) ;
void cleanupTestCase ( ) ;
void init ( ) ;
void cleanup ( ) ;
private slots :
void insertSpacerItem ( ) ;
2013-04-23 13:04:26 +00:00
void insertLayout ( ) ;
2011-04-27 10:05:43 +00:00
void sizeHint ( ) ;
void sizeConstraints ( ) ;
void setGeometry ( ) ;
void setStyleShouldChangeSpacing ( ) ;
2013-08-27 11:29:48 +00:00
void testLayoutEngine_data ( ) ;
void testLayoutEngine ( ) ;
2011-04-27 10:05:43 +00:00
void taskQTBUG_7103_minMaxWidthNotRespected ( ) ;
2012-10-21 18:10:22 +00:00
void taskQTBUG_27420_takeAtShouldUnparentLayout ( ) ;
2012-09-03 04:35:39 +00:00
void replaceWidget ( ) ;
2011-04-27 10:05:43 +00:00
} ;
2012-11-23 14:56:13 +00:00
class CustomLayoutStyle : public QProxyStyle
2011-04-27 10:05:43 +00:00
{
Q_OBJECT
public :
2012-11-23 14:56:13 +00:00
CustomLayoutStyle ( ) : QProxyStyle ( QStyleFactory : : create ( " windows " ) )
2011-04-27 10:05:43 +00:00
{
hspacing = 5 ;
vspacing = 10 ;
}
virtual int pixelMetric ( PixelMetric metric , const QStyleOption * option = 0 ,
const QWidget * widget = 0 ) const ;
int hspacing ;
int vspacing ;
} ;
int CustomLayoutStyle : : pixelMetric ( PixelMetric metric , const QStyleOption * option /*= 0*/ ,
const QWidget * widget /*= 0*/ ) const
{
switch ( metric ) {
case PM_LayoutLeftMargin :
return 0 ;
break ;
case PM_LayoutTopMargin :
return 3 ;
break ;
case PM_LayoutRightMargin :
return 6 ;
break ;
case PM_LayoutBottomMargin :
return 9 ;
break ;
case PM_LayoutHorizontalSpacing :
return hspacing ;
case PM_LayoutVerticalSpacing :
return vspacing ;
break ;
default :
break ;
}
2012-11-23 14:56:13 +00:00
return QProxyStyle : : pixelMetric ( metric , option , widget ) ;
2011-04-27 10:05:43 +00:00
}
tst_QBoxLayout : : tst_QBoxLayout ( )
{
}
tst_QBoxLayout : : ~ tst_QBoxLayout ( )
{
}
void tst_QBoxLayout : : initTestCase ( )
{
}
void tst_QBoxLayout : : cleanupTestCase ( )
{
}
void tst_QBoxLayout : : init ( )
{
}
void tst_QBoxLayout : : cleanup ( )
{
}
void tst_QBoxLayout : : insertSpacerItem ( )
{
QWidget * window = new QWidget ;
QSpacerItem * spacer1 = new QSpacerItem ( 20 , 10 , QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
QSpacerItem * spacer2 = new QSpacerItem ( 40 , 20 , QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
QBoxLayout * layout = new QHBoxLayout ;
layout - > addWidget ( new QLineEdit ( " Foooooooooooooooooooooooooo " ) ) ;
layout - > addSpacerItem ( spacer1 ) ;
layout - > addWidget ( new QLineEdit ( " Baaaaaaaaaaaaaaaaaaaaaaaaar " ) ) ;
layout - > insertSpacerItem ( 0 , spacer2 ) ;
window - > setLayout ( layout ) ;
QVERIFY ( layout - > itemAt ( 0 ) = = spacer2 ) ;
QVERIFY ( layout - > itemAt ( 2 ) = = spacer1 ) ;
window - > show ( ) ;
}
2013-04-23 13:04:26 +00:00
void tst_QBoxLayout : : insertLayout ( )
{
QWidget * window = new QWidget ;
QVBoxLayout * vbox = new QVBoxLayout ( window ) ;
QVBoxLayout * dummyParentLayout = new QVBoxLayout ;
QHBoxLayout * subLayout = new QHBoxLayout ;
dummyParentLayout - > addLayout ( subLayout ) ;
QCOMPARE ( subLayout - > parent ( ) , dummyParentLayout ) ;
QCOMPARE ( dummyParentLayout - > count ( ) , 1 ) ;
// add subLayout to another layout
QTest : : ignoreMessage ( QtWarningMsg , " QLayout::addChildLayout: layout \" \" already has a parent " ) ;
vbox - > addLayout ( subLayout ) ;
QCOMPARE ( ( subLayout - > parent ( ) = = vbox ) , ( vbox - > count ( ) = = 1 ) ) ;
delete dummyParentLayout ;
delete window ;
}
2011-04-27 10:05:43 +00:00
void tst_QBoxLayout : : sizeHint ( )
{
QWidget * window = new QWidget ;
QHBoxLayout * lay1 = new QHBoxLayout ;
QHBoxLayout * lay2 = new QHBoxLayout ;
QLabel * label = new QLabel ( " widget twooooooooooooooooooooooooooooooooooooooooooooooooooooooo " ) ;
lay2 - > addWidget ( label ) ;
lay1 - > addLayout ( lay2 ) ;
window - > setLayout ( lay1 ) ;
window - > show ( ) ;
label - > setText ( " foooooooo baaaaaaar " ) ;
QSize sh = lay1 - > sizeHint ( ) ;
QApplication : : processEvents ( ) ;
// Note that this is not strictly required behaviour - actually
// the preferred behaviour would be that sizeHint returns
// the same value regardless of what's lying in the event queue.
// (i.e. we would check for equality here instead)
QVERIFY ( lay1 - > sizeHint ( ) ! = sh ) ;
}
void tst_QBoxLayout : : sizeConstraints ( )
{
QWidget * window = new QWidget ;
QHBoxLayout * lay = new QHBoxLayout ;
lay - > addWidget ( new QLabel ( " foooooooooooooooooooooooooooooooooooo " ) ) ;
lay - > addWidget ( new QLabel ( " baaaaaaaaaaaaaaaaaaaaaaaaaaaaaar " ) ) ;
lay - > setSizeConstraint ( QLayout : : SetFixedSize ) ;
window - > setLayout ( lay ) ;
window - > show ( ) ;
QApplication : : processEvents ( ) ;
QSize sh = window - > sizeHint ( ) ;
lay - > takeAt ( 1 ) ;
QVERIFY ( sh . width ( ) > = window - > sizeHint ( ) . width ( ) & &
sh . height ( ) > = window - > sizeHint ( ) . height ( ) ) ;
}
void tst_QBoxLayout : : setGeometry ( )
{
QWidget toplevel ;
2012-12-28 16:35:54 +00:00
setFrameless ( & toplevel ) ;
2011-04-27 10:05:43 +00:00
QWidget w ( & toplevel ) ;
QVBoxLayout * lay = new QVBoxLayout ;
lay - > setMargin ( 0 ) ;
lay - > setSpacing ( 0 ) ;
QHBoxLayout * lay2 = new QHBoxLayout ;
QDial * dial = new QDial ;
lay2 - > addWidget ( dial ) ;
lay2 - > setAlignment ( Qt : : AlignTop ) ;
lay2 - > setAlignment ( Qt : : AlignRight ) ;
lay - > addLayout ( lay2 ) ;
w . setLayout ( lay ) ;
toplevel . show ( ) ;
QRect newGeom ( 0 , 0 , 70 , 70 ) ;
lay2 - > setGeometry ( newGeom ) ;
QVERIFY2 ( newGeom . contains ( dial - > geometry ( ) ) , " dial->geometry() should be smaller and within newGeom " ) ;
}
void tst_QBoxLayout : : setStyleShouldChangeSpacing ( )
{
QWidget * window = new QWidget ;
QHBoxLayout * hbox = new QHBoxLayout ( window ) ;
QPushButton * pb1 = new QPushButton ( tr ( " The spacing between this " ) ) ;
QPushButton * pb2 = new QPushButton ( tr ( " and this button should depend on the style of the parent widget " ) ) ; ;
pb1 - > setAttribute ( Qt : : WA_LayoutUsesWidgetRect ) ;
pb2 - > setAttribute ( Qt : : WA_LayoutUsesWidgetRect ) ;
hbox - > addWidget ( pb1 ) ;
hbox - > addWidget ( pb2 ) ;
CustomLayoutStyle * style1 = new CustomLayoutStyle ;
style1 - > hspacing = 6 ;
window - > setStyle ( style1 ) ;
window - > show ( ) ;
QTest : : qWait ( 100 ) ;
int spacing = pb2 - > geometry ( ) . left ( ) - pb1 - > geometry ( ) . right ( ) - 1 ;
QCOMPARE ( spacing , 6 ) ;
CustomLayoutStyle * style2 = new CustomLayoutStyle ( ) ;
style2 - > hspacing = 10 ;
window - > setStyle ( style2 ) ;
QTest : : qWait ( 100 ) ;
spacing = pb2 - > geometry ( ) . left ( ) - pb1 - > geometry ( ) . right ( ) - 1 ;
QCOMPARE ( spacing , 10 ) ;
delete window ;
delete style1 ;
delete style2 ;
}
void tst_QBoxLayout : : taskQTBUG_7103_minMaxWidthNotRespected ( )
{
QLabel * label = new QLabel ( " Qt uses standard C++, but makes extensive use of the C pre-processor to enrich the language. Qt can also be used in several other programming languages via language bindings. It runs on all major platforms, and has extensive internationalization support. Non-GUI features include SQL database access, XML parsing, thread management, network support and a unified cross-platform API for file handling. " ) ;
label - > setWordWrap ( true ) ;
label - > setFixedWidth ( 200 ) ;
QVBoxLayout * layout = new QVBoxLayout ;
layout - > addWidget ( label ) ;
layout - > addSpacerItem ( new QSpacerItem ( 1 , 1 , QSizePolicy : : Fixed , QSizePolicy : : Expanding ) ) ;
QWidget widget ;
widget . setLayout ( layout ) ;
widget . show ( ) ;
2012-07-30 10:36:02 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & widget ) ) ;
2011-04-27 10:05:43 +00:00
int height = label - > height ( ) ;
QRect g = widget . geometry ( ) ;
g . setWidth ( 600 ) ;
widget . setGeometry ( g ) ;
QTest : : qWait ( 50 ) ;
QCOMPARE ( label - > height ( ) , height ) ;
}
2012-10-21 18:10:22 +00:00
void tst_QBoxLayout : : taskQTBUG_27420_takeAtShouldUnparentLayout ( )
{
QSharedPointer < QHBoxLayout > outer ( new QHBoxLayout ) ;
QPointer < QVBoxLayout > inner = new QVBoxLayout ;
outer - > addLayout ( inner ) ;
QCOMPARE ( outer - > count ( ) , 1 ) ;
QCOMPARE ( inner - > parent ( ) , outer . data ( ) ) ;
QLayoutItem * item = outer - > takeAt ( 0 ) ;
QCOMPARE ( item - > layout ( ) , inner . data ( ) ) ;
QVERIFY ( ! item - > layout ( ) - > parent ( ) ) ;
outer . reset ( ) ;
if ( inner )
delete item ; // success: a taken item/layout should not be deleted when the old parent is deleted
else
QVERIFY ( ! inner . isNull ( ) ) ;
}
2013-08-27 11:29:48 +00:00
struct Descr
{
Descr ( int min , int sh , int max = - 1 , bool exp = false , int _stretch = 0 , bool _empty = false )
: minimumSize ( min ) , sizeHint ( sh ) , maximumSize ( max < 0 ? QLAYOUTSIZE_MAX : max ) ,
expanding ( exp ) , stretch ( _stretch ) , empty ( _empty )
{ }
int minimumSize ;
int sizeHint ;
int maximumSize ;
bool expanding ;
int stretch ;
bool empty ;
} ;
typedef QList < Descr > DescrList ;
Q_DECLARE_METATYPE ( DescrList ) ;
typedef QList < int > SizeList ;
typedef QList < int > PosList ;
class LayoutItem : public QLayoutItem
{
public :
LayoutItem ( const Descr & descr ) : m_descr ( descr ) { }
QSize sizeHint ( ) const { return QSize ( m_descr . sizeHint , 100 ) ; }
QSize minimumSize ( ) const { return QSize ( m_descr . minimumSize , 0 ) ; }
QSize maximumSize ( ) const { return QSize ( m_descr . maximumSize , QLAYOUTSIZE_MAX ) ; }
Qt : : Orientations expandingDirections ( ) const
{ return m_descr . expanding ? Qt : : Horizontal : Qt : : Orientations ( 0 ) ; }
void setGeometry ( const QRect & r ) { m_pos = r . x ( ) ; m_size = r . width ( ) ; }
QRect geometry ( ) const { return QRect ( m_pos , 0 , m_size , 100 ) ; }
bool isEmpty ( ) const { return m_descr . empty ; }
private :
Descr m_descr ;
int m_pos ;
int m_size ;
} ;
void tst_QBoxLayout : : testLayoutEngine_data ( )
{
// (int min, int sh, int max = -1, bool exp= false, int _stretch = 0, bool _empty = false)
QTest : : addColumn < DescrList > ( " itemDescriptions " ) ;
QTest : : addColumn < int > ( " size " ) ;
QTest : : addColumn < int > ( " spacing " ) ;
QTest : : addColumn < PosList > ( " expectedPositions " ) ;
QTest : : addColumn < SizeList > ( " expectedSizes " ) ;
QTest : : newRow ( " Just one " )
< < ( DescrList ( ) < < Descr ( 0 , 100 ) )
< < 200
< < 0
< < ( PosList ( ) < < 0 )
< < ( SizeList ( ) < < 200 ) ;
QTest : : newRow ( " Two non-exp " )
< < ( DescrList ( ) < < Descr ( 0 , 100 ) < < Descr ( 0 , 100 ) )
< < 400
< < 0
< < ( PosList ( ) < < 0 < < 200 )
< < ( SizeList ( ) < < 200 < < 200 ) ;
QTest : : newRow ( " Exp + non-exp " )
< < ( DescrList ( ) < < Descr ( 0 , 100 , - 1 , true ) < < Descr ( 0 , 100 ) )
< < 400
< < 0
< < ( PosList ( ) < < 0 < < 300 )
< < ( SizeList ( ) < < 300 < < 100 ) ;
QTest : : newRow ( " Stretch " )
< < ( DescrList ( ) < < Descr ( 0 , 100 , - 1 , false , 1 ) < < Descr ( 0 , 100 , - 1 , false , 2 ) )
< < 300
< < 0
< < ( PosList ( ) < < 0 < < 100 )
< < ( SizeList ( ) < < 100 < < 200 ) ;
QTest : : newRow ( " Spacing " )
< < ( DescrList ( ) < < Descr ( 0 , 100 ) < < Descr ( 0 , 100 ) )
< < 400
< < 10
< < ( PosList ( ) < < 0 < < 205 )
< < ( SizeList ( ) < < 195 < < 195 ) ;
QTest : : newRow ( " Less than minimum " )
< < ( DescrList ( ) < < Descr ( 100 , 100 , 100 , false ) < < Descr ( 50 , 100 , 100 , false ) )
< < 100
< < 0
< < ( PosList ( ) < < 0 < < 50 )
< < ( SizeList ( ) < < 50 < < 50 ) ;
QTest : : newRow ( " Less than sizehint " )
< < ( DescrList ( ) < < Descr ( 100 , 200 , 100 , false ) < < Descr ( 50 , 200 , 100 , false ) )
< < 200
< < 0
< < ( PosList ( ) < < 0 < < 100 )
< < ( SizeList ( ) < < 100 < < 100 ) ;
QTest : : newRow ( " Too much space " )
< < ( DescrList ( ) < < Descr ( 0 , 100 , 100 , false ) < < Descr ( 0 , 100 , 100 , false ) )
< < 500
< < 0
< < ( PosList ( ) < < 100 < < 300 )
< < ( SizeList ( ) < < 100 < < 100 ) ;
QTest : : newRow ( " Empty " )
< < ( DescrList ( ) < < Descr ( 0 , 100 , 100 ) < < Descr ( 0 , 0 , - 1 , false , 0 , true ) < < Descr ( 0 , 100 , 100 ) )
< < 500
< < 0
< < ( PosList ( ) < < 100 < < 300 < < 300 )
< < ( SizeList ( ) < < 100 < < 0 < < 100 ) ;
2013-08-27 12:47:55 +00:00
QTest : : newRow ( " QTBUG-33104 " )
< < ( DescrList ( ) < < Descr ( 11 , 75 , 75 , true ) < < Descr ( 75 , 75 ) )
< < 200
< < 0
< < ( PosList ( ) < < 0 < < 75 )
< < ( SizeList ( ) < < 75 < < 125 ) ;
QTest : : newRow ( " Expanding with maximumSize " )
< < ( DescrList ( ) < < Descr ( 11 , 75 , 100 , true ) < < Descr ( 75 , 75 ) )
< < 200
< < 0
< < ( PosList ( ) < < 0 < < 100 )
< < ( SizeList ( ) < < 100 < < 100 ) ;
QTest : : newRow ( " Stretch with maximumSize " )
< < ( DescrList ( ) < < Descr ( 11 , 75 , 100 , false , 1 ) < < Descr ( 75 , 75 ) )
< < 200
< < 0
< < ( PosList ( ) < < 0 < < 100 )
< < ( SizeList ( ) < < 100 < < 100 ) ;
QTest : : newRow ( " Stretch with maximumSize last " )
< < ( DescrList ( ) < < Descr ( 75 , 75 ) < < Descr ( 11 , 75 , 100 , false , 1 ) )
< < 200
< < 0
< < ( PosList ( ) < < 0 < < 100 )
< < ( SizeList ( ) < < 100 < < 100 ) ;
2013-08-27 11:29:48 +00:00
}
void tst_QBoxLayout : : testLayoutEngine ( )
{
QFETCH ( DescrList , itemDescriptions ) ;
QFETCH ( int , size ) ;
QFETCH ( int , spacing ) ;
QFETCH ( PosList , expectedPositions ) ;
QFETCH ( SizeList , expectedSizes ) ;
QHBoxLayout box ;
box . setSpacing ( spacing ) ;
int i ;
for ( i = 0 ; i < itemDescriptions . count ( ) ; + + i ) {
Descr descr = itemDescriptions . at ( i ) ;
LayoutItem * li = new LayoutItem ( descr ) ;
box . addItem ( li ) ;
box . setStretch ( i , descr . stretch ) ;
}
box . setGeometry ( QRect ( 0 , 0 , size , 100 ) ) ;
for ( i = 0 ; i < expectedSizes . count ( ) ; + + i ) {
int xSize = expectedSizes . at ( i ) ;
int xPos = expectedPositions . at ( i ) ;
QLayoutItem * item = box . itemAt ( i ) ;
QCOMPARE ( item - > geometry ( ) . width ( ) , xSize ) ;
QCOMPARE ( item - > geometry ( ) . x ( ) , xPos ) ;
}
}
2012-09-03 04:35:39 +00:00
void tst_QBoxLayout : : replaceWidget ( )
{
QWidget w ;
QBoxLayout * boxLayout = new QVBoxLayout ( & w ) ;
QLineEdit * replaceFrom = new QLineEdit ;
QLineEdit * replaceTo = new QLineEdit ;
boxLayout - > addWidget ( new QLineEdit ( ) ) ;
boxLayout - > addWidget ( replaceFrom ) ;
boxLayout - > addWidget ( new QLineEdit ( ) ) ;
QCOMPARE ( boxLayout - > indexOf ( replaceFrom ) , 1 ) ;
QCOMPARE ( boxLayout - > indexOf ( replaceTo ) , - 1 ) ;
boxLayout - > replaceWidget ( replaceFrom , replaceTo ) ;
QCOMPARE ( boxLayout - > indexOf ( replaceFrom ) , - 1 ) ;
QCOMPARE ( boxLayout - > indexOf ( replaceTo ) , 1 ) ;
}
2011-04-27 10:05:43 +00:00
QTEST_MAIN ( tst_QBoxLayout )
# include "tst_qboxlayout.moc"