From 82c48b13249fbcd96d8287f3cd1fdfd61802523c Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 29 Jun 2009 15:38:06 +0200 Subject: QMenuBar: adding autotest and simplify/fix geometry calculation --- src/gui/widgets/qmenubar.cpp | 21 +++++++----------- src/gui/widgets/qmenubar_p.h | 3 +-- tests/auto/qmenubar/tst_qmenubar.cpp | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index a31dc67..5a8c0e2 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -198,8 +198,6 @@ void QMenuBarPrivate::updateGeometries() } #endif calcActionRects(q_width, q_start); - itemsWidth = q_width; - itemsStart = q_start; currentAction = 0; #ifndef QT_NO_SHORTCUT if(itemsDirty) { @@ -271,6 +269,9 @@ QRect QMenuBarPrivate::actionRect(QAction *act) const if (index == -1) return QRect(); + //makes sure the geometries are up-to-date + const_cast(this)->updateGeometries(); + QRect ret = actionRects.at(index); const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); ret.translate(fw, fw); @@ -415,9 +416,9 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start) const { Q_Q(const QMenuBar); - if(!itemsDirty && itemsWidth == max_width && itemsStart == start) { + if(!itemsDirty) return; - } + //let's reinitialize the buffer actionRects.resize(actions.count()); actionRects.fill(QRect()); @@ -1658,17 +1659,11 @@ QSize QMenuBar::sizeHint() const int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); if(as_gui_menubar) { - QMap actionRects; - QList actionList; const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width(); d->calcActionRects(w - (2 * fw), 0); - for (QMap::const_iterator i = actionRects.constBegin(); - i != actionRects.constEnd(); ++i) { - QRect actionRect(i.value()); - if(actionRect.x() + actionRect.width() > ret.width()) - ret.setWidth(actionRect.x() + actionRect.width()); - if(actionRect.y() + actionRect.height() > ret.height()) - ret.setHeight(actionRect.y() + actionRect.height()); + for (int i = 0; i < d->actionRects.count(); ++i) { + const QRect &actionRect = d->actionRects.at(i); + ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height())); } ret += QSize(2*fw + 2*hmargin, 2*fw + 2*vmargin); } diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h index 5b209b2..bac1912 100644 --- a/src/gui/widgets/qmenubar_p.h +++ b/src/gui/widgets/qmenubar_p.h @@ -69,7 +69,7 @@ class QMenuBarPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QMenuBar) public: - QMenuBarPrivate() : itemsDirty(0), itemsWidth(0), itemsStart(-1), currentAction(0), mouseDown(0), + QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0), closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0), nativeMenuBar(-1) #ifdef Q_WS_MAC @@ -95,7 +95,6 @@ public: //item calculations uint itemsDirty : 1; - int itemsWidth, itemsStart; QVector shortcutIndexMap; mutable QVector actionRects; diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 8a38782..f6f5873 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #ifdef Q_WS_WIN #include @@ -150,6 +151,7 @@ private slots: void check_menuPosition(); void task223138_triggered(); void task256322_highlight(); + void menubarSizeHint(); #if defined(QT3_SUPPORT) void indexBasedInsertion_data(); @@ -1556,6 +1558,47 @@ void tst_QMenuBar::task256322_highlight() QVERIFY(!win.menuBar()->activeAction()); } +void tst_QMenuBar::menubarSizeHint() +{ + QMenuBar mb; + //this is a list of arbitrary strings so that we check the geometry + QStringList list = QStringList() << "trer" << "ezrfgtgvqd" << "sdgzgzerzerzer" << "eerzertz" << "er"; + foreach(QString str, list) + mb.addAction(str); + + int left, top, right, bottom; + mb.getContentsMargins(&left, &top, &right, &bottom); + const int panelWidth = mb.style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, &mb); + + mb.show(); + QRect result; + foreach(QAction *action, mb.actions()) { + result |= mb.actionGeometry(action); + QCOMPARE(result.x(), left + panelWidth); + QCOMPARE(result.y(), top + panelWidth); + } + + //this code is copied from QMenuBar + //there is no public member that allows to initialize a styleoption instance + QStyleOptionMenuItem opt; + opt.rect = mb.rect(); + opt.menuRect = mb.rect(); + opt.state = QStyle::State_None; + opt.menuItemType = QStyleOptionMenuItem::Normal; + opt.checkType = QStyleOptionMenuItem::NotCheckable; + opt.palette = mb.palette(); + + QSize resSize = QSize(result.x(), result.y()) + result.size() + + QSize(right + panelWidth, top + panelWidth); + + + resSize = mb.style()->sizeFromContents(QStyle::CT_MenuBar, &opt, + resSize.expandedTo(QApplication::globalStrut()), + &mb); + + QCOMPARE(resSize, mb.sizeHint()); +} + #if defined(QT3_SUPPORT) void tst_QMenuBar::indexBasedInsertion_data() -- cgit v0.12