changeset 22744:2df51376f587

Correctly handle visibility of custom menu items (bug #49529) * Figure.h (Figure::m_previousHeight: new int attribute to keep track of the menubar height * Figure.h (Figure::updateMenuBar): change signature to accept a prescribed initial size for the menubar (default to -1) * Figure.h (Figure::showMenuBar): ditto * Figure.cc: revert cset 0cd8a1c22f23 (except removed comments) * Figure.cc (Figure::showMenuBar): resize and change visibility if the menubar current and requested states don't match * Figure.cc (Figure::hasUiMenuChildren): return true only if any custom menu is visible * Figure.cc (Figure::eventNotifyBefore): store the menubar height before QEvent::ActionChanged events * Figure.cc (Figure::eventNotifyAfter): after QEvent::ActionChanged events, call updateMenuBar with a prescribed initial height when the menubar size has changed
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Wed, 09 Nov 2016 09:16:17 +0100
parents 661cf739818c
children 9506842e0f6f
files libgui/graphics/Figure.cc libgui/graphics/Figure.h
diffstat 2 files changed, 47 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/graphics/Figure.cc	Wed Nov 09 16:58:44 2016 -0500
+++ b/libgui/graphics/Figure.cc	Wed Nov 09 09:16:17 2016 +0100
@@ -93,7 +93,8 @@
       {
         graphics_object go (gh_manager::get_object (kids(i)));
 
-        if (go && go.isa ("uimenu"))
+        if (go && go.isa ("uimenu") && 
+            go.get ("visible").string_value () == "on")
           return true;
       }
 
@@ -427,8 +428,8 @@
           int boffset = 0;
 
           foreach (QToolBar* tb, win->findChildren<QToolBar*> ())
-          if (! tb->isHidden ())
-            toffset += tb->sizeHint ().height ();
+            if (! tb->isHidden ())
+              toffset += tb->sizeHint ().height ();
 
           if (! m_menuBar->isHidden ())
             toffset += m_menuBar->sizeHint ().height ();
@@ -532,43 +533,49 @@
   }
 
   void
-  Figure::showMenuBar (bool visible)
+  Figure::showMenuBar (bool visible, int h1)
   {
-    int h1 = m_menuBar->sizeHint ().height ();
+    // Get the height before and after toggling the visibility of builtin menus 
+    if (h1 <= 0)
+      h1 = m_menuBar->sizeHint ().height ();
 
     foreach (QAction* a, m_menuBar->actions ())
-    if (a->objectName () == "builtinMenu")
-      a->setVisible (visible);
+      if (a->objectName () == "builtinMenu")
+        a->setVisible (visible);
 
     int h2 = m_menuBar->sizeHint ().height ();
 
+    // Keep the menubar visible if it contains custom menus
     if (! visible)
       visible = hasUiMenuChildren (properties<figure> ());
-
-    int dy = qMax (h1, h2);
-    QRect r = qWidget<QWidget> ()->geometry ();
+    
+    if (m_menuBar->isVisible () ^ visible)
+      {
+        int dy = qMax (h1, h2);
+        QRect r = qWidget<QWidget> ()->geometry ();
+        
+        if (! visible)
+          r.adjust (0, dy, 0, 0);
+        else
+          r.adjust (0, -dy, 0, 0);
 
-    if (! visible)
-      r.adjust (0, dy, 0, 0);
-    else
-      r.adjust (0, -dy, 0, 0);
-
-    m_blockUpdates = true;
-    qWidget<QWidget> ()->setGeometry (r);
-    m_menuBar->setVisible (visible);
-    m_blockUpdates = false;
-
+        m_blockUpdates = true;
+        qWidget<QWidget> ()->setGeometry (r);
+        m_menuBar->setVisible (visible);
+        m_blockUpdates = false;
+      }
     updateBoundingBox (false);
   }
 
   void
-  Figure::updateMenuBar (void)
+  Figure::updateMenuBar (int height)
   {
     gh_manager::auto_lock lock;
     graphics_object go = object ();
 
     if (go.valid_object ())
-      showMenuBar (Utils::properties<figure> (go).menubar_is ("figure"));
+      showMenuBar (Utils::properties<figure> (go).menubar_is ("figure"), 
+                   height);
   }
 
   void
@@ -684,6 +691,9 @@
           {
             switch (xevent->type ())
               {
+              case QEvent::ActionChanged:
+                m_previousHeight = m_menuBar->sizeHint ().height ();
+                break;
               case QEvent::ActionRemoved:
                 {
                   QAction* a = dynamic_cast<QActionEvent*> (xevent)->action ();
@@ -755,12 +765,23 @@
           {
             switch (xevent->type ())
               {
+              case QEvent::ActionChanged:
+                // The mennubar may have been resized if no action is visible
+                {
+                  QAction* a = dynamic_cast<QActionEvent*> (xevent)->action ();
+                  if (m_menuBar->sizeHint ().height () != m_previousHeight
+                      && a->objectName () != "builtinMenu"
+                      && ! a->isSeparator ())
+                    updateMenuBar (m_previousHeight);
+                }
+                break;
               case QEvent::ActionAdded:
                 {
                   QAction* a = dynamic_cast<QActionEvent*> (xevent)->action ();
 
                   if (! a->isSeparator ()
-                      && a->objectName () != "builtinMenu")
+                      && a->objectName () != "builtinMenu"
+                      && a->isVisible ())
                     updateMenuBar ();
                 }
                 break;
--- a/libgui/graphics/Figure.h	Wed Nov 09 16:58:44 2016 -0500
+++ b/libgui/graphics/Figure.h	Wed Nov 09 09:16:17 2016 +0100
@@ -102,7 +102,7 @@
   private:
     void createFigureToolBarAndMenuBar (void);
     void showFigureToolBar (bool visible);
-    void showMenuBar (bool visible);
+    void showMenuBar (bool visible, int height = -1);
     void addCustomToolBar (QToolBar* bar, bool visible);
     void showCustomToolBar (QToolBar* bar, bool visible);
 
@@ -122,7 +122,7 @@
     void fileCloseFigure (void);
     void editCopy (bool choose_format = false);
     void helpAboutOctave (void);
-    void updateMenuBar (void);
+    void updateMenuBar (int height = -1);
     void updateContainer (void);
     void toggleAxes (void);
     void toggleGrid (void);
@@ -140,6 +140,7 @@
     QRect m_innerRect;
     QRect m_outerRect;
     MouseModeActionGroup* m_mouseModeGroup;
+    int m_previousHeight;
   };
 
 }