QMenuBar: fix extra indent on the right with a TopLeftCorner widget.

When setting a left corner widget on a QMenuBar, the first
action rectangle is offset by its width and thus the width
should not be added to the size hint. Use QSize::expandedTo()
instead.

Task-number: QTBUG-36010
Change-Id: I660e3facbd0aeb5fb84fac8923db3e0c7998309d
Reviewed-by: Jan Arve Sæther <jan-arve.saether@theqtcompany.com>
This commit is contained in:
Friedemann Kleint 2014-11-19 16:23:51 +01:00
parent 9fb4c2c412
commit 8e9d78e43e
2 changed files with 82 additions and 3 deletions

View File

@ -1631,9 +1631,8 @@ QSize QMenuBar::sizeHint() const
int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
if(d->leftWidget) { if(d->leftWidget) {
QSize sz = d->leftWidget->sizeHint(); QSize sz = d->leftWidget->sizeHint();
ret.setWidth(ret.width() + sz.width()); sz.rheight() += margin;
if(sz.height() + margin > ret.height()) ret.expandedTo(sz);
ret.setHeight(sz.height() + margin);
} }
if(d->rightWidget) { if(d->rightWidget) {
QSize sz = d->rightWidget->sizeHint(); QSize sz = d->rightWidget->sizeHint();

View File

@ -42,6 +42,8 @@
#include <qdesktopwidget.h> #include <qdesktopwidget.h>
#include <qaction.h> #include <qaction.h>
#include <qstyleoption.h> #include <qstyleoption.h>
#include <QVBoxLayout>
#include <QLabel>
#include <qscreen.h> #include <qscreen.h>
#include <qobject.h> #include <qobject.h>
@ -83,6 +85,7 @@ public:
private slots: private slots:
void getSetCheck(); void getSetCheck();
void cleanup();
void clear(); void clear();
void removeItemAt(); void removeItemAt();
@ -126,6 +129,8 @@ private slots:
#endif #endif
void taskQTBUG11823_crashwithInvisibleActions(); void taskQTBUG11823_crashwithInvisibleActions();
void closeOnSecondClick(); void closeOnSecondClick();
void cornerWidgets_data();
void cornerWidgets();
protected slots: protected slots:
void onSimpleActivated( QAction*); void onSimpleActivated( QAction*);
@ -195,6 +200,11 @@ void tst_QMenuBar::onSimpleActivated( QAction* action )
m_simpleActivatedCount++; m_simpleActivatedCount++;
} }
void tst_QMenuBar::cleanup()
{
QVERIFY(QApplication::topLevelWidgets().isEmpty());
}
// Create a simple menu bar and connect its actions to onSimpleActivated(). // Create a simple menu bar and connect its actions to onSimpleActivated().
TestMenu tst_QMenuBar::initSimpleMenuBar(QMenuBar *mb) TestMenu tst_QMenuBar::initSimpleMenuBar(QMenuBar *mb)
@ -1325,5 +1335,75 @@ void tst_QMenuBar::closeOnSecondClick() // QTBUG-32807, menu should close on 2nd
QTRY_VERIFY(!fileMenu->isVisible()); QTRY_VERIFY(!fileMenu->isVisible());
} }
Q_DECLARE_METATYPE(Qt::Corner)
void tst_QMenuBar::cornerWidgets_data()
{
QTest::addColumn<Qt::Corner>("corner");
QTest::newRow("left") << Qt::TopLeftCorner;
QTest::newRow("right") << Qt::TopRightCorner;
}
static QByteArray msgComparison(int v1, const char *op, int v2)
{
QString result;
QDebug(&result) << v1 << op << v2 << "failed";
return result.toLocal8Bit();
}
void tst_QMenuBar::cornerWidgets()
{
enum { cornerWidgetWidth = 100 };
QFETCH(Qt::Corner, corner);
#if defined(Q_OS_OSX) || defined(Q_OS_WINCE)
QSKIP("Test interferes with native menu bars on this platform");
#endif
QWidget widget;
const QString dataTag = QLatin1String(QTest::currentDataTag());
widget.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + dataTag);
QVBoxLayout *layout = new QVBoxLayout(&widget);
QMenuBar *menuBar = new QMenuBar(&widget);
layout->addWidget(menuBar);
QMenu *fileMenu = menuBar->addMenu("File");
fileMenu->addAction("Quit");
QMenu *editMenu =menuBar->addMenu("Edit");
editMenu->addAction("Copy");
centerOnScreen(&widget);
QLabel *cornerLabel = new QLabel(dataTag);
cornerLabel->setFixedWidth(cornerWidgetWidth);
menuBar->setCornerWidget(cornerLabel, corner);
QCOMPARE(menuBar->cornerWidget(corner), cornerLabel);
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
const QRect fileMenuGeometry = menuBar->actionGeometry(fileMenu->menuAction());
const QRect editMenuGeometry = menuBar->actionGeometry(editMenu->menuAction());
const int menuBarWidth = menuBar->width();
switch (corner) { // QTBUG-36010 , verify corner widget geometry is correct
case Qt::TopLeftCorner:
QVERIFY2(fileMenuGeometry.left() >= cornerWidgetWidth,
msgComparison(fileMenuGeometry.left(), ">=", cornerWidgetWidth));
QVERIFY2(menuBarWidth - editMenuGeometry.right() < cornerWidgetWidth,
msgComparison(menuBarWidth - editMenuGeometry.right(), "<", cornerWidgetWidth));
break;
case Qt::TopRightCorner:
QVERIFY2(fileMenuGeometry.left() < cornerWidgetWidth,
msgComparison(fileMenuGeometry.left(), "<", cornerWidgetWidth));
QVERIFY2(menuBarWidth - editMenuGeometry.right() >= cornerWidgetWidth,
msgComparison(menuBarWidth - editMenuGeometry.right(), ">=", cornerWidgetWidth));
break;
default:
break;
}
menuBar->setCornerWidget(0, corner); // Don't crash.
QVERIFY(!menuBar->cornerWidget(corner));
delete cornerLabel;
}
QTEST_MAIN(tst_QMenuBar) QTEST_MAIN(tst_QMenuBar)
#include "tst_qmenubar.moc" #include "tst_qmenubar.moc"