QFrame: introduce initStyleOption (and use it)

For some reason lost in time QFrame was missing that method. Of course
that led to duplicated code and to subtle sizing miscalculations.

Task-number: QTBUG-29330
Change-Id: I81163f5def6661e01cb2ecc49c1169449a3e3758
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Giuseppe D'Angelo 2014-10-30 18:40:03 +01:00
parent 7afc6d6277
commit 29c4913b02
3 changed files with 129 additions and 31 deletions

View File

@ -202,6 +202,49 @@ QFrame::QFrame(QFramePrivate &dd, QWidget* parent, Qt::WindowFlags f)
d->init(); d->init();
} }
/*!
\since 5.5
Initializes \a option with the values from this QFrame. This method is
useful for subclasses when they need a QStyleOptionFrame but don't want to
fill in all the information themselves.
\sa QStyleOption::initFrom()
*/
void QFrame::initStyleOption(QStyleOptionFrame *option) const
{
if (!option)
return;
Q_D(const QFrame);
option->initFrom(this);
int frameShape = d->frameStyle & QFrame::Shape_Mask;
int frameShadow = d->frameStyle & QFrame::Shadow_Mask;
option->frameShape = Shape(int(option->frameShape) | frameShape);
option->rect = frameRect();
switch (frameShape) {
case QFrame::Box:
case QFrame::HLine:
case QFrame::VLine:
case QFrame::StyledPanel:
case QFrame::Panel:
option->lineWidth = d->lineWidth;
option->midLineWidth = d->midLineWidth;
break;
default:
// most frame styles do not handle customized line and midline widths
// (see updateFrameWidth()).
option->lineWidth = d->frameWidth;
break;
}
if (frameShadow == Sunken)
option->state |= QStyle::State_Sunken;
else if (frameShadow == Raised)
option->state |= QStyle::State_Raised;
}
/*! /*!
Destroys the frame. Destroys the frame.
@ -362,10 +405,7 @@ void QFramePrivate::updateStyledFrameWidths()
{ {
Q_Q(const QFrame); Q_Q(const QFrame);
QStyleOptionFrame opt; QStyleOptionFrame opt;
opt.initFrom(q); q->initStyleOption(&opt);
opt.lineWidth = lineWidth;
opt.midLineWidth = midLineWidth;
opt.frameShape = QFrame::Shape(frameStyle & QFrame::Shape_Mask);
QRect cr = q->style()->subElementRect(QStyle::SE_ShapedFrameContents, &opt, q); QRect cr = q->style()->subElementRect(QStyle::SE_ShapedFrameContents, &opt, q);
leftFrameWidth = cr.left() - opt.rect.left(); leftFrameWidth = cr.left() - opt.rect.left();
@ -472,34 +512,8 @@ void QFrame::paintEvent(QPaintEvent *)
*/ */
void QFrame::drawFrame(QPainter *p) void QFrame::drawFrame(QPainter *p)
{ {
Q_D(QFrame);
QStyleOptionFrame opt; QStyleOptionFrame opt;
opt.init(this); initStyleOption(&opt);
int frameShape = d->frameStyle & QFrame::Shape_Mask;
int frameShadow = d->frameStyle & QFrame::Shadow_Mask;
opt.frameShape = Shape(int(opt.frameShape) | frameShape);
opt.rect = frameRect();
switch (frameShape) {
case QFrame::Box:
case QFrame::HLine:
case QFrame::VLine:
case QFrame::StyledPanel:
case QFrame::Panel:
opt.lineWidth = d->lineWidth;
opt.midLineWidth = d->midLineWidth;
break;
default:
// most frame styles do not handle customized line and midline widths
// (see updateFrameWidth()).
opt.lineWidth = d->frameWidth;
break;
}
if (frameShadow == Sunken)
opt.state |= QStyle::State_Sunken;
else if (frameShadow == Raised)
opt.state |= QStyle::State_Raised;
style()->drawControl(QStyle::CE_ShapedFrame, &opt, p, this); style()->drawControl(QStyle::CE_ShapedFrame, &opt, p, this);
} }

View File

@ -40,6 +40,7 @@ QT_BEGIN_NAMESPACE
class QFramePrivate; class QFramePrivate;
class QStyleOptionFrame;
class Q_WIDGETS_EXPORT QFrame : public QWidget class Q_WIDGETS_EXPORT QFrame : public QWidget
{ {
@ -107,6 +108,7 @@ protected:
protected: protected:
QFrame(QFramePrivate &dd, QWidget* parent = 0, Qt::WindowFlags f = 0); QFrame(QFramePrivate &dd, QWidget* parent = 0, Qt::WindowFlags f = 0);
void initStyleOption(QStyleOptionFrame *option) const;
private: private:
Q_DISABLE_COPY(QFrame) Q_DISABLE_COPY(QFrame)

View File

@ -34,12 +34,15 @@
#include <QTest> #include <QTest>
#include <QFrame> #include <QFrame>
#include <QStyleOptionFrame>
class tst_QFrame : public QObject class tst_QFrame : public QObject
{ {
Q_OBJECT Q_OBJECT
private slots: private slots:
void testDefaults(); void testDefaults();
void testInitStyleOption_data();
void testInitStyleOption();
}; };
Q_DECLARE_METATYPE(QFrame::Shape) Q_DECLARE_METATYPE(QFrame::Shape)
@ -55,6 +58,85 @@ void tst_QFrame::testDefaults()
QCOMPARE(frame.frameStyle(), int(QFrame::Box)); QCOMPARE(frame.frameStyle(), int(QFrame::Box));
} }
class Frame : public QFrame
{
public:
using QFrame::initStyleOption;
};
void tst_QFrame::testInitStyleOption_data()
{
QTest::addColumn<QString>("basename");
QTest::addColumn<int>("lineWidth");
QTest::addColumn<int>("midLineWidth");
QTest::addColumn<QFrame::Shape>("shape");
QTest::addColumn<QFrame::Shadow>("shadow");
for (int lineWidth = 0; lineWidth < 3; ++lineWidth) {
for (int midLineWidth = 0; midLineWidth < 3; ++midLineWidth) {
QTest::newRow(qPrintable(QStringLiteral("box_noshadow_%1_%2").arg(lineWidth).arg(midLineWidth)))
<< "box_noshadow" << lineWidth << midLineWidth << QFrame::Box << (QFrame::Shadow)0;
QTest::newRow(qPrintable(QStringLiteral("box_plain_%1_%2").arg(lineWidth).arg(midLineWidth)))
<< "box_plain" << lineWidth << midLineWidth << QFrame::Box << QFrame::Plain;
QTest::newRow(qPrintable(QStringLiteral("box_raised_%1_%2").arg(lineWidth).arg(midLineWidth)))
<< "box_raised" << lineWidth << midLineWidth << QFrame::Box << QFrame::Raised;
QTest::newRow(qPrintable(QStringLiteral("box_sunken_%1_%2").arg(lineWidth).arg(midLineWidth)))
<< "box_sunken" << lineWidth << midLineWidth << QFrame::Box << QFrame::Sunken;
QTest::newRow(qPrintable(QStringLiteral("winpanel_noshadow_%1_%2").arg(lineWidth).arg(midLineWidth)))
<< "winpanel_noshadow" << lineWidth << midLineWidth << QFrame::WinPanel << (QFrame::Shadow)0;
QTest::newRow(qPrintable(QStringLiteral("winpanel_plain_%1_%2").arg(lineWidth).arg(midLineWidth)))
<< "winpanel_plain" << lineWidth << midLineWidth << QFrame::WinPanel << QFrame::Plain;
QTest::newRow(qPrintable(QStringLiteral("winpanel_raised_%1_%2").arg(lineWidth).arg(midLineWidth)))
<< "winpanel_raised" << lineWidth << midLineWidth << QFrame::WinPanel << QFrame::Raised;
QTest::newRow(qPrintable(QStringLiteral("winpanel_sunken_%1_%2").arg(lineWidth).arg(midLineWidth)))
<< "winpanel_sunken" << lineWidth << midLineWidth << QFrame::WinPanel << QFrame::Sunken;
}
}
}
void tst_QFrame::testInitStyleOption()
{
QFETCH(QString, basename);
QFETCH(int, lineWidth);
QFETCH(int, midLineWidth);
QFETCH(QFrame::Shape, shape);
QFETCH(QFrame::Shadow, shadow);
Frame frame;
frame.setFrameStyle(shape | shadow);
frame.setLineWidth(lineWidth);
frame.setMidLineWidth(midLineWidth);
frame.resize(16, 16);
QStyleOptionFrame styleOption;
frame.initStyleOption(&styleOption);
switch (shape) {
case QFrame::Box:
case QFrame::Panel:
case QFrame::StyledPanel:
case QFrame::HLine:
case QFrame::VLine:
QCOMPARE(styleOption.lineWidth, lineWidth);
QCOMPARE(styleOption.midLineWidth, midLineWidth);
break;
case QFrame::NoFrame:
case QFrame::WinPanel:
QCOMPARE(styleOption.lineWidth, frame.frameWidth());
QCOMPARE(styleOption.midLineWidth, 0);
break;
}
QCOMPARE(styleOption.features, QStyleOptionFrame::None);
QCOMPARE(styleOption.frameShape, shape);
if (shadow == QFrame::Sunken)
QVERIFY(styleOption.state & QStyle::State_Sunken);
else if (shadow == QFrame::Raised)
QVERIFY(styleOption.state & QStyle::State_Raised);
}
QTEST_MAIN(tst_QFrame) QTEST_MAIN(tst_QFrame)
#include "tst_qframe.moc" #include "tst_qframe.moc"