qt-bugs@ issue : N25566
applied: no
author: Waldo Bastian <bastian@kde.org>

Hi,

In KDE we experience problems with the arrow menu being created too early. The
problem seems to be mostly caused by the assumption of the
QToolBar::createPopup() code that the layout order of the toolbar-buttons
matches the order of the child-widgets. In KDE we break that assumption.

The problem is then that doHide can be set to true for a widget that doesn't
actually cause an entry in the popup-menu. Once this occurs the trigger-point
for the extension menu is placed (d->extension->width() / j) pixels more to
the left and this then makes that the right-most button, which would actually
still just fit within width(), is considered hidden by the extension menu,
and as a result placed in the extension menu which then actually causes the
extension menu to appear. That's really not necassery though and rather
unfortunate.

The attached patch (qtoolbar_arrow.patch) [WABA: See below]
sets doHide only then when there is actually an entry added to the 
extension menu.

Another thing what puzzles me is the "int j = 2" construct. This suggests that
a button should only be added to the menu when the right-edge of the button
is past the middle of the arrow button. This seems a very odd criteria: if
the button is small in comparison to the arrow button, the button can be
hidden completely already before it is added to the extension menu. A more
correct criteria IMO should either be: the button should be added to the menu
if any pixel of the button is hidden by the extension menu, (This can be
achieved simply by setting j = 1) or perhaps: the buttons should be added to
the menu if more than half of the button is hidden by the extension menu. In
that case the width of the button in question should be halved, not the width
of the extension menu.

Thirdly, since KDE breaks the assumption about ordering, it would be very nice
for KDE if the algorithm could be turned into a two-pass one. The
qtoolbar_arrow2.patch [WABA: 0012-qtoolbar-arrow.patch] provides an 
example for that. The first pass determines
if the extension menu should be shown at all, the second pass determines
which entries it should contain. Note that I have left indentation changes
out of the patch. Buttons are added to the menu if at least one or more
pixels of the button are invisible.

Cheers,
Waldo

Index: qtoolbar.cpp
===================================================================
RCS file: /home/kde/qt-copy/src/widgets/qtoolbar.cpp,v
retrieving revision 1.52
diff -u -r1.52 qtoolbar.cpp
--- qtoolbar.cpp	30 Oct 2002 01:54:27 -0000	1.52
+++ qtoolbar.cpp	29 Jun 2003 16:04:02 -0000
@@ -636,7 +636,6 @@
 	        hide = TRUE;
 	}
 	if ( hide && !w->isHidden() ) {
-	    doHide = TRUE;
 	    if ( w->inherits( "QToolButton" ) ) {
 	        QToolButton *b = (QToolButton*)w;
 	        QString s = b->textLabel();
@@ -650,6 +649,7 @@
 		    d->extensionPopup->setItemChecked( id, b->isOn() );
 		if ( !b->isEnabled() )
 		    d->extensionPopup->setItemEnabled( id, FALSE );
+		doHide = TRUE;
 	    } else if ( w->inherits( "QButton" ) ) {
 		QButton *b = (QButton*)w;
 		QString s = b->text();
@@ -663,6 +663,7 @@
 		    d->extensionPopup->setItemChecked( id, b->isOn() );
 		if ( !b->isEnabled() )
 		    d->extensionPopup->setItemEnabled( id, FALSE );
+		doHide = TRUE;
 	    } else if ( w->inherits( "QComboBox" ) ) {
 		QComboBox *c = (QComboBox*)w;
 		if ( c->count() != 0 ) {
@@ -694,6 +695,7 @@
 			        c, SLOT( internalActivate( int ) ) );
 			}
 		    }
+		    doHide = TRUE;
 		}
 	    }
 	}
