From 703491332328ad11fbdc78ffc26a82e291dd8bde Mon Sep 17 00:00:00 2001
From: Thierry Bastian <thierry.bastian@nokia.com>
Date: Mon, 29 Jun 2009 17:34:39 +0200
Subject: QMenuBar: adding autotest for the geometry calculation

Also fixed  a bug that would take the VMargin 3 times instead of 2.
---
 src/gui/widgets/qmenubar.cpp         | 11 +++++-----
 tests/auto/qmenubar/tst_qmenubar.cpp | 42 +++++++++++++++++++++++++++++-------
 2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index 5a8c0e2..7982d98 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -273,8 +273,6 @@ QRect QMenuBarPrivate::actionRect(QAction *act) const
     const_cast<QMenuBarPrivate*>(this)->updateGeometries();
 
     QRect ret = actionRects.at(index);
-    const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
-    ret.translate(fw, fw);
     return QStyle::visualRect(q->layoutDirection(), q->rect(), ret);
 }
 
@@ -480,8 +478,9 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start) const
     }
 
     //calculate position
-    int x = ((start == -1) ? hmargin : start) + itemSpacing;
-    int y = vmargin;
+    const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
+    int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
+    int y = fw + vmargin;
     for(int i = 0; i < actions.count(); i++) {
         QRect &rect = actionRects[i];
         if (rect.isNull())
@@ -1665,7 +1664,9 @@ QSize QMenuBar::sizeHint() const
             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);
+        //the action geometries already contain the top and left
+        //margins. So we only need to add those from right and bottom.
+        ret += QSize(fw + hmargin, fw + vmargin);
     }
     int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
     if(d->leftWidget) {
diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp
index f6f5873..500465c 100644
--- a/tests/auto/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/qmenubar/tst_qmenubar.cpp
@@ -48,6 +48,7 @@
 #include <q3popupmenu.h>
 #endif
 #include <qstyle.h>
+#include <qwindowsstyle.h>
 #include <qdesktopwidget.h>
 #include <qaction.h>
 #include <qstyleoption.h>
@@ -1560,22 +1561,47 @@ void tst_QMenuBar::task256322_highlight()
 
 void tst_QMenuBar::menubarSizeHint()
 {
+    struct MyStyle : public QWindowsStyle
+    {
+        virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0, const QWidget * widget = 0 ) const
+        {
+            // I chose strange values (prime numbers to be more sure that the size of the menubar is correct)
+            switch (metric) 
+            {
+            case QStyle::PM_MenuBarItemSpacing:
+                return 7;
+            case PM_MenuBarHMargin:
+                return 13;
+            case PM_MenuBarVMargin:
+                return 11;
+            case PM_MenuBarPanelWidth:
+                return 1;
+            }
+            return QWindowsStyle::pixelMetric(metric, option, widget);
+        }
+    } style;
+
     QMenuBar mb;
+    mb.setStyle(&style);
     //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);
+    const int panelWidth = style.pixelMetric(QStyle::PM_MenuBarPanelWidth);
+    const int hmargin = style.pixelMetric(QStyle::PM_MenuBarHMargin);
+    const int vmargin = style.pixelMetric(QStyle::PM_MenuBarVMargin);
+    const int spacing = style.pixelMetric(QStyle::PM_MenuBarItemSpacing);
 
     mb.show();
     QRect result;
     foreach(QAction *action, mb.actions()) {
-        result |= mb.actionGeometry(action);
-        QCOMPARE(result.x(), left + panelWidth);
-        QCOMPARE(result.y(), top + panelWidth);
+        const QRect actionRect = mb.actionGeometry(action);
+        if (!result.isNull()) //this is the first item
+            QCOMPARE(actionRect.left() - result.right() - 1, spacing);
+        result |= actionRect;
+        QCOMPARE(result.x(), panelWidth + hmargin + spacing);
+        QCOMPARE(result.y(), panelWidth + vmargin);
     }
 
     //this code is copied from QMenuBar
@@ -1589,10 +1615,10 @@ void tst_QMenuBar::menubarSizeHint()
     opt.palette = mb.palette();
 
     QSize resSize = QSize(result.x(), result.y()) + result.size()
-        + QSize(right + panelWidth, top + panelWidth);
+        + QSize(panelWidth + hmargin, panelWidth + vmargin);
 
 
-    resSize = mb.style()->sizeFromContents(QStyle::CT_MenuBar, &opt,
+    resSize = style.sizeFromContents(QStyle::CT_MenuBar, &opt,
                                          resSize.expandedTo(QApplication::globalStrut()),
                                          &mb);
 
-- 
cgit v0.12