diff options
Diffstat (limited to 'experimental/tqtinterface/qt4/src/widgets/tqmenubar.cpp')
-rw-r--r-- | experimental/tqtinterface/qt4/src/widgets/tqmenubar.cpp | 1673 |
1 files changed, 1673 insertions, 0 deletions
diff --git a/experimental/tqtinterface/qt4/src/widgets/tqmenubar.cpp b/experimental/tqtinterface/qt4/src/widgets/tqmenubar.cpp new file mode 100644 index 000000000..aadb3ee79 --- /dev/null +++ b/experimental/tqtinterface/qt4/src/widgets/tqmenubar.cpp @@ -0,0 +1,1673 @@ +/**************************************************************************** +** +** Implementation of TQMenuBar class +** +** Created : 941209 +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +// tqmainwindow.h before tqmenubar.h because of GCC-2.7.* compatibility +// ### could be reorganised by discarding INCLUDE_MENUITEM_DEF and put +// the relevant declarations in a private header? +#include "tqmainwindow.h" +#ifndef TQT_NO_MENUBAR +#include "tqmenubar.h" +#include "tqpopupmenu.h" +#include "tqaccel.h" +#include "tqpainter.h" +#include "tqdrawutil.h" +#include "tqapplication.h" +#include "tqguardedptr.h" +#include "tqlayout.h" +#include "tqcleanuphandler.h" +#include "../kernel/tqinternal_p.h" +#include "tqstyle.h" +#include "tqtimer.h" +#if defined(TQT_ACCESSIBILITY_SUPPORT) +#include "tqaccessible.h" +#endif + +class TQMenuDataData { + // attention: also defined in qmenudata.cpp +public: + TQMenuDataData(); + TQGuardedPtr<TQWidget> aWidget; + int aInt; +}; + +#if defined(TQT_ACCESSIBILITY_SUPPORT) +static bool inMenu = FALSE; +#endif + +#if defined(TQ_WS_X11) +extern int qt_xfocusout_grab_counter; // defined in qapplication_x11.cpp +#endif + +/*! + \class TQMenuBar tqmenubar.h + \brief The TQMenuBar class provides a horizontal menu bar. + + \ingroup application + \mainclass + + A menu bar consists of a list of pull-down menu items. You add + menu items with \link TQMenuData::insertItem() + insertItem()\endlink. For example, asuming that \c menubar is a + pointer to a TQMenuBar and \c filemenu is a pointer to a + TQPopupMenu, the following statement inserts the menu into the menu + bar: + \code + menubar->insertItem( "&File", filemenu ); + \endcode + The ampersand in the menu item's text sets Alt+F as a shortcut for + this menu. (You can use "\&\&" to get a real ampersand in the menu + bar.) + + Items are either enabled or disabled. You toggle their state with + setItemEnabled(). + + There is no need to lay out a menu bar. It automatically sets its + own tqgeometry to the top of the tqparent widget and changes it + appropriately whenever the tqparent is resized. + + \important insertItem removeItem clear insertSeparator setItemEnabled isItemEnabled setItemVisible isItemVisible + + Example of creating a menu bar with menu items (from \l menu/menu.cpp): + \quotefile menu/menu.cpp + \skipto file = new TQPopupMenu + \printline + \skipto Qt::Key_O + \printline + \printline + \skipto new TQMenuBar + \printline + \skipto insertItem + \printline + + In most main window style applications you would use the menuBar() + provided in TQMainWindow, adding \l{TQPopupMenu}s to the menu bar + and adding \l{TQAction}s to the popup menus. + + Example (from \l action/application.cpp): + \quotefile action/application.cpp + \skipto file = new TQPopupMenu + \printuntil fileNewAction + + Menu items can have text and pixmaps (or iconsets), see the + various \link TQMenuData::insertItem() insertItem()\endlink + overloads, as well as separators, see \link + TQMenuData::insertSeparator() insertSeparator()\endlink. You can + also add custom menu items that are derived from + \l{TQCustomMenuItem}. + + Menu items may be removed with removeItem() and enabled or + disabled with \link TQMenuData::setItemEnabled() + setItemEnabled()\endlink. + + <img src=qmenubar-m.png> <img src=qmenubar-w.png> + + \section1 TQMenuBar on TQt/Mac + + TQMenuBar on TQt/Mac is a wrapper for using the system-wide menubar. + If you have multiple menubars in one dialog the outermost menubar + (normally inside a widget with widget flag \c WType_TopLevel) will + be used for the system-wide menubar. + + Note that arbitrary TQt widgets \e cannot be inserted into a + TQMenuBar on the Mac because TQt uses Mac's native menus which don't + support this functionality. This limitation does not apply to + stand-alone TQPopupMenus. + + TQt/Mac also provides a menubar merging feature to make TQMenuBar + conform more closely to accepted Mac OS X menubar tqlayout. The + merging functionality is based on string matching the title of a + TQPopupMenu entry. These strings are translated (using + TQObject::tr()) in the "TQMenuBar" context. If an entry is moved its + Q_SLOTS will still fire as if it was in the original place. The + table below outlines the strings looked for and where the entry is + placed if matched: + + \table + \header \i String matches \i Placement \i Notes + \row \i about.* + \i Application Menu | About <application name> + \i If this entry is not found no About item will appear in + the Application Menu + \row \i config, options, setup, settings or preferences + \i Application Menu | Preferences + \i If this entry is not found the Settings item will be disabled + \row \i quit or exit + \i Application Menu | Quit <application name> + \i If this entry is not found a default Quit item will be + created to call TQApplication::quit() + \endtable + + \link menu-example.html menu/menu.cpp\endlink is an example of + TQMenuBar and TQPopupMenu use. + + \sa TQPopupMenu TQAccel TQAction \link http://developer.apple.com/techpubs/macosx/Carbon/HumanInterfaceToolbox/Aqua/aqua.html Aqua Style Guidelines \endlink \link guibooks.html#fowler GUI Design Handbook: Menu Bar \endlink +*/ + + +/*! + \enum TQMenuBar::Separator + + This enum type is used to decide whether TQMenuBar should draw a + separator line at its bottom. + + \value Never In many applications there is already a separator, + and having two looks wrong. + + \value InWindowsStyle In some other applications a separator looks + good in Windows style, but nowhere else. +*/ + +/*! + \fn void TQMenuBar::activated( int id ) + + This signal is emitted when a menu item is selected; \a id is the + id of the selected item. + + Normally you will connect each menu item to a single slot using + TQMenuData::insertItem(), but sometimes you will want to connect + several items to a single slot (most often if the user selects + from an array). This signal is useful in such cases. + + \sa highlighted(), TQMenuData::insertItem() +*/ + +/*! + \fn void TQMenuBar::highlighted( int id ) + + This signal is emitted when a menu item is highlighted; \a id is + the id of the highlighted item. + + Normally, you will connect each menu item to a single slot using + TQMenuData::insertItem(), but sometimes you will want to connect + several items to a single slot (most often if the user selects + from an array). This signal is useful in such cases. + + \sa activated(), TQMenuData::insertItem() +*/ + + +// Motif style parameters + +static const int motifBarHMargin = 2; // menu bar hor margin to item +static const int motifBarVMargin = 1; // menu bar ver margin to item +static const int motifItemFrame = 2; // menu item frame width +static const int motifItemHMargin = 5; // menu item hor text margin +static const int motifItemVMargin = 4; // menu item ver text margin + +/* + ++----------------------------- +| BarFrame +| +------------------------- +| | V BarMargin +| | +--------------------- +| | H | ItemFrame +| | | +----------------- +| | | | \ +| | | | ^ T E X T ^ | ItemVMargin +| | | | | | / +| | | ItemHMargin +| | +| + +*/ + + +/***************************************************************************** + TQMenuBar member functions + *****************************************************************************/ + + +/*! + Constructs a menu bar called \a name with tqparent \a tqparent. +*/ +TQMenuBar::TQMenuBar( TQWidget *tqparent, const char *name ) + : TQFrame( tqparent, name, TQt::WNoAutoErase ) +{ +#if defined( TQ_WS_MAC ) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + mac_eaten_menubar = FALSE; + mac_d = 0; + macCreateNativeMenubar(); +#endif + isMenuBar = TRUE; +#ifndef TQT_NO_ACCEL + autoaccel = 0; +#endif + irects = 0; + rightSide = 0; // Right of here is right-aligned content + mseparator = 0; + waitforalt = 0; + popupvisible = 0; + hasmouse = 0; + defaultup = 0; + toggleclose = 0; + pendingDelayedContentsChanges = 0; + pendingDelayedStateChanges = 0; + if ( tqparent ) { + // filter tqparent events for resizing + tqparent->installEventFilter( this ); + + // filter top-level-widget events for accelerators + TQWidget *tlw = tqtopLevelWidget(); + if ( tlw != tqparent ) + tlw->installEventFilter( this ); + } + installEventFilter( this ); + + setBackgroundMode( TQt::PaletteButton ); + setFrameStyle( TQFrame::MenuBarPanel | TQFrame::Raised ); + + TQFontMetrics fm = fontMetrics(); + int h = 2*motifBarVMargin + fm.height() + motifItemVMargin + 2*frameWidth() + 2*motifItemFrame; + + setGeometry( 0, 0, width(), h ); + + setMouseTracking( tqstyle().tqstyleHint(TQStyle::SH_MenuBar_MouseTracking) ); +} + + + +/*! \reimp */ + +void TQMenuBar::styleChange( TQStyle& old ) +{ + setMouseTracking( tqstyle().tqstyleHint(TQStyle::SH_MenuBar_MouseTracking) ); + TQFrame::styleChange( old ); +} + + + +/*! + Destroys the menu bar. +*/ + +TQMenuBar::~TQMenuBar() +{ +#ifndef TQT_NO_ACCEL + delete autoaccel; +#endif +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + macRemoveNativeMenubar(); +#endif + if ( irects ) // Avoid purify complaint. + delete [] irects; +} + +/*! + \internal + + Repaints the menu item with id \a id; does nothing if there is no + such menu item. +*/ +void TQMenuBar::updateItem( int id ) +{ + int i = indexOf( id ); + if ( i >= 0 && irects ) + tqrepaint( irects[i], FALSE ); +} + +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) +static bool fromFrameChange = FALSE; +#endif + +/*! + Recomputes the menu bar's display data according to the new + contents. + + You should never need to call this; it is called automatically by + TQMenuData whenever it needs to be called. +*/ + +void TQMenuBar::menuContentsChanged() +{ + // here the part that can't be delayed + TQMenuData::menuContentsChanged(); + badSize = TRUE; // might change the size + if( pendingDelayedContentsChanges ) + return; + pendingDelayedContentsChanges = 1; + if( !pendingDelayedStateChanges )// if the timer hasn't been started yet + TQTimer::singleShot( 0, this, TQT_SLOT(performDelayedChanges())); +} + +void TQMenuBar::performDelayedContentsChanged() +{ + pendingDelayedContentsChanges = 0; + // here the part the can be delayed +#ifndef TQT_NO_ACCEL + // if performDelayedStateChanged() will be called too, + // it will call setupAccelerators() too, no need to do it twice + if( !pendingDelayedStateChanges ) + setupAccelerators(); +#endif + calculateRects(); + if ( isVisible() ) { + update(); +#ifndef TQT_NO_MAINWINDOW + TQMainWindow *mw = ::tqqt_cast<TQMainWindow*>(tqparent()); + if ( mw ) { + mw->triggerLayout(); + mw->update(); + } +#endif +#ifndef TQT_NO_LAYOUT + if ( parentWidget() && parentWidget()->tqlayout() ) + parentWidget()->tqlayout()->activate(); +#endif + } +} + +/*! + Recomputes the menu bar's display data according to the new state. + + You should never need to call this; it is called automatically by + TQMenuData whenever it needs to be called. +*/ + +void TQMenuBar::menuStateChanged() +{ + if( pendingDelayedStateChanges ) + return; + pendingDelayedStateChanges = 1; + if( !pendingDelayedContentsChanges ) // if the timer hasn't been started yet + TQTimer::singleShot( 0, this, TQT_SLOT(performDelayedChanges())); +} + +void TQMenuBar::performDelayedStateChanged() +{ + pendingDelayedStateChanges = 0; + // here the part that can be delayed +#ifndef TQT_NO_ACCEL + setupAccelerators(); // ### when we have a good solution for the accel vs. focus + // widget problem, remove that. That is only a workaround + // if you remove this, see performDelayedContentsChanged() +#endif + update(); +} + + +void TQMenuBar::performDelayedChanges() +{ +#if defined(TQ_WS_MAC) && !defined(TQMAC_MENUBAR_NO_NATIVE) + // I must do this here as the values change in the function below. + bool needMacUpdate = (pendingDelayedContentsChanges || pendingDelayedStateChanges); +#endif + if( pendingDelayedContentsChanges ) + performDelayedContentsChanged(); + if( pendingDelayedStateChanges ) + performDelayedStateChanged(); +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + if(mac_eaten_menubar && needMacUpdate) { + macDirtyNativeMenubar(); + + bool all_hidden = TRUE; + if(irects) { + for(int i = 0; all_hidden && i < (int)mitems->count(); i++) + all_hidden = irects[i].isEmpty(); + } + if( all_hidden ) { + if( !isHidden()) + hide(); + } else { + if( !isShown() && !fromFrameChange ) + show(); + } + } +#endif +} + + +void TQMenuBar::menuInsPopup( TQPopupMenu *popup ) +{ + connect( popup, TQT_SIGNAL(activatedRedirect(int)), + TQT_SLOT(subActivated(int)) ); + connect( popup, TQT_SIGNAL(highlightedRedirect(int)), + TQT_SLOT(subHighlighted(int)) ); + connect( popup, TQT_SIGNAL(destroyed(TQObject*)), + this, TQT_SLOT(popupDestroyed(TQObject*)) ); +} + +void TQMenuBar::menuDelPopup( TQPopupMenu *popup ) +{ + popup->disconnect( TQT_SIGNAL(activatedRedirect(int)) ); + popup->disconnect( TQT_SIGNAL(highlightedRedirect(int)) ); + disconnect( popup, TQT_SIGNAL(destroyed(TQObject*)), + this, TQT_SLOT(popupDestroyed(TQObject*)) ); +} + +void TQMenuBar::frameChanged() +{ +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + fromFrameChange = TRUE; +#endif + menuContentsChanged(); +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + fromFrameChange = FALSE; +#endif +} + +void TQMenuBar::languageChange() +{ + menuContentsChanged(); +} + +/*! + \internal + + This function is used to adjust the menu bar's tqgeometry to the + tqparent widget's tqgeometry. Note that this is \e not part of the + public interface - the function is \c public only because + TQObject::eventFilter() is. + + Resizes the menu bar to fit in the tqparent widget when the tqparent + receives a resize event. +*/ + +bool TQMenuBar::eventFilter( TQObject *object, TQEvent *event ) +{ + if ( object == tqparent() && object +#ifndef TQT_NO_TOOLBAR + && !::tqqt_cast<TQToolBar*>(object) +#endif + && event->type() == TQEvent::Resize ) { + TQResizeEvent *e = (TQResizeEvent *)event; + int w = e->size().width(); + setGeometry( 0, y(), w, heightForWidth(w) ); + return FALSE; + } + + if ( !isVisible() || !object->isWidgetType() ) + return FALSE; + + if ( TQT_BASE_OBJECT(object) == TQT_BASE_OBJECT(this) && event->type() == TQEvent::LanguageChange ) { + badSize = TRUE; + calculateRects(); + return FALSE; + } else if ( event->type() == TQEvent::MouseButtonPress || + event->type() == TQEvent::MouseButtonRelease ) { + waitforalt = 0; + return FALSE; + } else if ( waitforalt && event->type() == TQEvent::FocusOut ) { + // some window systems/managers use alt/meta as accelerator keys + // for switching between windows/desktops/etc. If the focus + // widget gets unfocused, then we need to stop waiting for alt + // NOTE: this event came from the real focus widget, so we don't + // need to touch the event filters + waitforalt = 0; + // although the comment above said not to remove the event filter, it is + // incorrect. We need to remove our self fom the focused widget as normally + // this happens in the key release but it does not happen in this case + TQWidget * f = ((TQWidget *)object)->tqfocusWidget(); + if (f) + f->removeEventFilter( this ); + return FALSE; + } else if ( !( event->type() == TQEvent::Accel || + event->type() == TQEvent::AccelOverride || + event->type() == TQEvent::KeyPress || + event->type() == TQEvent::KeyRelease ) || + !tqstyle().tqstyleHint(TQStyle::SH_MenuBar_AltKeyNavigation, this) ) { + return FALSE; + } + + TQKeyEvent * ke = (TQKeyEvent *) event; +#ifndef TQT_NO_ACCEL + // look for Alt press and Alt-anything press + if ( event->type() == TQEvent::Accel ) { + TQWidget * f = ((TQWidget *)object)->tqfocusWidget(); + // ### this thinks alt and meta are the same + if ( ke->key() == Qt::Key_Alt || ke->key() == Qt::Key_Meta ) { + // A new Alt press and we wait for release, eat + // this key and don't wait for Alt on this widget + if ( waitforalt ) { + waitforalt = 0; + if ( object->tqparent() ) + object->removeEventFilter( this ); + ke->accept(); + return TRUE; + // Menu has focus, send focus back + } else if ( hasFocus() ) { + setAltMode( FALSE ); + ke->accept(); + return TRUE; + // Start waiting for Alt release on focus widget + } else if ( ke->stateAfter() == TQt::AltButton ) { + waitforalt = 1; +#if defined(TQ_WS_X11) + TQMenuData::d->aInt = qt_xfocusout_grab_counter; +#endif + if ( f && TQT_TQOBJECT(f) != object ) + f->installEventFilter( this ); + } + // Other modifiers kills focus on menubar + } else if ( ke->key() == Qt::Key_Control || ke->key() == Qt::Key_Shift) { + setAltMode( FALSE ); + // Got other key, no need to wait for Alt release + } else { + waitforalt = 0; + } + // ### ! block all accelerator events when the menu bar is active + if ( tqApp && tqApp->tqfocusWidget() == this ) { + return TRUE; + } + + return FALSE; + } +#endif + // look for Alt release + if ( TQT_TQOBJECT(((TQWidget*)object)->tqfocusWidget()) == object || + (object->tqparent() == 0 && ((TQWidget*)object)->tqfocusWidget() == 0) ) { + if ( waitforalt && event->type() == TQEvent::KeyRelease && + ( ke->key() == Qt::Key_Alt || ke->key() == Qt::Key_Meta ) +#if defined(TQ_WS_X11) + && TQMenuData::d->aInt == qt_xfocusout_grab_counter +#endif + ) { + setAltMode( TRUE ); + if ( object->tqparent() ) + object->removeEventFilter( this ); + TQWidget * tlw = ((TQWidget *)object)->tqtopLevelWidget(); + if ( tlw ) { + // ### ! + // make sure to be the first event filter, so we can kill + // accelerator events before the accelerators get to them. + tlw->removeEventFilter( this ); + tlw->installEventFilter( this ); + } + return TRUE; + // Cancel if next keypress is NOT Alt/Meta, + } else if ( !hasFocus() && (event->type() == TQEvent::AccelOverride ) && + !(((TQKeyEvent *)event)->key() == Qt::Key_Alt || + ((TQKeyEvent *)event)->key() == Qt::Key_Meta) ) { + if ( object->tqparent() ) + object->removeEventFilter( this ); + setAltMode( FALSE ); + } + } + + return FALSE; // don't stop event +} + + + +/*! + \internal + Receives Q_SIGNALS from menu items. +*/ + +void TQMenuBar::subActivated( int id ) +{ + emit activated( id ); +} + +/*! + \internal + Receives Q_SIGNALS from menu items. +*/ + +void TQMenuBar::subHighlighted( int id ) +{ + emit highlighted( id ); +} + +/*! + \internal + Receives Q_SIGNALS from menu accelerator. +*/ +#ifndef TQT_NO_ACCEL +void TQMenuBar::accelActivated( int id ) +{ +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + if(mac_eaten_menubar) + return; +#endif + if ( !isEnabled() ) // the menu bar is disabled + return; + setAltMode( TRUE ); + setActiveItem( indexOf( id ) ); +} +#endif + +/*! + \internal + This slot receives Q_SIGNALS from menu accelerator when it is about to be + destroyed. +*/ +#ifndef TQT_NO_ACCEL +void TQMenuBar::accelDestroyed() +{ + autoaccel = 0; // don't delete it twice! +} +#endif + +void TQMenuBar::popupDestroyed( TQObject *o ) +{ + removePopup( (TQPopupMenu*)o ); +} + +bool TQMenuBar::tryMouseEvent( TQPopupMenu *, TQMouseEvent *e ) +{ + TQPoint pos = mapFromGlobal( e->globalPos() ); + if ( !TQT_TQRECT_OBJECT(rect()).tqcontains( pos ) ) // outside + return FALSE; + int item = itemAtPos( pos ); + if ( item == -1 && (e->type() == TQEvent::MouseButtonPress || + e->type() == TQEvent::MouseButtonRelease) ) { + hidePopups(); + goodbye(); + return FALSE; + } + TQMouseEvent ee( e->type(), pos, e->globalPos(), e->button(), e->state() ); + event( &ee ); + return TRUE; +} + + +void TQMenuBar::tryKeyEvent( TQPopupMenu *, TQKeyEvent *e ) +{ + event( e ); +} + + +void TQMenuBar::goodbye( bool cancelled ) +{ + mouseBtDn = FALSE; + popupvisible = 0; + setAltMode( cancelled && tqstyle().tqstyleHint(TQStyle::SH_MenuBar_AltKeyNavigation, this) ); +} + + +void TQMenuBar::openActPopup() +{ +#if defined(TQT_ACCESSIBILITY_SUPPORT) + if ( !inMenu ) { + TQAccessible::updateAccessibility( this, 0, TQAccessible::MenuStart ); + inMenu = TRUE; + } +#endif + + if ( actItem < 0 ) + return; + TQPopupMenu *popup = mitems->at(actItem)->popup(); + if ( !popup || !popup->isEnabled() ) + return; + + TQRect r = tqitemRect( actItem ); + bool reverse = TQApplication::reverseLayout(); + const int yoffset = 1; //(tqstyle().tqstyleHint( TQStyle::SH_GUIStyle ) == TQStyle::WindowsStyle) ? 4 : 1; ### this breaks designer mainwindow editing + TQPoint pos = r.bottomLeft() + TQPoint(0,yoffset); + if( reverse ) { + pos = r.bottomRight() + TQPoint(0,yoffset); + pos.rx() -= popup->tqsizeHint().width(); + } + + int ph = popup->tqsizeHint().height(); + pos = mapToGlobal(pos); + int sh = TQApplication::desktop()->height(); + if ( defaultup || (pos.y() + ph > sh) ) { + TQPoint t = mapToGlobal( r.topLeft() ); + if( reverse ) { + t = mapToGlobal( r.topRight() ); + t.rx() -= popup->tqsizeHint().width(); + } + t.ry() -= (TQCOORD)ph; + if ( !defaultup || t.y() >= 0 ) + pos = t; + } + + //avoid circularity + if ( popup->isVisible() ) + return; + + TQ_ASSERT( popup->parentMenu == 0 ); + popup->parentMenu = this; // set tqparent menu + + popup->snapToMouse = FALSE; + popup->popup( pos ); + popup->snapToMouse = TRUE; +} + +/*! + \internal + Hides all popup menu items. +*/ + +void TQMenuBar::hidePopups() +{ +#if defined(TQT_ACCESSIBILITY_SUPPORT) + bool anyVisible = FALSE; +#endif + TQMenuItemListIt it(*mitems); + register TQMenuItem *mi; + while ( (mi=it.current()) ) { + ++it; + if ( mi->popup() && mi->popup()->isVisible() ) { +#if defined(TQT_ACCESSIBILITY_SUPPORT) + anyVisible = TRUE; +#endif + mi->popup()->hide(); + } + } +#if defined(TQT_ACCESSIBILITY_SUPPORT) + if ( !popupvisible && anyVisible && inMenu ) { + TQAccessible::updateAccessibility( this, 0, TQAccessible::MenuEnd ); + inMenu = FALSE; + } +#endif +} + + +/*! + Reimplements TQWidget::show() in order to set up the correct + keyboard accelerators and to raise itself to the top of the widget + stack. +*/ + +void TQMenuBar::show() +{ +#ifndef TQT_NO_ACCEL + setupAccelerators(); +#endif + + if ( parentWidget() ) + resize( parentWidget()->width(), height() ); + + TQApplication::sendPostedEvents( this, TQEvent::Resize ); + performDelayedChanges(); + calculateRects(); + +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + if(mac_eaten_menubar) { + //If all elements are invisible no reason for me to be visible either + bool all_hidden = TRUE; + if(irects) { + for(int i = 0; all_hidden && i < (int)mitems->count(); i++) + all_hidden = irects[i].isEmpty(); + } + if(all_hidden) + TQWidget::hide(); + else + TQWidget::show(); + } else { + TQWidget::show(); + } +#else + TQWidget::show(); +#endif + +#ifndef TQT_NO_MAINWINDOW + TQMainWindow *mw = ::tqqt_cast<TQMainWindow*>(tqparent()); + if ( mw ) //### ugly workaround + mw->triggerLayout(); +#endif + raise(); +} + +/*! + Reimplements TQWidget::hide() in order to deselect any selected + item, and calls setUpLayout() for the main window. +*/ + +void TQMenuBar::hide() +{ + TQWidget::hide(); + setAltMode( FALSE ); + hidePopups(); +#ifndef TQT_NO_MAINWINDOW + TQMainWindow *mw = ::tqqt_cast<TQMainWindow*>(tqparent()); + if ( mw ) //### ugly workaround + mw->triggerLayout(); +#endif +} + +/*! + \internal + Needs to change the size of the menu bar when a new font is set. +*/ + +void TQMenuBar::fontChange( const TQFont & f ) +{ + badSize = TRUE; + updateGeometry(); + if ( isVisible() ) + calculateRects(); + TQWidget::fontChange( f ); +} + + +/***************************************************************************** + Item tqgeometry functions + *****************************************************************************/ + +/* + This function serves two different purposes. If the parameter is + negative, it updates the irects member for the current width and + resizes. Otherwise, it does the same calculations for the GIVEN + width and returns the height to which it WOULD have resized. A bit + tricky, but both operations require almost identical steps. +*/ +int TQMenuBar::calculateRects( int max_width ) +{ + polish(); + bool update = ( max_width < 0 ); + + if ( update ) { + rightSide = 0; + if ( !badSize ) // size was not changed + return 0; + delete [] irects; + int i = mitems->count(); + if ( i == 0 ) { + irects = 0; + } else { + irects = new TQRect[ i ]; + TQ_CHECK_PTR( irects ); + } + max_width = width(); + } + TQFontMetrics fm = fontMetrics(); + int max_height = 0; + int max_item_height = 0; + int nlitems = 0; // number on items on cur line + int gs = tqstyle().tqstyleHint(TQStyle::SH_GUIStyle); + bool reverse = TQApplication::reverseLayout(); + int x = frameWidth(); + int y = frameWidth(); + if ( gs == TQt::MotifStyle ) { + x += motifBarHMargin; + y += motifBarVMargin; + } else if ( tqstyle().inherits("TQWindowsXPStyle") && tqstyle().tqstyleHint(TQStyle::SH_TitleBar_NoBorder) ) { + ; + } else if ( gs == TQt::WindowsStyle ) { + x += 2; + y += 2; + } + if ( reverse ) + x = max_width - x; + + int i = 0; + int separator = -1; + const int itemSpacing = tqstyle().tqpixelMetric(TQStyle::PM_MenuBarItemSpacing); + const int lastItem = reverse ? 0 : mitems->count() - 1; + + while ( i < (int)mitems->count() ) { // for each menu item... + TQMenuItem *mi = mitems->at(i); + + int w=0, h=0; + if ( !mi->isVisible() +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + || (mac_eaten_menubar && !mi->custom() && !mi->widget() ) +#endif + ) { + ; // empty rectangle + } else if ( mi->widget() ) { + if ( mi->widget()->parentWidget() != this ) { + mi->widget()->reparent( this, TQPoint(0,0) ); + } + w = mi->widget()->tqsizeHint().expandedTo( TQApplication::globalStrut() ).width()+2; + h = mi->widget()->tqsizeHint().expandedTo( TQApplication::globalStrut() ).height()+2; + if ( i && separator < 0 ) + separator = i; + } else if ( mi->pixmap() ) { // pixmap item + w = TQMAX( mi->pixmap()->width() + 4, TQApplication::globalStrut().width() ); + h = TQMAX( mi->pixmap()->height() + 4, TQApplication::globalStrut().height() ); + } else if ( !mi->text().isNull() ) { // text item + TQString s = mi->text(); + w = fm.boundingRect( s ).width() + + 2*motifItemHMargin; + w -= s.tqcontains('&')*fm.width('&'); + w += s.tqcontains("&&")*fm.width('&'); + w = TQMAX( w, TQApplication::globalStrut().width() ); + h = TQMAX( fm.height() + motifItemVMargin, TQApplication::globalStrut().height() ); + } else if ( mi->isSeparator() ) { // separator item + if ( tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle ) + separator = i; //### only motif? + } + if ( !mi->isSeparator() || mi->widget() ) { +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + if ( !mac_eaten_menubar ) { +#endif + if ( gs == TQt::MotifStyle && mi->isVisible() ) { + w += 2*motifItemFrame; + h += 2*motifItemFrame; + } +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + } +#endif + + if ( ( ( !reverse && x + w + frameWidth() - max_width > 0 ) || + ( reverse && x - w - itemSpacing - frameWidth() < 0 ) ) + && nlitems > 0 ) { + nlitems = 0; + x = frameWidth(); + y += h; + if ( gs == TQt::MotifStyle ) { + x += motifBarHMargin; + y += motifBarVMargin; + } + if ( reverse ) + x = max_width - x + itemSpacing; + if ( tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle ) + separator = -1; + } + if ( y + h + 2*frameWidth() > max_height ) + max_height = y + h + 2*frameWidth(); + if ( h > max_item_height ) + max_item_height = h; + } + + const bool isLast = (i == lastItem); + + if( reverse ) { + x -= w; + if (!isLast && !mi->isSeparator()) + x -= itemSpacing; + } + if ( update ) { + irects[i].setRect( x, y, w, h ); + } + if ( !reverse ) { + x += w; + if (!isLast && !mi->isSeparator()) + x += itemSpacing; + } + nlitems++; + i++; + } + if ( gs == TQt::WindowsStyle ) { + max_height += 2; + max_width += 2; + } + + if ( update ) { + if ( separator >= 0 ) { + int moveBy = reverse ? - x - frameWidth() : max_width - x - frameWidth(); + rightSide = x; + while( --i >= separator ) { + irects[i].moveBy( moveBy, 0 ); + } + } else { + rightSide = width()-frameWidth(); + } + if ( max_height != height() ) + resize( width(), max_height ); + for ( i = 0; i < (int)mitems->count(); i++ ) { + irects[i].setHeight( max_item_height ); + TQMenuItem *mi = mitems->at(i); + if ( mi->widget() ) { + TQRect r ( TQPoint(0,0), mi->widget()->tqsizeHint() ); + r.moveCenter( irects[i].center() ); + mi->widget()->setGeometry( r ); + if( mi->widget()->isHidden() ) + mi->widget()->show(); + } + } + badSize = FALSE; + } + + return max_height; +} + +/*! + Returns the height that the menu would resize itself to if its + tqparent (and hence itself) resized to the given \a max_width. This + can be useful for simple tqlayout tasks in which the height of the + menu bar is needed after items have been inserted. See \l + showimg/showimg.cpp for an example of the usage. +*/ +int TQMenuBar::heightForWidth(int max_width) const +{ + // Okay to cast away const, as we are not updating. + if ( max_width < 0 ) max_width = 0; + return ((TQMenuBar*)this)->calculateRects( max_width ); +} + +/*! + \internal + Return the bounding rectangle for the menu item at position \a index. +*/ + +TQRect TQMenuBar::tqitemRect( int index ) +{ + calculateRects(); + return irects ? irects[index] : TQRect(0,0,0,0); +} + +/*! + \internal + Return the item at \a pos, or -1 if there is no item there or if + it is a separator item. +*/ + +int TQMenuBar::itemAtPos( const TQPoint &pos_ ) +{ + calculateRects(); + if ( !irects ) + return -1; + int i = 0; + TQPoint pos = pos_; + // Fitts' Law for edges - compensate for the extra margin + // added in calculateRects() + const int margin = 2; + pos.setX( TQMAX( margin, TQMIN( width() - margin, pos.x()))); + pos.setY( TQMAX( margin, TQMIN( height() - margin, pos.y()))); + while ( i < (int)mitems->count() ) { + if ( !irects[i].isEmpty() && irects[i].tqcontains( pos ) ) { + TQMenuItem *mi = mitems->at(i); + return mi->isSeparator() ? -1 : i; + } + ++i; + } + return -1; // no match +} + + +/*! + \property TQMenuBar::separator + \brief in which cases a menubar sparator is drawn + + \obsolete +*/ +void TQMenuBar::setSeparator( Separator when ) +{ + mseparator = when; +} + +TQMenuBar::Separator TQMenuBar::separator() const +{ + return mseparator ? InWindowsStyle : Never; +} + +/***************************************************************************** + Event handlers + *****************************************************************************/ + +/*! + Called from TQFrame::paintEvent(). Draws the menu bar contents + using painter \a p. +*/ + +void TQMenuBar::drawContents( TQPainter *p ) +{ + performDelayedChanges(); + TQRegion reg( contentsRect() ); + TQColorGroup g = tqcolorGroup(); + bool e; + + // this shouldn't happen + if ( !irects ) + return; + + for ( int i=0; i<(int)mitems->count(); i++ ) { + TQMenuItem *mi = mitems->at( i ); + if ( !mi->text().isNull() || mi->pixmap() ) { + TQRect r = irects[i]; + if(r.isEmpty() || !mi->isVisible()) + continue; + e = mi->isEnabledAndVisible(); + if ( e ) + g = isEnabled() ? ( isActiveWindow() ? tqpalette().active() : + tqpalette().inactive() ) : tqpalette().disabled(); + else + g = tqpalette().disabled(); + reg = reg.subtract( r ); + TQSharedDoubleBuffer buffer( p, r ); + buffer.painter()->setFont( p->font() ); + buffer.painter()->setPen( p->pen() ); + buffer.painter()->setBrush( p->brush() ); + + TQStyle::SFlags flags = TQStyle::Style_Default; + if (isEnabled() && e) + flags |= TQStyle::Style_Enabled; + if ( i == actItem ) + flags |= TQStyle::Style_Active; + if ( actItemDown ) + flags |= TQStyle::Style_Down; + if (hasFocus() || hasmouse || popupvisible) + flags |= TQStyle::Style_HasFocus; + tqstyle().tqdrawControl(TQStyle::CE_MenuBarItem, buffer.painter(), this, + r, g, flags, TQStyleOption(mi)); + } + } + + p->save(); + p->setClipRegion(reg); + tqstyle().tqdrawControl(TQStyle::CE_MenuBarEmptyArea, p, this, contentsRect(), g); + p->restore(); + +#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE) + if ( !mac_eaten_menubar ) +#endif + { + TQt::GUIStyle gs = (TQt::GUIStyle) tqstyle().tqstyleHint(TQStyle::SH_GUIStyle); + if ( mseparator == InWindowsStyle && gs == TQt::WindowsStyle ) { + p->setPen( g.light() ); + p->drawLine( 0, height()-1, width()-1, height()-1 ); + p->setPen( g.dark() ); + p->drawLine( 0, height()-2, width()-1, height()-2 ); + } + } +} + + +/*! + \reimp +*/ +void TQMenuBar::mousePressEvent( TQMouseEvent *e ) +{ + if ( e->button() != Qt::LeftButton ) + return; + mouseBtDn = TRUE; // mouse button down + int item = itemAtPos( e->pos() ); + if ( item == actItem && popupvisible ) + toggleclose = 1; + if ( item >= 0 ) { +#ifndef USE_QT4 + TQFocusEvent::Reason oldReason = TQFocusEvent::reason(); +#endif // USE_QT4 + TQMenuItem *mi = tqfindItem( idAt( item ) ); + // we know that a popup will open, so set the reason to avoid + // itemviews to redraw their selections + if ( mi && mi->popup() ) +#ifdef USE_QT4 +#warning [FIXME] How can TQFocusEvent::Popup be set as the reason for the setAltMode call? +#else // USE_QT4 + TQFocusEvent::setReason( TQFocusEvent::Popup ); +#endif // USE_QT4 + setAltMode( TRUE ); +#ifndef USE_QT4 + TQFocusEvent::setReason( oldReason ); +#endif // USE_QT4 + } + setActiveItem( item, TRUE, FALSE ); +} + + +/*! + \reimp +*/ +void TQMenuBar::mouseReleaseEvent( TQMouseEvent *e ) +{ + if ( e->button() != Qt::LeftButton ) + return; + if ( !mouseBtDn ) + return; + mouseBtDn = FALSE; // mouse button up + int item = itemAtPos( e->pos() ); + if ( (item >= 0 && !mitems->at(item)->isEnabledAndVisible()) || + (actItem >= 0 && !mitems->at(actItem)->isEnabledAndVisible()) ) { + hidePopups(); + setActiveItem( -1 ); + return; + } + bool showMenu = TRUE; + if ( toggleclose && + // pressing an item twice closes in windows, but not in motif :/ + tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::WindowsStyle && + actItem == item ) { + showMenu = FALSE; + setAltMode( FALSE ); + } + setActiveItem( item, showMenu, !hasMouseTracking() ); + toggleclose = 0; +} + + +/*! + \reimp +*/ +void TQMenuBar::mouseMoveEvent( TQMouseEvent *e ) +{ + int item = itemAtPos( e->pos() ); + if ( !mouseBtDn && !popupvisible) { + if ( item >= 0 ) { + if ( !hasmouse ) { + hasmouse = 1; + if ( actItem == item ) + actItem = -1; // trigger update + } + } + setActiveItem( item, FALSE, FALSE ); + return; + } + if ( item != actItem && item >= 0 && ( popupvisible || mouseBtDn ) ) + setActiveItem( item, TRUE, FALSE ); +} + + +/*! + \reimp +*/ +void TQMenuBar::leaveEvent( TQEvent * e ) +{ + hasmouse = 0; + int actId = idAt( actItem ); + if ( !hasFocus() && !popupvisible ) + actItem = -1; + updateItem( actId ); + TQFrame::leaveEvent( e ); +} + + +/*! + \reimp +*/ +void TQMenuBar::keyPressEvent( TQKeyEvent *e ) +{ + if ( actItem < 0 ) + return; + + TQMenuItem *mi = 0; + int dx = 0; + + if ( e->state() & ControlButton && + ( e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab ) ) + { + e->ignore(); + return; + } + + switch ( e->key() ) { + case Qt::Key_Left: + dx = TQApplication::reverseLayout() ? 1 : -1; + break; + + case Qt::Key_Right: + case Qt::Key_Tab: + dx = TQApplication::reverseLayout() ? -1 : 1; + break; + + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Enter: + case Qt::Key_Return: + if ( tqstyle().tqstyleHint(TQStyle::SH_MenuBar_AltKeyNavigation) ) + setActiveItem( actItem ); + break; + + case Key_Escape: + setAltMode( FALSE ); + break; + } + + if ( dx ) { // highlight next/prev + register int i = actItem; + int c = mitems->count(); + int n = c; + while ( n-- ) { + i = i + dx; + if ( i == c ) + i = 0; + else if ( i < 0 ) + i = c - 1; + mi = mitems->at( i ); + // ### fix windows-style traversal - currently broken due to + // TQMenuBar's reliance on TQPopupMenu + if ( /* (tqstyle() == TQt::WindowsStyle || */ mi->isEnabledAndVisible() /* ) */ + && !mi->isSeparator() ) + break; + } + setActiveItem( i, popupvisible ); + } else if ( ( !e->state() || (e->state()&(TQt::MetaButton|TQt::AltButton)) ) && e->text().length()==1 && !popupvisible ) { + TQChar c = TQT_TQCHAR(e->text()[0]).upper(); + + TQMenuItemListIt it(*mitems); + TQMenuItem* first = 0; + TQMenuItem* currentSelected = 0; + TQMenuItem* firstAfterCurrent = 0; + + register TQMenuItem *m; + int indx = 0; + int clashCount = 0; + while ( (m=it.current()) ) { + ++it; + TQString s = m->text(); + if ( !s.isEmpty() ) { + int i = s.tqfind( '&' ); + if ( i >= 0 ) + { + if ( s[i+1].upper() == c ) { + clashCount++; + if ( !first ) + first = m; + if ( indx == actItem ) + currentSelected = m; + else if ( !firstAfterCurrent && currentSelected ) + firstAfterCurrent = m; + } + } + } + indx++; + } + if ( 0 == clashCount ) { + return; + } else if ( 1 == clashCount ) { + indx = indexOf( first->id() ); + } else { + // If there's clashes and no one is selected, use first one + // or if there is no clashes _after_ current, use first one + if ( !currentSelected || (currentSelected && !firstAfterCurrent)) + indx = indexOf( first->id() ); + else + indx = indexOf( firstAfterCurrent->id() ); + } + + setActiveItem( indx ); + } +} + + +/*! + \reimp +*/ +void TQMenuBar::resizeEvent( TQResizeEvent *e ) +{ + TQFrame::resizeEvent( e ); + if ( badSize ) + return; + badSize = TRUE; + calculateRects(); +} + +/* + Sets actItem to \a i and calls tqrepaint for the changed things. + + Takes care to optimize the repainting. Assumes that + calculateRects() has been called as appropriate. +*/ + +void TQMenuBar::setActiveItem( int i, bool show, bool activate_first_item ) +{ + if ( i == actItem && (uint)show == popupvisible ) + return; + + TQMenuItem* mi = 0; + if ( i >= 0 ) + mi = mitems->at( i ); + if ( mi && !mi->isEnabledAndVisible() ) + return; + + popupvisible = i >= 0 ? (show) : 0; + actItemDown = popupvisible; + + if ( i < 0 || actItem < 0 ) { + // just one item needs repainting + int n = TQMAX( actItem, i ); + actItem = i; + if ( irects && n >= 0 ) + tqrepaint( irects[n], FALSE ); + } else if ( TQABS(i-actItem) == 1 ) { + // two neighbouring items need repainting + int o = actItem; + actItem = i; + if ( irects ) + tqrepaint( irects[i].unite( irects[o] ), FALSE ); + } else { + // two non-neighbouring items need repainting + int o = actItem; + actItem = i; + if ( irects ) { + tqrepaint( irects[o], FALSE ); + tqrepaint( irects[i], FALSE ); + } + } + + hidePopups(); + + if ( !popupvisible && actItem >= 0 && irects ) { + TQRect mfrect = irects[actItem]; + setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE ); + } + +#if defined(TQT_ACCESSIBILITY_SUPPORT) + if ( mi ) + TQAccessible::updateAccessibility( this, indexOf( mi->id() )+1, TQAccessible::Focus ); +#endif + + if ( actItem < 0 || !popupvisible || !mi ) + return; + + TQPopupMenu *popup = mi->popup(); + if ( popup ) { + emit highlighted( mi->id() ); + openActPopup(); + if ( activate_first_item ) + popup->setFirstItemActive(); + } else { // not a popup + goodbye( FALSE ); + if ( mi->signal() ) // activate signal + mi->signal()->activate(); + emit activated( mi->id() ); + } +} + + +void TQMenuBar::setAltMode( bool enable ) +{ +#if defined(TQT_ACCESSIBILITY_SUPPORT) + if ( inMenu && !enable ) { + TQAccessible::updateAccessibility( this, 0, TQAccessible::MenuEnd ); + inMenu = FALSE; + } else if ( !inMenu && enable ) { + TQAccessible::updateAccessibility( this, 0, TQAccessible::MenuStart ); + inMenu = TRUE; + } +#endif + + waitforalt = 0; + actItemDown = FALSE; + if ( enable ) { + if ( !TQMenuData::d->aWidget ) + TQMenuData::d->aWidget = tqApp->tqfocusWidget(); + setFocus(); + updateItem( idAt( actItem ) ); + } else { + // set the focus back to the previous widget if + // we still have the focus. + if ( tqApp->tqfocusWidget() == this ) { + if ( TQMenuData::d->aWidget ) + TQMenuData::d->aWidget->setFocus(); + else + clearFocus(); + } + int actId = idAt( actItem ); + actItem = -1; + updateItem( actId ); + TQMenuData::d->aWidget = 0; + } +} + +/*! + Sets up keyboard accelerators for the menu bar. +*/ +#ifndef TQT_NO_ACCEL + +void TQMenuBar::setupAccelerators() +{ + delete autoaccel; + autoaccel = 0; + + TQMenuItemListIt it(*mitems); + register TQMenuItem *mi; + while ( (mi=it.current()) ) { + ++it; + if ( !mi->isEnabledAndVisible() ) // ### when we have a good solution for the accel vs. focus widget problem, remove that. That is only a workaround + continue; + TQString s = mi->text(); + if ( !s.isEmpty() ) { + int i = TQAccel::shortcutKey( s ); + if ( i ) { + if ( !autoaccel ) { + autoaccel = new TQAccel( this ); + TQ_CHECK_PTR( autoaccel ); + autoaccel->setIgnoreWhatsThis( TRUE ); + connect( autoaccel, TQT_SIGNAL(activated(int)), + TQT_SLOT(accelActivated(int)) ); + connect( autoaccel, TQT_SIGNAL(activatedAmbiguously(int)), + TQT_SLOT(accelActivated(int)) ); + connect( autoaccel, TQT_SIGNAL(destroyed()), + TQT_SLOT(accelDestroyed()) ); + } + autoaccel->insertItem( i, mi->id() ); + } + } + if ( mi->popup() ) { + TQPopupMenu* popup = mi->popup(); + popup->updateAccel( this ); + if ( !popup->isEnabled() ) + popup->enableAccel( FALSE ); + } + } +} +#endif + +/*! + \reimp + */ +bool TQMenuBar::customWhatsThis() const +{ + return TRUE; +} + + + +/*! + \reimp + */ +void TQMenuBar::focusInEvent( TQFocusEvent * ) +{ + if ( actItem < 0 ) { + int i = -1; + while ( actItem < 0 && ++i < (int) mitems->count() ) { + TQMenuItem* mi = mitems->at( i ); + if ( mi && mi->isEnabledAndVisible() && !mi->isSeparator() ) + setActiveItem( i, FALSE ); + } + } else if ( !popupvisible ) { + updateItem( idAt( actItem ) ); + } +} + +/*! + \reimp + */ +void TQMenuBar::focusOutEvent( TQFocusEvent * ) +{ + updateItem( idAt( actItem ) ); + if ( !popupvisible ) + setAltMode( FALSE ); +} + +/*! + \reimp +*/ + +TQSize TQMenuBar::tqsizeHint() const +{ + int h = height(); + if ( badSize ) + h = ( (TQMenuBar*)this )->calculateRects(); + TQSize s( 2*frameWidth(),0); + if ( irects ) { + for ( int i = 0; i < (int)mitems->count(); ++i ) + s.setWidth( s.width() + irects[ i ].width() + 2 ); + } + s.setHeight( h ); + return (tqstyle().tqsizeFromContents(TQStyle::CT_MenuBar, this, s. + expandedTo(TQApplication::globalStrut()))); +} + +/*! + \reimp +*/ + +TQSize TQMenuBar::tqminimumSize() const +{ +#ifndef TQT_NO_TOOLBAR + TQToolBar *tb = ::tqqt_cast<TQToolBar*>(tqparent()); + if ( tb ) + return tqsizeHint(); +#endif + return TQFrame::tqminimumSize(); +} + +/*! + \reimp +*/ + +TQSize TQMenuBar::tqminimumSizeHint() const +{ + return tqminimumSize(); +} + +/*! + \property TQMenuBar::defaultUp + \brief the popup orientation + + The default popup orientation. By default, menus pop "down" the + screen. By setting the property to TRUE, the menu will pop "up". + You might call this for menus that are \e below the document to + which they refer. + + If the menu would not fit on the screen, the other direction is + used automatically. +*/ +void TQMenuBar::setDefaultUp( bool on ) +{ + defaultup = on; +} + +bool TQMenuBar::isDefaultUp() const +{ + return defaultup; +} + + +/*! + \reimp + */ +void TQMenuBar::activateItemAt( int index ) +{ + if ( index >= 0 && index < (int) mitems->count() ) + setActiveItem( index ); + else + goodbye( FALSE ); +} + +#endif // TQT_NO_MENUBAR |