framework/source/layoutmanager/layoutmanager.cxx | 10 include/vcl/menu.hxx | 29 sfx2/source/control/dispatch.cxx | 439 --- vcl/Library_vcl.mk | 4 vcl/source/window/menu.cxx | 3255 ----------------------- vcl/source/window/menubarwindow.cxx | 1156 ++++++++ vcl/source/window/menubarwindow.hxx | 147 + vcl/source/window/menufloatingwindow.cxx | 1209 ++++++++ vcl/source/window/menufloatingwindow.hxx | 121 vcl/source/window/menuitemlist.cxx | 280 + vcl/source/window/menuitemlist.hxx | 152 + vcl/source/window/menuwindow.cxx | 161 + vcl/source/window/menuwindow.hxx | 59 13 files changed, 3559 insertions(+), 3463 deletions(-)
New commits: commit 9195fd3819197c14f6fc018483075c4be5bf85fd Author: Jan Holesovsky <ke...@collabora.com> Date: Mon Sep 8 13:18:17 2014 +0200 vcl: Kill bIsMenuBar. Change-Id: I16bcb4be7fcdba6272f9f4a92d5c90c71dc431e8 diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx index aeff356..741ed21 100644 --- a/include/vcl/menu.hxx +++ b/include/vcl/menu.hxx @@ -144,10 +144,9 @@ private: sal_uInt16 nImgOrChkPos; sal_uInt16 nTextPos; - bool bIsMenuBar : 1, // Is this a menubar? - bCanceled : 1, // Terminated during a callback - bInCallback : 1, // In Activate/Deactivate - bKilled : 1; // Killed... + bool bCanceled : 1, ///< Terminated during a callback + bInCallback : 1, ///< In Activate/Deactivate + bKilled : 1; ///< Killed ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxAccessible; mutable vcl::MenuLayoutData* mpLayoutData; @@ -201,12 +200,11 @@ public: SAL_DLLPRIVATE void ImplKillLayoutData() const; SAL_DLLPRIVATE Menu* ImplGetStartedFrom() const { return pStartedFrom; } - Menu(); - explicit Menu( bool bMenuBar ); SAL_DLLPRIVATE Window* ImplGetWindow() const { return pWindow; } void ImplSelectWithStart( Menu* pStartMenu = NULL ); - public: +public: + Menu(); virtual ~Menu(); virtual void Activate(); @@ -285,7 +283,7 @@ public: bool IsItemPosVisible( sal_uInt16 nItemPos ) const; bool IsMenuVisible() const; - bool IsMenuBar() const { return bIsMenuBar; } + virtual bool IsMenuBar() const { return false; } void RemoveDisabledEntries( bool bCheckPopups = true, bool bRemoveEmptyPopups = false ); bool HasValidEntries( bool bCheckPopups = true ); @@ -413,6 +411,8 @@ public: MenuBar& operator =( const MenuBar& rMenu ); + virtual bool IsMenuBar() const SAL_OVERRIDE { return true; } + void ShowCloser( bool bShow = true ); bool HasCloser() const { return mbCloserVisible; } bool HasFloatButton() const { return mbFloatBtnVisible; } diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index f41729f..56a1d5d 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -112,15 +112,6 @@ static void ImplSetMenuItemData( MenuItemData* pData ) Menu::Menu() { - bIsMenuBar = false; - ImplInit(); -} - -// this constructor makes sure we're creating the native menu -// with the correct type (ie, MenuBar vs. PopupMenu) -Menu::Menu( bool bMenubar ) -{ - bIsMenuBar = bMenubar; ImplInit(); } @@ -176,7 +167,6 @@ void Menu::ImplInit() mpSalMenu = NULL; nMenuFlags = 0; nDefaultItem = 0; - //bIsMenuBar = false; // this is now set in the ctor, must not be changed here!!! nSelectedId = 0; pItemList = new MenuItemList; pLogo = NULL; @@ -189,7 +179,7 @@ void Menu::ImplInit() mpLayoutData = NULL; mpFirstDel = NULL; // Dtor notification list // Native-support: returns NULL if not supported - mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu( bIsMenuBar, this ); + mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(IsMenuBar(), this); } void Menu::ImplLoadRes( const ResId& rResId ) @@ -216,7 +206,7 @@ void Menu::ImplLoadRes( const ResId& rResId ) if( nObjMask & RSC_MENU_TEXT ) { - if( bIsMenuBar ) // no title in menubar + if (IsMenuBar()) // no title in menubar ReadStringRes(); else aTitleText = ReadStringRes(); @@ -571,7 +561,7 @@ void Menu::InsertItem( const ResId& rResId, sal_uInt16 nPos ) void Menu::InsertSeparator(const OString &rIdent, sal_uInt16 nPos) { // do nothing if it's a menu bar - if ( bIsMenuBar ) + if (IsMenuBar()) return; // if position > ItemCount, append @@ -1002,7 +992,7 @@ void Menu::EnableItem( sal_uInt16 nItemId, bool bEnable ) Window* pWin = ImplGetWindow(); if ( pWin && pWin->IsVisible() ) { - DBG_ASSERT( bIsMenuBar, "Menu::EnableItem - Popup visible!" ); + DBG_ASSERT(IsMenuBar(), "Menu::EnableItem - Popup visible!" ); long nX = 0; size_t nCount = pItemList->size(); for ( size_t n = 0; n < nCount; n++ ) @@ -1040,8 +1030,8 @@ void Menu::ShowItem( sal_uInt16 nItemId, bool bVisible ) size_t nPos; MenuItemData* pData = pItemList->GetData( nItemId, nPos ); - DBG_ASSERT( !bIsMenuBar, "Menu::ShowItem - ignored for menu bar entries!" ); - if ( !bIsMenuBar && pData && ( pData->bVisible != bVisible ) ) + DBG_ASSERT(!IsMenuBar(), "Menu::ShowItem - ignored for menu bar entries!"); + if (!IsMenuBar()&& pData && (pData->bVisible != bVisible)) { Window* pWin = ImplGetWindow(); if ( pWin && pWin->IsVisible() ) @@ -1075,7 +1065,7 @@ void Menu::SetItemText( sal_uInt16 nItemId, const OUString& rStr ) Window* pWin = ImplGetWindow(); delete mpLayoutData, mpLayoutData = NULL; - if ( pWin && IsMenuBar() ) + if (pWin && IsMenuBar()) { ImplCalcSize( pWin ); if ( pWin->IsVisible() ) @@ -1307,7 +1297,6 @@ Menu& Menu::operator=( const Menu& rMenu ) aHighlightHdl = rMenu.aHighlightHdl; aSelectHdl = rMenu.aSelectHdl; aTitleText = rMenu.aTitleText; - bIsMenuBar = rMenu.bIsMenuBar; return *this; } @@ -1366,8 +1355,8 @@ bool Menu::ImplIsVisible( sal_uInt16 nPos ) const // not allowed for menubar, as I do not know // whether a menu-entry will disappear or will appear - if ( bVisible && !bIsMenuBar && ( nMenuFlags & MENU_FLAG_HIDEDISABLEDENTRIES ) && - !( nMenuFlags & MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES ) ) + if (bVisible && !IsMenuBar() && (nMenuFlags & MENU_FLAG_HIDEDISABLEDENTRIES) && + !(nMenuFlags & MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES)) { if( !pData ) // e.g. nPos == ITEMPOS_INVALID bVisible = false; @@ -1405,7 +1394,7 @@ bool Menu::ImplIsSelectable( sal_uInt16 nPos ) const void Menu::SelectItem( sal_uInt16 nItemId ) { - if( bIsMenuBar ) + if (IsMenuBar()) static_cast<MenuBar*>(this)->SelectEntry( nItemId ); else static_cast<PopupMenu*>(this)->SelectEntry( nItemId ); @@ -1437,7 +1426,7 @@ void Menu::SelectItem( sal_uInt16 nItemId ) { UnoWrapperBase* pWrapper = Application::GetUnoWrapper(); if ( pWrapper ) - mxAccessible = pWrapper->CreateAccessible( this, bIsMenuBar ); + mxAccessible = pWrapper->CreateAccessible(this, IsMenuBar()); } return mxAccessible; @@ -1453,7 +1442,7 @@ Size Menu::ImplGetNativeCheckAndRadioSize( const Window* pWin, long& rCheckHeigh long nCheckWidth = 0, nRadioWidth = 0; rCheckHeight = rRadioHeight = 0; - if( ! bIsMenuBar ) + if (!IsMenuBar()) { ImplControlValue aVal; Rectangle aNativeBounds; @@ -1613,14 +1602,14 @@ Size Menu::ImplCalcSize( const Window* pWin ) long nWidth = 0; // Separator - if ( !bIsMenuBar && ( pData->eType == MENUITEM_SEPARATOR ) ) + if (!IsMenuBar()&& (pData->eType == MENUITEM_SEPARATOR)) { - DBG_ASSERT( !bIsMenuBar, "Separator in MenuBar ?! " ); + DBG_ASSERT( !IsMenuBar(), "Separator in MenuBar ?! " ); pData->aSz.Height() = 4; } // Image: - if ( !bIsMenuBar && ( ( pData->eType == MENUITEM_IMAGE ) || ( pData->eType == MENUITEM_STRINGIMAGE ) ) ) + if (!IsMenuBar()&& ((pData->eType == MENUITEM_IMAGE) || (pData->eType == MENUITEM_STRINGIMAGE))) { Size aImgSz = pData->aImage.GetSizePixel(); aImgSz.Height() += 4; // add a border for native marks @@ -1634,7 +1623,7 @@ Size Menu::ImplCalcSize( const Window* pWin ) } // Check Buttons: - if ( !bIsMenuBar && pData->HasCheck() ) + if (!IsMenuBar() && pData->HasCheck()) { nCheckWidth = aMaxSize.Width(); // checks / images take the same place @@ -1648,7 +1637,7 @@ Size Menu::ImplCalcSize( const Window* pWin ) long nTextWidth = pWin->GetCtrlTextWidth( pData->aText ); long nTextHeight = pWin->GetTextHeight(); - if ( bIsMenuBar ) + if (IsMenuBar()) { if ( nTextHeight > pData->aSz.Height() ) pData->aSz.Height() = nTextHeight; @@ -1663,7 +1652,7 @@ Size Menu::ImplCalcSize( const Window* pWin ) } // Accel - if ( !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() ) + if (!IsMenuBar()&& pData->aAccelKey.GetCode() && !ImplAccelDisabled()) { OUString aName = pData->aAccelKey.GetName(); long nAccWidth = pWin->GetTextWidth( aName ); @@ -1672,7 +1661,7 @@ Size Menu::ImplCalcSize( const Window* pWin ) } // SubMenu? - if ( !bIsMenuBar && pData->pSubMenu ) + if (!IsMenuBar() && pData->pSubMenu) { if ( nFontHeight > nWidth ) nWidth += nFontHeight; @@ -1682,7 +1671,7 @@ Size Menu::ImplCalcSize( const Window* pWin ) pData->aSz.Height() += EXTRAITEMHEIGHT; // little bit more distance - if ( !bIsMenuBar ) + if (!IsMenuBar()) aSz.Height() += (long)pData->aSz.Height(); if ( nWidth > nMaxWidth ) @@ -1691,7 +1680,7 @@ Size Menu::ImplCalcSize( const Window* pWin ) } } - if ( !bIsMenuBar ) + if (!IsMenuBar()) { // popup menus should not be wider than half the screen // except on rather small screens @@ -1824,7 +1813,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa aTopLeft.X() = pLogo->aBitmap.GetSizePixel().Width(); int nOuterSpaceX = 0; - if( !bIsMenuBar ) + if (!IsMenuBar()) { nOuterSpaceX = ImplGetSVData()->maNWFData.mnMenuFormatBorderX; aTopLeft.X() += nOuterSpaceX; @@ -1843,7 +1832,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa { if ( pThisItemOnly ) { - if ( bIsMenuBar && bRollover ) + if (IsMenuBar()&& bRollover ) pWin->SetTextColor( rSettings.GetMenuBarRolloverTextColor() ); else if ( bHighlighted ) pWin->SetTextColor( rSettings.GetMenuHighlightTextColor() ); @@ -1856,7 +1845,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa if ( aPos.Y() >= 0 ) { long nTextOffsetY = ((pData->aSz.Height()-nFontHeight)/2); - if( bIsMenuBar ) + if (IsMenuBar()) nTextOffsetY += (aOutSz.Height()-pData->aSz.Height()) / 2; sal_uInt16 nTextStyle = 0; sal_uInt16 nSymbolStyle = 0; @@ -1874,7 +1863,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa } // Separator - if ( !bLayout && !bIsMenuBar && ( pData->eType == MENUITEM_SEPARATOR ) ) + if (!bLayout && !IsMenuBar() && (pData->eType == MENUITEM_SEPARATOR)) { bool bNativeOk = false; if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, @@ -1915,7 +1904,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa aOuterCheckRect.Bottom() -= 1; // CheckMark - if ( !bLayout && !bIsMenuBar && pData->HasCheck() ) + if (!bLayout && !IsMenuBar() && pData->HasCheck()) { // draw selection transparent marker if checked // onto that either a checkmark or the item image @@ -1985,7 +1974,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa } // Image: - if ( !bLayout && !bIsMenuBar && ( ( pData->eType == MENUITEM_IMAGE ) || ( pData->eType == MENUITEM_STRINGIMAGE ) ) ) + if (!bLayout && !IsMenuBar() && ((pData->eType == MENUITEM_IMAGE) || (pData->eType == MENUITEM_STRINGIMAGE))) { // Don't render an image for a check thing if( pData->bChecked ) @@ -2021,19 +2010,19 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa bool bSetTmpBackground = !pWin->IsBackground() && pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ); if( bSetTmpBackground ) { - Color aBg = bIsMenuBar ? + Color aBg = IsMenuBar()? pWin->GetSettings().GetStyleSettings().GetMenuBarColor() : pWin->GetSettings().GetStyleSettings().GetMenuColor(); pWin->SetBackground( Wallpaper( aBg ) ); } // how much space is there for the text ? long nMaxItemTextWidth = aOutSz.Width() - aTmpPos.X() - nExtra - nOuterSpaceX; - if( !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() ) + if (!IsMenuBar() && pData->aAccelKey.GetCode() && !ImplAccelDisabled()) { OUString aAccText = pData->aAccelKey.GetName(); nMaxItemTextWidth -= pWin->GetTextWidth( aAccText ) + 3*nExtra; } - if( !bIsMenuBar && pData->pSubMenu ) + if (!IsMenuBar() && pData->pSubMenu) { nMaxItemTextWidth -= nFontHeight - nExtra; } @@ -2044,7 +2033,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa } // Accel - if ( !bLayout && !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() ) + if (!bLayout && !IsMenuBar() && pData->aAccelKey.GetCode() && !ImplAccelDisabled()) { OUString aAccText = pData->aAccelKey.GetName(); aTmpPos.X() = aOutSz.Width() - pWin->GetTextWidth( aAccText ); @@ -2057,7 +2046,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa } // SubMenu? - if ( !bLayout && !bIsMenuBar && pData->pSubMenu ) + if (!bLayout && !IsMenuBar() && pData->pSubMenu) { bool bNativeOk = false; if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, @@ -2116,7 +2105,7 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa { // This restores the normal menu or menu bar text // color for when it is no longer highlighted. - if ( bIsMenuBar ) + if (IsMenuBar()) pWin->SetTextColor( rSettings.GetMenuBarTextColor() ); else pWin->SetTextColor( rSettings.GetMenuTextColor() ); @@ -2124,14 +2113,14 @@ void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemDa } if( bLayout ) { - if ( !bIsMenuBar ) + if (!IsMenuBar()) mpLayoutData->m_aVisibleItemBoundRects[ n ] = Rectangle( aTopLeft, Size( aOutSz.Width(), pData->aSz.Height() ) ); else mpLayoutData->m_aVisibleItemBoundRects[ n ] = Rectangle( aTopLeft, pData->aSz ); } } - if ( !bIsMenuBar ) + if (!IsMenuBar()) { aTopLeft.Y() += pData->aSz.Height(); } @@ -2290,7 +2279,7 @@ void Menu::CloseStartedFrom() // pWin from parent could be 0, if the list is // cleaned from the start, now clean up the endpopup-events - if (pStartedFrom->bIsMenuBar) + if (pStartedFrom->IsMenuBar()) { MenuBarWindow* p = (MenuBarWindow*) pStartedFrom->ImplGetWindow(); if (p) @@ -2307,7 +2296,7 @@ void Menu::CloseStartedFrom() sal_uLong Menu::DeactivateMenuBar(sal_uLong nFocusId) { - if (!bIsMenuBar) + if (!IsMenuBar()) return nFocusId; nFocusId = ((MenuBarWindow*)(dynamic_cast<MenuBar*>(this))->ImplGetWindow())->GetFocusId(); @@ -2322,7 +2311,7 @@ sal_uLong Menu::DeactivateMenuBar(sal_uLong nFocusId) void Menu::MenuBarKeyInput(const KeyEvent& rEvent) { - if (!bIsMenuBar) + if (!IsMenuBar()) return; ((MenuBarWindow*)(dynamic_cast<MenuBar*>(this))->ImplGetWindow())->KeyInput(rEvent); @@ -2338,7 +2327,7 @@ void Menu::ImplFillLayoutData() const if( pWindow && pWindow->IsReallyVisible() ) { mpLayoutData = new MenuLayoutData(); - if( bIsMenuBar ) + if (IsMenuBar()) { ImplPaint( pWindow, 0, 0, 0, false, true ); } @@ -2455,7 +2444,7 @@ bool Menu::IsHighlighted( sal_uInt16 nItemPos ) const if( pWindow ) { - if( bIsMenuBar ) + if (IsMenuBar()) bRet = ( nItemPos == static_cast< MenuBarWindow * > (pWindow)->GetHighlightedItem() ); else bRet = ( nItemPos == static_cast< MenuFloatingWindow * > (pWindow)->GetHighlightedItem() ); @@ -2468,7 +2457,7 @@ void Menu::HighlightItem( sal_uInt16 nItemPos ) { if ( pWindow ) { - if ( bIsMenuBar ) + if (IsMenuBar()) { MenuBarWindow* pMenuWin = static_cast< MenuBarWindow* >( pWindow ); pMenuWin->SetAutoPopup( false ); @@ -2483,7 +2472,7 @@ void Menu::HighlightItem( sal_uInt16 nItemPos ) // - MenuBar - -MenuBar::MenuBar() : Menu( true ) +MenuBar::MenuBar() : Menu() { mbDisplayable = true; mbCloserVisible = false; @@ -2491,14 +2480,13 @@ MenuBar::MenuBar() : Menu( true ) mbHideBtnVisible = false; } -MenuBar::MenuBar( const MenuBar& rMenu ) : Menu( true ) +MenuBar::MenuBar( const MenuBar& rMenu ) : Menu() { mbDisplayable = true; mbCloserVisible = false; mbFloatBtnVisible = false; mbHideBtnVisible = false; *this = rMenu; - bIsMenuBar = true; } MenuBar::~MenuBar() @@ -2835,7 +2823,7 @@ sal_uInt16 PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, sal_uLong else { // assure that only one menu is open at a time - if( pStartedFrom->bIsMenuBar && pSVData->maWinData.mpFirstFloat ) + if (pStartedFrom->IsMenuBar() && pSVData->maWinData.mpFirstFloat) pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL ); } @@ -2844,9 +2832,9 @@ sal_uInt16 PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, sal_uLong aRect.SetPos( pW->OutputToScreenPixel( aRect.TopLeft() ) ); WinBits nStyle = WB_BORDER; - if ( bRealExecute ) + if (bRealExecute) nPopupModeFlags |= FLOATWIN_POPUPMODE_NEWLEVEL; - if ( !pStartedFrom || !pStartedFrom->bIsMenuBar ) + if (!pStartedFrom || !pStartedFrom->IsMenuBar()) nPopupModeFlags |= FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK | FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE; nPopupModeFlags |= FLOATWIN_POPUPMODE_NOKEYCLOSE; @@ -2948,7 +2936,7 @@ sal_uInt16 PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, sal_uLong nMaxHeight = std::min(nMaxHeight, std::max(nHeightAbove, nHeightBelow)); } - if ( pStartedFrom && pStartedFrom->bIsMenuBar ) + if (pStartedFrom && pStartedFrom->IsMenuBar()) nMaxHeight -= pW->GetSizePixel().Height(); sal_Int32 nLeft, nTop, nRight, nBottom; pWindow->GetBorder( nLeft, nTop, nRight, nBottom ); @@ -2987,7 +2975,7 @@ sal_uInt16 PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, sal_uLong if( pSFrom ) { sal_uInt16 aPos; - if( pSFrom->bIsMenuBar ) + if (pSFrom->IsMenuBar()) aPos = ((MenuBarWindow *) pSFrom->pWindow)->GetHighlightedItem(); else aPos = ((MenuFloatingWindow *) pSFrom->pWindow)->GetHighlightedItem(); diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx index 6359606..5151110 100644 --- a/vcl/source/window/menufloatingwindow.cxx +++ b/vcl/source/window/menufloatingwindow.cxx @@ -68,7 +68,7 @@ void MenuFloatingWindow::doShutdown() if( nHighlightedItem != ITEMPOS_INVALID ) pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem ); pMenu->SetHighlightItem(ITEMPOS_INVALID); - if( !bKeyInput && pMenu && pMenu->pStartedFrom && !pMenu->pStartedFrom->bIsMenuBar ) + if (!bKeyInput && pMenu && pMenu->pStartedFrom && !pMenu->pStartedFrom->IsMenuBar()) { // #102461# remove highlight in parent MenuItemData* pData; @@ -443,8 +443,8 @@ void MenuFloatingWindow::EndExecute() // if started elsewhere, cleanup there as well MenuFloatingWindow* pCleanUpFrom = this; MenuFloatingWindow* pWin = this; - while ( pWin && !pWin->bInExecute && - pWin->pMenu->pStartedFrom && !pWin->pMenu->pStartedFrom->bIsMenuBar ) + while (pWin && !pWin->bInExecute && + pWin->pMenu->pStartedFrom && !pWin->pMenu->pStartedFrom->IsMenuBar()) { pWin = ((PopupMenu*)pWin->pMenu->pStartedFrom)->ImplGetFloatingWindow(); } @@ -670,7 +670,7 @@ void MenuFloatingWindow::ChangeHighlightItem( sal_uInt16 n, bool bStartPopupTime DBG_ASSERT( pMenu->ImplIsVisible( nHighlightedItem ) || nHighlightedItem == ITEMPOS_INVALID, "ChangeHighlightItem: Not visible!" ); if( nHighlightedItem != ITEMPOS_INVALID ) { - if( pMenu->pStartedFrom && !pMenu->pStartedFrom->bIsMenuBar ) + if (pMenu->pStartedFrom && !pMenu->pStartedFrom->IsMenuBar()) { // #102461# make sure parent entry is highlighted as well MenuItemData* pData; @@ -960,7 +960,7 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent ) StopExecute(); KillActivePopup(); } - else if ( pMenu->pStartedFrom->bIsMenuBar ) + else if (pMenu->pStartedFrom->IsMenuBar()) { pMenu->pStartedFrom->MenuBarKeyInput(rKEvent); } @@ -981,7 +981,7 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent ) if ( pMenu && pMenu->pStartedFrom ) { StopExecute(); - if ( pMenu->pStartedFrom->bIsMenuBar ) + if (pMenu->pStartedFrom->IsMenuBar()) { pMenu->pStartedFrom->MenuBarKeyInput(rKEvent); } @@ -1013,7 +1013,7 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent ) if ( !bDone ) { Menu* pStart = pMenu->ImplGetStartMenu(); - if ( pStart && pStart->bIsMenuBar ) + if (pStart && pStart->IsMenuBar()) { // Forward... pStart->ImplGetWindow()->KeyInput( rKEvent ); @@ -1044,7 +1044,7 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent ) if( pMenu ) { Menu* pStart = pMenu->ImplGetStartMenu(); - if ( pStart && pStart->bIsMenuBar ) + if (pStart && pStart->IsMenuBar()) { // Forward... pStart->ImplGetWindow()->KeyInput( rKEvent ); commit ca455cd55efe9ad48b635f60363ea131b55e1eef Author: Jan Holesovsky <ke...@collabora.com> Date: Mon Sep 8 10:45:16 2014 +0200 vcl: Move MenuBarWindow to an own file + adapt code. Change-Id: Id24711ad0a6fa6a0599fcc172c47f48fbe65183b diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index ec50fdd..560687f 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -138,6 +138,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/window/keyevent \ vcl/source/window/layout \ vcl/source/window/menu \ + vcl/source/window/menubarwindow \ vcl/source/window/menufloatingwindow \ vcl/source/window/menuitemlist \ vcl/source/window/menuwindow \ diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 0967380..f41729f 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -42,12 +42,14 @@ #include <vcl/dockingarea.hxx> #include <vcl/settings.hxx> -#include "salinst.hxx" -#include "svdata.hxx" -#include "svids.hrc" -#include "window.h" -#include "salmenu.hxx" -#include "salframe.hxx" +#include <salinst.hxx> +#include <svdata.hxx> +#include <svids.hrc> +#include <window.h> +#include <salmenu.hxx> +#include <salframe.hxx> + +#include "menubarwindow.hxx" #include "menufloatingwindow.hxx" #include "menuitemlist.hxx" @@ -82,9 +84,6 @@ using namespace vcl; #define EXTRAITEMHEIGHT 4 -// document closer -#define IID_DOCUMENTCLOSE 1 - static bool ImplAccelDisabled() { // display of accelerator strings may be suppressed via configuration @@ -100,218 +99,6 @@ static bool ImplAccelDisabled() return nAccelDisabled == 1; } -// To get the transparent mouse-over look, the closer is actually a toolbox -// overload DataChange to handle style changes correctly -class DecoToolBox : public ToolBox -{ - long lastSize; - Size maMinSize; - - using Window::ImplInit; -public: - DecoToolBox( Window* pParent, WinBits nStyle = 0 ); - void ImplInit(); - - void DataChanged( const DataChangedEvent& rDCEvt ) SAL_OVERRIDE; - - void SetImages( long nMaxHeight = 0, bool bForce = false ); - - void calcMinSize(); - const Size& getMinSize() { return maMinSize;} - - Image maImage; -}; - -DecoToolBox::DecoToolBox( Window* pParent, WinBits nStyle ) : - ToolBox( pParent, nStyle ) -{ - ImplInit(); -} - -void DecoToolBox::ImplInit() -{ - lastSize = -1; - calcMinSize(); -} - -void DecoToolBox::DataChanged( const DataChangedEvent& rDCEvt ) -{ - Window::DataChanged( rDCEvt ); - - if ( rDCEvt.GetFlags() & SETTINGS_STYLE ) - { - calcMinSize(); - SetBackground(); - SetImages( 0, true); - } -} - -void DecoToolBox::calcMinSize() -{ - ToolBox aTbx( GetParent() ); - if( GetItemCount() == 0 ) - { - ResMgr* pResMgr = ImplGetResMgr(); - - Bitmap aBitmap; - if( pResMgr ) - aBitmap = Bitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) ); - aTbx.InsertItem( IID_DOCUMENTCLOSE, Image( aBitmap ) ); - } - else - { - sal_uInt16 nItems = GetItemCount(); - for( sal_uInt16 i = 0; i < nItems; i++ ) - { - sal_uInt16 nId = GetItemId( i ); - aTbx.InsertItem( nId, GetItemImage( nId ) ); - } - } - aTbx.SetOutStyle( TOOLBOX_STYLE_FLAT ); - maMinSize = aTbx.CalcWindowSizePixel(); -} - - -void DecoToolBox::SetImages( long nMaxHeight, bool bForce ) -{ - long border = getMinSize().Height() - maImage.GetSizePixel().Height(); - - if( !nMaxHeight && lastSize != -1 ) - nMaxHeight = lastSize + border; // don't change anything if called with 0 - - if( nMaxHeight < getMinSize().Height() ) - nMaxHeight = getMinSize().Height(); - - if( (lastSize != nMaxHeight - border) || bForce ) - { - lastSize = nMaxHeight - border; - - Color aEraseColor( 255, 255, 255, 255 ); - BitmapEx aBmpExDst( maImage.GetBitmapEx() ); - BitmapEx aBmpExSrc( aBmpExDst ); - - aEraseColor.SetTransparency( 255 ); - aBmpExDst.Erase( aEraseColor ); - aBmpExDst.SetSizePixel( Size( lastSize, lastSize ) ); - - Rectangle aSrcRect( Point(0,0), maImage.GetSizePixel() ); - Rectangle aDestRect( Point((lastSize - maImage.GetSizePixel().Width())/2, - (lastSize - maImage.GetSizePixel().Height())/2 ), - maImage.GetSizePixel() ); - - aBmpExDst.CopyPixel( aDestRect, aSrcRect, &aBmpExSrc ); - SetItemImage( IID_DOCUMENTCLOSE, Image( aBmpExDst ) ); - } -} - -// a basic class for both (due to pActivePopup, Timer,...) would be nice, -// but a container class should have been created then, as they -// would be derived from different windows -// In most functions we would have to create exceptions for -// menubar, popupmenu, hence we made two classes - -class MenuBarWindow : public MenuWindow, public Window -{ - friend class MenuBar; - friend class Menu; - -private: - struct AddButtonEntry - { - sal_uInt16 m_nId; - Link m_aSelectLink; - Link m_aHighlightLink; - - AddButtonEntry() : m_nId( 0 ) {} - }; - - Menu* pMenu; - PopupMenu* pActivePopup; - sal_uInt16 nHighlightedItem; - sal_uInt16 nRolloveredItem; - sal_uLong nSaveFocusId; - bool mbAutoPopup; - bool bIgnoreFirstMove; - bool bStayActive; - - DecoToolBox aCloser; - PushButton aFloatBtn; - PushButton aHideBtn; - - std::map< sal_uInt16, AddButtonEntry > m_aAddButtons; - - void HighlightItem( sal_uInt16 nPos, bool bHighlight ); - void ChangeHighlightItem( sal_uInt16 n, bool bSelectPopupEntry, bool bAllowRestoreFocus = true, bool bDefaultToDocument = true ); - - sal_uInt16 ImplFindEntry( const Point& rMousePos ) const; - void ImplCreatePopup( bool bPreSelectFirst ); - bool ImplHandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu = true ); - Rectangle ImplGetItemRect( sal_uInt16 nPos ); - - void ImplInitStyleSettings(); - - DECL_LINK(CloserHdl, void *); - DECL_LINK(FloatHdl, void *); - DECL_LINK(HideHdl, void *); - DECL_LINK( ToolboxEventHdl, VclWindowEvent* ); - DECL_LINK( ShowHideListener, VclWindowEvent* ); - - void StateChanged( StateChangedType nType ) SAL_OVERRIDE; - void DataChanged( const DataChangedEvent& rDCEvt ) SAL_OVERRIDE; - void LoseFocus() SAL_OVERRIDE; - void GetFocus() SAL_OVERRIDE; - -public: - MenuBarWindow( Window* pParent ); - virtual ~MenuBarWindow(); - - void ShowButtons( bool bClose, bool bFloat, bool bHide ); - - virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE; - virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE; - virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE; - virtual void KeyInput( const KeyEvent& rKEvent ) SAL_OVERRIDE; - virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE; - virtual void Resize() SAL_OVERRIDE; - virtual void RequestHelp( const HelpEvent& rHEvt ) SAL_OVERRIDE; - - void SetFocusId( sal_uLong nId ) { nSaveFocusId = nId; } - sal_uLong GetFocusId() const { return nSaveFocusId; } - - void SetMenu( MenuBar* pMenu ); - void KillActivePopup(); - void PopupClosed( Menu* pMenu ); - sal_uInt16 GetHighlightedItem() const { return nHighlightedItem; } - virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE; - - void SetAutoPopup( bool bAuto ) { mbAutoPopup = bAuto; } - void ImplLayoutChanged(); - Size MinCloseButtonSize(); - - // add an arbitrary button to the menubar (will appear next to closer) - sal_uInt16 AddMenuBarButton( const Image&, const Link&, const OUString&, sal_uInt16 nPos ); - void SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link& ); - Rectangle GetMenuBarButtonRectPixel( sal_uInt16 nId ); - void RemoveMenuBarButton( sal_uInt16 nId ); - bool HandleMenuButtonEvent( sal_uInt16 i_nButtonId ); -}; - -static void ImplAddNWFSeparator( Window *pThis, const MenubarValue& rMenubarValue ) -{ - // add a separator if - // - we have an adjacent docking area - // - and if toolbars would draw them as well (mbDockingAreaSeparateTB must not be set, see dockingarea.cxx) - if( rMenubarValue.maTopDockingAreaHeight && !ImplGetSVData()->maNWFData.mbDockingAreaSeparateTB && !ImplGetSVData()->maNWFData.mbDockingAreaAvoidTBFrames ) - { - // note: the menubar only provides the upper (dark) half of it, the rest (bright part) is drawn by the docking area - - pThis->SetLineColor( pThis->GetSettings().GetStyleSettings().GetSeparatorColor() ); - Point aPt; - Rectangle aRect( aPt, pThis->GetOutputSizePixel() ); - pThis->DrawLine( aRect.BottomLeft(), aRect.BottomRight() ); - } -} - static void ImplSetMenuItemData( MenuItemData* pData ) { // convert data @@ -323,41 +110,6 @@ static void ImplSetMenuItemData( MenuItemData* pData ) pData->eType = MENUITEM_STRINGIMAGE; } -static int ImplGetTopDockingAreaHeight( Window *pWindow ) -{ - // find docking area that is top aligned and return its height - // note: dockingareas are direct children of the SystemWindow - if( pWindow->ImplGetFrameWindow() ) - { - Window *pWin = pWindow->ImplGetFrameWindow()->GetWindow( WINDOW_FIRSTCHILD ); //mpWindowImpl->mpFirstChild; - while( pWin ) - { - if( pWin->IsSystemWindow() ) - { - Window *pChildWin = pWin->GetWindow( WINDOW_FIRSTCHILD ); //mpWindowImpl->mpFirstChild; - while( pChildWin ) - { - DockingAreaWindow *pDockingArea = NULL; - if ( pChildWin->GetType() == WINDOW_DOCKINGAREA ) - pDockingArea = static_cast< DockingAreaWindow* >( pChildWin ); - - if( pDockingArea && pDockingArea->GetAlign() == WINDOWALIGN_TOP && - pDockingArea->IsVisible() && pDockingArea->GetOutputSizePixel().Height() != 0 ) - { - return pDockingArea->GetOutputSizePixel().Height(); - } - - pChildWin = pChildWin->GetWindow( WINDOW_NEXT ); //mpWindowImpl->mpNext; - } - - } - - pWin = pWin->GetWindow( WINDOW_NEXT ); //mpWindowImpl->mpNext; - } - } - return 0; -} - Menu::Menu() { bIsMenuBar = false; @@ -3367,993 +3119,6 @@ long PopupMenu::ImplCalcHeight( sal_uInt16 nEntries ) const return nHeight; } -MenuBarWindow::MenuBarWindow( Window* pParent ) : - Window( pParent, 0 ), - aCloser( this ), - aFloatBtn( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE ), - aHideBtn( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE ) -{ - SetType( WINDOW_MENUBARWINDOW ); - pMenu = NULL; - pActivePopup = NULL; - nSaveFocusId = 0; - nHighlightedItem = ITEMPOS_INVALID; - nRolloveredItem = ITEMPOS_INVALID; - mbAutoPopup = true; - nSaveFocusId = 0; - bIgnoreFirstMove = true; - bStayActive = false; - - ResMgr* pResMgr = ImplGetResMgr(); - - if( pResMgr ) - { - BitmapEx aBitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) ); - aCloser.maImage = Image( aBitmap ); - - aCloser.SetOutStyle( TOOLBOX_STYLE_FLAT ); - aCloser.SetBackground(); - aCloser.SetPaintTransparent( true ); - aCloser.SetParentClipMode( PARENTCLIPMODE_NOCLIP ); - - aCloser.InsertItem( IID_DOCUMENTCLOSE, aCloser.maImage, 0 ); - aCloser.SetSelectHdl( LINK( this, MenuBarWindow, CloserHdl ) ); - aCloser.AddEventListener( LINK( this, MenuBarWindow, ToolboxEventHdl ) ); - aCloser.SetQuickHelpText( IID_DOCUMENTCLOSE, ResId(SV_HELPTEXT_CLOSEDOCUMENT, *pResMgr).toString() ); - - aFloatBtn.SetClickHdl( LINK( this, MenuBarWindow, FloatHdl ) ); - aFloatBtn.SetSymbol( SYMBOL_FLOAT ); - aFloatBtn.SetQuickHelpText( ResId(SV_HELPTEXT_RESTORE, *pResMgr).toString() ); - - aHideBtn.SetClickHdl( LINK( this, MenuBarWindow, HideHdl ) ); - aHideBtn.SetSymbol( SYMBOL_HIDE ); - aHideBtn.SetQuickHelpText( ResId(SV_HELPTEXT_MINIMIZE, *pResMgr).toString() ); - } - - ImplInitStyleSettings(); - - AddEventListener( LINK( this, MenuBarWindow, ShowHideListener ) ); -} - -MenuBarWindow::~MenuBarWindow() -{ - aCloser.RemoveEventListener( LINK( this, MenuBarWindow, ToolboxEventHdl ) ); - RemoveEventListener( LINK( this, MenuBarWindow, ShowHideListener ) ); -} - -void MenuBarWindow::SetMenu( MenuBar* pMen ) -{ - pMenu = pMen; - KillActivePopup(); - nHighlightedItem = ITEMPOS_INVALID; - ImplInitMenuWindow( this, true, true ); - if ( pMen ) - { - aCloser.ShowItem( IID_DOCUMENTCLOSE, pMen->HasCloser() ); - aCloser.Show( pMen->HasCloser() || !m_aAddButtons.empty() ); - aFloatBtn.Show( pMen->HasFloatButton() ); - aHideBtn.Show( pMen->HasHideButton() ); - } - Invalidate(); - - // show and connect native menubar - if( pMenu && pMenu->ImplGetSalMenu() ) - { - if( pMenu->ImplGetSalMenu()->VisibleMenuBar() ) - ImplGetFrame()->SetMenu( pMenu->ImplGetSalMenu() ); - - pMenu->ImplGetSalMenu()->SetFrame( ImplGetFrame() ); - } -} - -void MenuBarWindow::ShowButtons( bool bClose, bool bFloat, bool bHide ) -{ - aCloser.ShowItem( IID_DOCUMENTCLOSE, bClose ); - aCloser.Show( bClose || ! m_aAddButtons.empty() ); - aFloatBtn.Show( bFloat ); - aHideBtn.Show( bHide ); - Resize(); -} - -Size MenuBarWindow::MinCloseButtonSize() -{ - return aCloser.getMinSize(); -} - -IMPL_LINK_NOARG(MenuBarWindow, CloserHdl) -{ - if( ! pMenu ) - return 0; - - if( aCloser.GetCurItemId() == IID_DOCUMENTCLOSE ) - { - // #i106052# call close hdl asynchronously to ease handler implementation - // this avoids still being in the handler while the DecoToolBox already - // gets destroyed - Application::PostUserEvent( ((MenuBar*)pMenu)->GetCloserHdl(), pMenu ); - } - else - { - std::map<sal_uInt16,AddButtonEntry>::iterator it = m_aAddButtons.find( aCloser.GetCurItemId() ); - if( it != m_aAddButtons.end() ) - { - MenuBar::MenuBarButtonCallbackArg aArg; - aArg.nId = it->first; - aArg.bHighlight = (aCloser.GetHighlightItemId() == it->first); - aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu); - return it->second.m_aSelectLink.Call( &aArg ); - } - } - return 0; -} - -IMPL_LINK( MenuBarWindow, ToolboxEventHdl, VclWindowEvent*, pEvent ) -{ - if( ! pMenu ) - return 0; - - MenuBar::MenuBarButtonCallbackArg aArg; - aArg.nId = 0xffff; - aArg.bHighlight = (pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT); - aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu); - if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT ) - aArg.nId = aCloser.GetHighlightItemId(); - else if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHTOFF ) - { - sal_uInt16 nPos = static_cast< sal_uInt16 >(reinterpret_cast<sal_IntPtr>(pEvent->GetData())); - aArg.nId = aCloser.GetItemId( nPos ); - } - std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( aArg.nId ); - if( it != m_aAddButtons.end() ) - { - it->second.m_aHighlightLink.Call( &aArg ); - } - return 0; -} - -IMPL_LINK( MenuBarWindow, ShowHideListener, VclWindowEvent*, pEvent ) -{ - if( ! pMenu ) - return 0; - - if( pEvent->GetId() == VCLEVENT_WINDOW_SHOW ) - pMenu->ImplCallEventListeners( VCLEVENT_MENU_SHOW, ITEMPOS_INVALID ); - else if( pEvent->GetId() == VCLEVENT_WINDOW_HIDE ) - pMenu->ImplCallEventListeners( VCLEVENT_MENU_HIDE, ITEMPOS_INVALID ); - return 0; -} - -IMPL_LINK_NOARG(MenuBarWindow, FloatHdl) -{ - return pMenu ? ((MenuBar*)pMenu)->GetFloatButtonClickHdl().Call( pMenu ) : 0; -} - -IMPL_LINK_NOARG(MenuBarWindow, HideHdl) -{ - return pMenu ? ((MenuBar*)pMenu)->GetHideButtonClickHdl().Call( pMenu ) : 0; -} - -void MenuBarWindow::ImplCreatePopup( bool bPreSelectFirst ) -{ - MenuItemData* pItemData = pMenu ? pMenu->GetItemList()->GetDataFromPos( nHighlightedItem ) : NULL; - if ( pItemData ) - { - bIgnoreFirstMove = true; - if ( pActivePopup && ( pActivePopup != pItemData->pSubMenu ) ) - { - KillActivePopup(); - } - if ( pItemData->bEnabled && pItemData->pSubMenu && ( nHighlightedItem != ITEMPOS_INVALID ) && ( pItemData->pSubMenu != pActivePopup ) ) - { - pActivePopup = (PopupMenu*)pItemData->pSubMenu; - long nX = 0; - MenuItemData* pData = 0; - for ( sal_uLong n = 0; n < nHighlightedItem; n++ ) - { - pData = pMenu->GetItemList()->GetDataFromPos( n ); - nX += pData->aSz.Width(); - } - pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem ); - Point aItemTopLeft( nX, 0 ); - Point aItemBottomRight( aItemTopLeft ); - aItemBottomRight.X() += pData->aSz.Width(); - - // the menu bar could have height 0 in fullscreen mode: - // so do not use always WindowHeight, as ItemHeight < WindowHeight. - if ( GetSizePixel().Height() ) - { - // #107747# give menuitems the height of the menubar - aItemBottomRight.Y() += GetOutputSizePixel().Height()-1; - } - - // ImplExecute is not modal... - // #99071# do not grab the focus, otherwise it will be restored to the menubar - // when the frame is reactivated later - //GrabFocus(); - pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_NOHORZPLACEMENT, pMenu, bPreSelectFirst ); - if ( pActivePopup ) - { - // does not have a window, if aborted before or if there are no entries - if ( pActivePopup->ImplGetFloatingWindow() ) - pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this ); - else - pActivePopup = NULL; - } - } - } -} - -void MenuBarWindow::KillActivePopup() -{ - if ( pActivePopup ) - { - if( pActivePopup->pWindow != NULL ) - if( ((FloatingWindow *) pActivePopup->pWindow)->IsInCleanUp() ) - return; // kill it later - - if ( pActivePopup->bInCallback ) - pActivePopup->bCanceled = true; - - pActivePopup->bInCallback = true; - pActivePopup->Deactivate(); - pActivePopup->bInCallback = false; - // check for pActivePopup, if stopped by deactivate... - if ( pActivePopup->ImplGetWindow() ) - { - pActivePopup->ImplGetFloatingWindow()->StopExecute(); - pActivePopup->ImplGetFloatingWindow()->doShutdown(); - pActivePopup->pWindow->doLazyDelete(); - pActivePopup->pWindow = NULL; - } - pActivePopup = 0; - } -} - -void MenuBarWindow::PopupClosed( Menu* pPopup ) -{ - if ( pPopup == pActivePopup ) - { - KillActivePopup(); - ChangeHighlightItem( ITEMPOS_INVALID, false, ImplGetFrameWindow()->ImplGetFrameData()->mbHasFocus, false ); - } -} - -void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt ) -{ - mbAutoPopup = true; - sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() ); - if ( ( nEntry != ITEMPOS_INVALID ) && !pActivePopup ) - { - ChangeHighlightItem( nEntry, false ); - } - else - { - KillActivePopup(); - ChangeHighlightItem( ITEMPOS_INVALID, false ); - } -} - -void MenuBarWindow::MouseButtonUp( const MouseEvent& ) -{ -} - -void MenuBarWindow::MouseMove( const MouseEvent& rMEvt ) -{ - if ( rMEvt.IsSynthetic() || rMEvt.IsEnterWindow() ) - return; - - if ( rMEvt.IsLeaveWindow() ) - { - if ( nRolloveredItem != ITEMPOS_INVALID && nRolloveredItem != nHighlightedItem ) - HighlightItem( nRolloveredItem, false ); - - nRolloveredItem = ITEMPOS_INVALID; - return; - } - - sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() ); - if ( nHighlightedItem == ITEMPOS_INVALID ) - { - if ( nRolloveredItem != nEntry ) - { - if ( nRolloveredItem != ITEMPOS_INVALID ) - HighlightItem( nRolloveredItem, false ); - - nRolloveredItem = nEntry; - HighlightItem( nRolloveredItem, true ); - } - return; - } - nRolloveredItem = nEntry; - - if( bIgnoreFirstMove ) - { - bIgnoreFirstMove = false; - return; - } - - if ( ( nEntry != ITEMPOS_INVALID ) - && ( nEntry != nHighlightedItem ) ) - ChangeHighlightItem( nEntry, false ); -} - -void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, bool bSelectEntry, bool bAllowRestoreFocus, bool bDefaultToDocument) -{ - if( ! pMenu ) - return; - - // #57934# close active popup if applicable, as TH's background storage works. - MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n ); - if ( pActivePopup && pActivePopup->ImplGetWindow() && ( !pNextData || ( pActivePopup != pNextData->pSubMenu ) ) ) - KillActivePopup(); // pActivePopup when applicable without pWin, if Rescheduled in Activate() - - // activate menubar only ones per cycle... - bool bJustActivated = false; - if ( ( nHighlightedItem == ITEMPOS_INVALID ) && ( n != ITEMPOS_INVALID ) ) - { - ImplGetSVData()->maWinData.mbNoDeactivate = true; - if( !bStayActive ) - { - // #105406# avoid saving the focus when we already have the focus - bool bNoSaveFocus = (this == ImplGetSVData()->maWinData.mpFocusWin ); - - if( nSaveFocusId ) - { - if( !ImplGetSVData()->maWinData.mbNoSaveFocus ) - { - // we didn't clean up last time - Window::EndSaveFocus( nSaveFocusId, false ); // clean up - nSaveFocusId = 0; - if( !bNoSaveFocus ) - nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated - } - else { - ; // do nothing: we 're activated again from taskpanelist, focus was already saved - } - } - else - { - if( !bNoSaveFocus ) - nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated - } - } - else - bStayActive = false; - pMenu->bInCallback = true; // set here if Activate overloaded - pMenu->Activate(); - pMenu->bInCallback = false; - bJustActivated = true; - } - else if ( ( nHighlightedItem != ITEMPOS_INVALID ) && ( n == ITEMPOS_INVALID ) ) - { - pMenu->bInCallback = true; - pMenu->Deactivate(); - pMenu->bInCallback = false; - ImplGetSVData()->maWinData.mbNoDeactivate = false; - if( !ImplGetSVData()->maWinData.mbNoSaveFocus ) - { - sal_uLong nTempFocusId = nSaveFocusId; - nSaveFocusId = 0; - Window::EndSaveFocus( nTempFocusId, bAllowRestoreFocus ); - // #105406# restore focus to document if we could not save focus before - if( bDefaultToDocument && !nTempFocusId && bAllowRestoreFocus ) - GrabFocusToDocument(); - } - } - - if ( nHighlightedItem != ITEMPOS_INVALID ) - { - if ( nHighlightedItem != nRolloveredItem ) - HighlightItem( nHighlightedItem, false ); - - pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem ); - } - - nHighlightedItem = (sal_uInt16)n; - DBG_ASSERT( ( nHighlightedItem == ITEMPOS_INVALID ) || pMenu->ImplIsVisible( nHighlightedItem ), "ChangeHighlightItem: Not visible!" ); - if ( nHighlightedItem != ITEMPOS_INVALID ) - HighlightItem( nHighlightedItem, true ); - else if ( nRolloveredItem != ITEMPOS_INVALID ) - HighlightItem( nRolloveredItem, true ); - pMenu->SetHighlightItem(nHighlightedItem); - pMenu->ImplCallHighlight(nHighlightedItem); - - if( mbAutoPopup ) - ImplCreatePopup( bSelectEntry ); - - // #58935# #73659# Focus, if no popup underneath... - if ( bJustActivated && !pActivePopup ) - GrabFocus(); -} - -void MenuBarWindow::HighlightItem( sal_uInt16 nPos, bool bHighlight ) -{ - if( ! pMenu ) - return; - - long nX = 0; - size_t nCount = pMenu->pItemList->size(); - for ( size_t n = 0; n < nCount; n++ ) - { - MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n ); - if ( n == nPos ) - { - if ( pData->eType != MENUITEM_SEPARATOR ) - { - // #107747# give menuitems the height of the menubar - Rectangle aRect = Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), GetOutputSizePixel().Height()-2 ) ); - Push( PUSH_CLIPREGION ); - IntersectClipRegion( aRect ); - bool bRollover = bHighlight && nPos != nHighlightedItem; - if ( bHighlight ) - { - if( IsNativeControlSupported( CTRL_MENUBAR, PART_MENU_ITEM ) && - IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) ) - { - // draw background (transparency) - MenubarValue aControlValue; - aControlValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); - - if ( !Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() ) - Erase(); - else - { - Point tmp(0,0); - Rectangle aBgRegion( tmp, GetOutputSizePixel() ); - DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, - aBgRegion, - CTRL_STATE_ENABLED, - aControlValue, - OUString() ); - } - - ImplAddNWFSeparator( this, aControlValue ); - - // draw selected item - ControlState nState = CTRL_STATE_ENABLED; - if ( bRollover ) - nState |= CTRL_STATE_ROLLOVER; - else - nState |= CTRL_STATE_SELECTED; - DrawNativeControl( CTRL_MENUBAR, PART_MENU_ITEM, - aRect, - nState, - aControlValue, - OUString() ); - } - else - { - if ( bRollover ) - SetFillColor( GetSettings().GetStyleSettings().GetMenuBarRolloverColor() ); - else - SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() ); - SetLineColor(); - DrawRect( aRect ); - } - } - else - { - if( IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) ) - { - MenubarValue aMenubarValue; - aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); - - if ( !Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() ) - Erase( aRect ); - else - { - // use full window size to get proper gradient - // but clip accordingly - Point aPt; - Rectangle aCtrlRect( aPt, GetOutputSizePixel() ); - - DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED, aMenubarValue, OUString() ); - } - - ImplAddNWFSeparator( this, aMenubarValue ); - } - else - Erase( aRect ); - } - Pop(); - pMenu->ImplPaint( this, 0, 0, pData, bHighlight, false, bRollover ); - } - return; - } - - nX += pData->aSz.Width(); - } -} - -Rectangle MenuBarWindow::ImplGetItemRect( sal_uInt16 nPos ) -{ - Rectangle aRect; - if( pMenu ) - { - long nX = 0; - size_t nCount = pMenu->pItemList->size(); - for ( size_t n = 0; n < nCount; n++ ) - { - MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n ); - if ( n == nPos ) - { - if ( pData->eType != MENUITEM_SEPARATOR ) - // #107747# give menuitems the height of the menubar - aRect = Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), GetOutputSizePixel().Height()-2 ) ); - break; - } - - nX += pData->aSz.Width(); - } - } - return aRect; -} - -void MenuBarWindow::KeyInput( const KeyEvent& rKEvent ) -{ - if ( !ImplHandleKeyEvent( rKEvent ) ) - Window::KeyInput( rKEvent ); -} - -bool MenuBarWindow::ImplHandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu ) -{ - if( ! pMenu ) - return false; - - if ( pMenu->bInCallback ) - return true; // swallow - - bool bDone = false; - sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode(); - - if( GetParent() ) - { - if( GetParent()->GetWindow( WINDOW_CLIENT )->IsSystemWindow() ) - { - SystemWindow *pSysWin = (SystemWindow*)GetParent()->GetWindow( WINDOW_CLIENT ); - if( pSysWin->GetTaskPaneList() ) - if( pSysWin->GetTaskPaneList()->HandleKeyEvent( rKEvent ) ) - return true; - } - } - - if ( nCode == KEY_MENU && !rKEvent.GetKeyCode().IsShift() ) // only F10, not Shift-F10 - { - mbAutoPopup = ImplGetSVData()->maNWFData.mbOpenMenuOnF10; - if ( nHighlightedItem == ITEMPOS_INVALID ) - { - ChangeHighlightItem( 0, false ); - GrabFocus(); - } - else - { - ChangeHighlightItem( ITEMPOS_INVALID, false ); - nSaveFocusId = 0; - } - bDone = true; - } - else if ( bFromMenu ) - { - if ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) || - ( nCode == KEY_HOME ) || ( nCode == KEY_END ) ) - { - sal_uInt16 n = nHighlightedItem; - if ( n == ITEMPOS_INVALID ) - { - if ( nCode == KEY_LEFT) - n = 0; - else - n = pMenu->GetItemCount()-1; - } - - // handling gtk like (aka mbOpenMenuOnF10) - // do not highlight an item when opening a sub menu - // unless there already was a higlighted sub menu item - bool bWasHighlight = false; - if( pActivePopup ) - { - MenuFloatingWindow* pSubWindow = dynamic_cast<MenuFloatingWindow*>(pActivePopup->ImplGetWindow()); - if( pSubWindow ) - bWasHighlight = (pSubWindow->GetHighlightedItem() != ITEMPOS_INVALID); - } - - sal_uInt16 nLoop = n; - - if( nCode == KEY_HOME ) - { n = (sal_uInt16)-1; nLoop = n+1; } - if( nCode == KEY_END ) - { n = pMenu->GetItemCount(); nLoop = n-1; } - - do - { - if ( nCode == KEY_LEFT || nCode == KEY_END ) - { - if ( n ) - n--; - else - n = pMenu->GetItemCount()-1; - } - if ( nCode == KEY_RIGHT || nCode == KEY_HOME ) - { - n++; - if ( n >= pMenu->GetItemCount() ) - n = 0; - } - - MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n ); - if ( ( pData->eType != MENUITEM_SEPARATOR ) && pMenu->ImplIsVisible( n ) ) - { - bool bDoSelect = true; - if( ImplGetSVData()->maNWFData.mbOpenMenuOnF10 ) - bDoSelect = bWasHighlight; - ChangeHighlightItem( n, bDoSelect ); - break; - } - } while ( n != nLoop ); - bDone = true; - } - else if ( nCode == KEY_RETURN ) - { - if( pActivePopup ) KillActivePopup(); - else - if ( !mbAutoPopup ) - { - ImplCreatePopup( true ); - mbAutoPopup = true; - } - bDone = true; - } - else if ( ( nCode == KEY_UP ) || ( nCode == KEY_DOWN ) ) - { - if ( !mbAutoPopup ) - { - ImplCreatePopup( true ); - mbAutoPopup = true; - } - bDone = true; - } - else if ( nCode == KEY_ESCAPE || ( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() ) ) - { - if( pActivePopup ) - { - // bring focus to menu bar without any open popup - mbAutoPopup = false; - sal_uInt16 n = nHighlightedItem; - nHighlightedItem = ITEMPOS_INVALID; - bStayActive = true; - ChangeHighlightItem( n, false ); - bStayActive = false; - KillActivePopup(); - GrabFocus(); - } - else - ChangeHighlightItem( ITEMPOS_INVALID, false ); - - if( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() ) - { - // put focus into document - GrabFocusToDocument(); - } - - bDone = true; - } - } - - if ( !bDone && ( bFromMenu || rKEvent.GetKeyCode().IsMod2() ) ) - { - sal_Unicode nCharCode = rKEvent.GetCharCode(); - if ( nCharCode ) - { - sal_uInt16 nEntry, nDuplicates; - MenuItemData* pData = pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nEntry, nDuplicates, nHighlightedItem ); - if ( pData && (nEntry != ITEMPOS_INVALID) ) - { - mbAutoPopup = true; - ChangeHighlightItem( nEntry, true ); - bDone = true; - } - } - } - return bDone; -} - -void MenuBarWindow::Paint( const Rectangle& ) -{ - if( ! pMenu ) - return; - - // no VCL paint if native menus - if( pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar() ) - { - ImplGetFrame()->DrawMenuBar(); - return; - } - - if( IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) ) - { - MenubarValue aMenubarValue; - aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); - - if ( !Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() ) - Erase(); - else - { - Point aPt; - Rectangle aCtrlRegion( aPt, GetOutputSizePixel() ); - - DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aMenubarValue, OUString() ); - } - - ImplAddNWFSeparator( this, aMenubarValue ); - } - SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() ); - pMenu->ImplPaint( this, 0 ); - if ( nHighlightedItem != ITEMPOS_INVALID ) - HighlightItem( nHighlightedItem, true ); - - // in high contrast mode draw a separating line on the lower edge - if( ! IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) && - GetSettings().GetStyleSettings().GetHighContrastMode() ) - { - Push( PUSH_LINECOLOR | PUSH_MAPMODE ); - SetLineColor( Color( COL_WHITE ) ); - SetMapMode( MapMode( MAP_PIXEL ) ); - Size aSize = GetSizePixel(); - DrawLine( Point( 0, aSize.Height()-1 ), Point( aSize.Width()-1, aSize.Height()-1 ) ); - Pop(); - } - -} - -void MenuBarWindow::Resize() -{ - Size aOutSz = GetOutputSizePixel(); - long n = aOutSz.Height()-4; - long nX = aOutSz.Width()-3; - long nY = 2; - - if ( aCloser.IsVisible() ) - { - aCloser.Hide(); - aCloser.SetImages( n ); - Size aTbxSize( aCloser.CalcWindowSizePixel() ); - nX -= aTbxSize.Width(); - long nTbxY = (aOutSz.Height() - aTbxSize.Height())/2; - aCloser.setPosSizePixel( nX, nTbxY, aTbxSize.Width(), aTbxSize.Height() ); - nX -= 3; - aCloser.Show(); - } - if ( aFloatBtn.IsVisible() ) - { - nX -= n; - aFloatBtn.setPosSizePixel( nX, nY, n, n ); - } - if ( aHideBtn.IsVisible() ) - { - nX -= n; - aHideBtn.setPosSizePixel( nX, nY, n, n ); - } - - aFloatBtn.SetSymbol( SYMBOL_FLOAT ); - aHideBtn.SetSymbol( SYMBOL_HIDE ); - //aCloser.SetSymbol( SYMBOL_CLOSE ); //is a toolbox now - - Invalidate(); -} - -sal_uInt16 MenuBarWindow::ImplFindEntry( const Point& rMousePos ) const -{ - if( pMenu ) - { - long nX = 0; - size_t nCount = pMenu->pItemList->size(); - for ( size_t n = 0; n < nCount; n++ ) - { - MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n ); - if ( pMenu->ImplIsVisible( n ) ) - { - nX += pData->aSz.Width(); - if ( nX > rMousePos.X() ) - return (sal_uInt16)n; - } - } - } - return ITEMPOS_INVALID; -} - -void MenuBarWindow::RequestHelp( const HelpEvent& rHEvt ) -{ - sal_uInt16 nId = nHighlightedItem; - if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) ) - ChangeHighlightItem( ITEMPOS_INVALID, true ); - - Rectangle aHighlightRect( ImplGetItemRect( nHighlightedItem ) ); - if( !ImplHandleHelpEvent( this, pMenu, nId, rHEvt, aHighlightRect ) ) - Window::RequestHelp( rHEvt ); -} - -void MenuBarWindow::StateChanged( StateChangedType nType ) -{ - Window::StateChanged( nType ); - - if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) || - ( nType == STATE_CHANGE_CONTROLBACKGROUND ) ) - { - ImplInitMenuWindow( this, false, true ); - Invalidate(); - } - else if( pMenu ) - pMenu->ImplKillLayoutData(); - -} - -void MenuBarWindow::ImplLayoutChanged() -{ - if( pMenu ) - { - ImplInitMenuWindow( this, true, true ); - // if the font was changed. - long nHeight = pMenu->ImplCalcSize( this ).Height(); - - // depending on the native implementation or the displayable flag - // the menubar windows is suppressed (ie, height=0) - if( !((MenuBar*) pMenu)->IsDisplayable() || - ( pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar() ) ) - nHeight = 0; - - setPosSizePixel( 0, 0, 0, nHeight, WINDOW_POSSIZE_HEIGHT ); - GetParent()->Resize(); - Invalidate(); - Resize(); - if( pMenu ) - pMenu->ImplKillLayoutData(); - } -} - -void MenuBarWindow::ImplInitStyleSettings() -{ - if( IsNativeControlSupported( CTRL_MENUBAR, PART_MENU_ITEM ) && - IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) ) - { - AllSettings aSettings( GetSettings() ); - ImplGetFrame()->UpdateSettings( aSettings ); // to update persona - StyleSettings aStyle( aSettings.GetStyleSettings() ); - Color aHighlightTextColor = ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor; - if( aHighlightTextColor != Color( COL_TRANSPARENT ) ) - { - aStyle.SetMenuHighlightTextColor( aHighlightTextColor ); - } - aSettings.SetStyleSettings( aStyle ); - OutputDevice::SetSettings( aSettings ); - } -} - -void MenuBarWindow::DataChanged( const DataChangedEvent& rDCEvt ) -{ - Window::DataChanged( rDCEvt ); - - if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || - (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || - ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && - (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) - { - ImplInitStyleSettings(); - ImplLayoutChanged(); - } -} - -void MenuBarWindow::LoseFocus() -{ - if ( !HasChildPathFocus( true ) ) - ChangeHighlightItem( ITEMPOS_INVALID, false, false ); -} - -void MenuBarWindow::GetFocus() -{ - if ( nHighlightedItem == ITEMPOS_INVALID ) - { - mbAutoPopup = false; // do not open menu when activated by focus handling like taskpane cycling - ChangeHighlightItem( 0, false ); - } -} - -::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > MenuBarWindow::CreateAccessible() -{ - ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc; - - if ( pMenu ) - xAcc = pMenu->GetAccessible(); - - return xAcc; -} - -sal_uInt16 MenuBarWindow::AddMenuBarButton( const Image& i_rImage, const Link& i_rLink, const OUString& i_rToolTip, sal_uInt16 i_nPos ) -{ - // find first free button id - sal_uInt16 nId = IID_DOCUMENTCLOSE; - std::map< sal_uInt16, AddButtonEntry >::const_iterator it; - if( i_nPos > m_aAddButtons.size() ) - i_nPos = static_cast<sal_uInt16>(m_aAddButtons.size()); - do - { - nId++; - it = m_aAddButtons.find( nId ); - } while( it != m_aAddButtons.end() && nId < 128 ); - DBG_ASSERT( nId < 128, "too many addbuttons in menubar" ); - AddButtonEntry& rNewEntry = m_aAddButtons[nId]; - rNewEntry.m_nId = nId; - rNewEntry.m_aSelectLink = i_rLink; - aCloser.InsertItem( nId, i_rImage, 0, 0 ); - aCloser.calcMinSize(); - ShowButtons( aCloser.IsItemVisible( IID_DOCUMENTCLOSE ), - aFloatBtn.IsVisible(), - aHideBtn.IsVisible() ); - ImplLayoutChanged(); - - if( pMenu->mpSalMenu ) - pMenu->mpSalMenu->AddMenuBarButton( SalMenuButtonItem( nId, i_rImage, i_rToolTip ) ); - - return nId; -} - -void MenuBarWindow::SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link& rLink ) -{ - std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( nId ); - if( it != m_aAddButtons.end() ) - it->second.m_aHighlightLink = rLink; -} - -Rectangle MenuBarWindow::GetMenuBarButtonRectPixel( sal_uInt16 nId ) -{ - Rectangle aRect; - if( m_aAddButtons.find( nId ) != m_aAddButtons.end() ) - { - if( pMenu->mpSalMenu ) - { - aRect = pMenu->mpSalMenu->GetMenuBarButtonRectPixel( nId, ImplGetWindowImpl()->mpFrame ); - if( aRect == Rectangle( Point( -1, -1 ), Size( 1, 1 ) ) ) - { - // system menu button is somewhere but location cannot be determined - return Rectangle(); - } - } - - if( aRect.IsEmpty() ) - { - aRect = aCloser.GetItemRect( nId ); - Point aOffset = aCloser.OutputToScreenPixel( Point() ); - aRect.Move( aOffset.X(), aOffset.Y() ); - } - } - return aRect; -} - -void MenuBarWindow::RemoveMenuBarButton( sal_uInt16 nId ) -{ - sal_uInt16 nPos = aCloser.GetItemPos( nId ); - aCloser.RemoveItem( nPos ); - m_aAddButtons.erase( nId ); - aCloser.calcMinSize(); - ImplLayoutChanged(); - - if( pMenu->mpSalMenu ) - pMenu->mpSalMenu->RemoveMenuBarButton( nId ); -} - -bool MenuBarWindow::HandleMenuButtonEvent( sal_uInt16 i_nButtonId ) -{ - std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( i_nButtonId ); - if( it != m_aAddButtons.end() ) - { - MenuBar::MenuBarButtonCallbackArg aArg; - aArg.nId = it->first; - aArg.bHighlight = true; - aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu); - return it->second.m_aSelectLink.Call( &aArg ); - } - return false; -} - ImplMenuDelData::ImplMenuDelData( const Menu* pMenu ) : mpNext( 0 ) , mpMenu( 0 ) diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx new file mode 100644 index 0000000..b265517 --- /dev/null +++ b/vcl/source/window/menubarwindow.cxx @@ -0,0 +1,1156 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "menubarwindow.hxx" +#include "menuitemlist.hxx" +#include "menufloatingwindow.hxx" + +#include <vcl/dockingarea.hxx> +#include <vcl/settings.hxx> +#include <vcl/taskpanelist.hxx> + +#include <salframe.hxx> +#include <salmenu.hxx> +#include <svdata.hxx> +#include <svids.hrc> +#include <window.h> + +// document closing button +#define IID_DOCUMENTCLOSE 1 + +DecoToolBox::DecoToolBox( Window* pParent, WinBits nStyle ) : + ToolBox( pParent, nStyle ) +{ + ImplInit(); +} + +void DecoToolBox::ImplInit() +{ + lastSize = -1; + calcMinSize(); +} + +void DecoToolBox::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + if ( rDCEvt.GetFlags() & SETTINGS_STYLE ) + { + calcMinSize(); + SetBackground(); + SetImages( 0, true); + } +} + +void DecoToolBox::calcMinSize() +{ + ToolBox aTbx( GetParent() ); + if( GetItemCount() == 0 ) + { + ResMgr* pResMgr = ImplGetResMgr(); + + Bitmap aBitmap; + if( pResMgr ) + aBitmap = Bitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) ); + aTbx.InsertItem( IID_DOCUMENTCLOSE, Image( aBitmap ) ); + } + else + { + sal_uInt16 nItems = GetItemCount(); + for( sal_uInt16 i = 0; i < nItems; i++ ) + { + sal_uInt16 nId = GetItemId( i ); + aTbx.InsertItem( nId, GetItemImage( nId ) ); + } + } + aTbx.SetOutStyle( TOOLBOX_STYLE_FLAT ); + maMinSize = aTbx.CalcWindowSizePixel(); +} + +void DecoToolBox::SetImages( long nMaxHeight, bool bForce ) +{ + long border = getMinSize().Height() - maImage.GetSizePixel().Height(); + + if( !nMaxHeight && lastSize != -1 ) + nMaxHeight = lastSize + border; // don't change anything if called with 0 + + if( nMaxHeight < getMinSize().Height() ) + nMaxHeight = getMinSize().Height(); + + if( (lastSize != nMaxHeight - border) || bForce ) + { + lastSize = nMaxHeight - border; + + Color aEraseColor( 255, 255, 255, 255 ); + BitmapEx aBmpExDst( maImage.GetBitmapEx() ); + BitmapEx aBmpExSrc( aBmpExDst ); + + aEraseColor.SetTransparency( 255 ); + aBmpExDst.Erase( aEraseColor ); + aBmpExDst.SetSizePixel( Size( lastSize, lastSize ) ); + + Rectangle aSrcRect( Point(0,0), maImage.GetSizePixel() ); + Rectangle aDestRect( Point((lastSize - maImage.GetSizePixel().Width())/2, + (lastSize - maImage.GetSizePixel().Height())/2 ), + maImage.GetSizePixel() ); + + aBmpExDst.CopyPixel( aDestRect, aSrcRect, &aBmpExSrc ); + SetItemImage( IID_DOCUMENTCLOSE, Image( aBmpExDst ) ); + } +} + +MenuBarWindow::MenuBarWindow( Window* pParent ) : + Window( pParent, 0 ), + aCloser( this ), + aFloatBtn( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE ), + aHideBtn( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE ) +{ + SetType( WINDOW_MENUBARWINDOW ); + pMenu = NULL; + pActivePopup = NULL; + nSaveFocusId = 0; + nHighlightedItem = ITEMPOS_INVALID; + nRolloveredItem = ITEMPOS_INVALID; + mbAutoPopup = true; + nSaveFocusId = 0; + bIgnoreFirstMove = true; + bStayActive = false; + + ResMgr* pResMgr = ImplGetResMgr(); + + if( pResMgr ) + { + BitmapEx aBitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) ); + aCloser.maImage = Image( aBitmap ); + + aCloser.SetOutStyle( TOOLBOX_STYLE_FLAT ); + aCloser.SetBackground(); + aCloser.SetPaintTransparent( true ); + aCloser.SetParentClipMode( PARENTCLIPMODE_NOCLIP ); + + aCloser.InsertItem( IID_DOCUMENTCLOSE, aCloser.maImage, 0 ); + aCloser.SetSelectHdl( LINK( this, MenuBarWindow, CloserHdl ) ); + aCloser.AddEventListener( LINK( this, MenuBarWindow, ToolboxEventHdl ) ); + aCloser.SetQuickHelpText( IID_DOCUMENTCLOSE, ResId(SV_HELPTEXT_CLOSEDOCUMENT, *pResMgr).toString() ); + + aFloatBtn.SetClickHdl( LINK( this, MenuBarWindow, FloatHdl ) ); + aFloatBtn.SetSymbol( SYMBOL_FLOAT ); + aFloatBtn.SetQuickHelpText( ResId(SV_HELPTEXT_RESTORE, *pResMgr).toString() ); + + aHideBtn.SetClickHdl( LINK( this, MenuBarWindow, HideHdl ) ); + aHideBtn.SetSymbol( SYMBOL_HIDE ); + aHideBtn.SetQuickHelpText( ResId(SV_HELPTEXT_MINIMIZE, *pResMgr).toString() ); + } + + ImplInitStyleSettings(); + + AddEventListener( LINK( this, MenuBarWindow, ShowHideListener ) ); +} + +MenuBarWindow::~MenuBarWindow() +{ + aCloser.RemoveEventListener( LINK( this, MenuBarWindow, ToolboxEventHdl ) ); + RemoveEventListener( LINK( this, MenuBarWindow, ShowHideListener ) ); +} + +void MenuBarWindow::SetMenu( MenuBar* pMen ) +{ + pMenu = pMen; + KillActivePopup(); + nHighlightedItem = ITEMPOS_INVALID; + ImplInitMenuWindow( this, true, true ); + if ( pMen ) + { + aCloser.ShowItem( IID_DOCUMENTCLOSE, pMen->HasCloser() ); + aCloser.Show( pMen->HasCloser() || !m_aAddButtons.empty() ); + aFloatBtn.Show( pMen->HasFloatButton() ); + aHideBtn.Show( pMen->HasHideButton() ); + } + Invalidate(); + + // show and connect native menubar + if( pMenu && pMenu->ImplGetSalMenu() ) + { + if( pMenu->ImplGetSalMenu()->VisibleMenuBar() ) + ImplGetFrame()->SetMenu( pMenu->ImplGetSalMenu() ); + + pMenu->ImplGetSalMenu()->SetFrame( ImplGetFrame() ); + } +} + +void MenuBarWindow::ShowButtons( bool bClose, bool bFloat, bool bHide ) +{ + aCloser.ShowItem( IID_DOCUMENTCLOSE, bClose ); + aCloser.Show( bClose || ! m_aAddButtons.empty() ); + aFloatBtn.Show( bFloat ); + aHideBtn.Show( bHide ); + Resize(); +} + +Size MenuBarWindow::MinCloseButtonSize() +{ + return aCloser.getMinSize(); +} + +IMPL_LINK_NOARG(MenuBarWindow, CloserHdl) +{ + if( ! pMenu ) + return 0; + + if( aCloser.GetCurItemId() == IID_DOCUMENTCLOSE ) + { + // #i106052# call close hdl asynchronously to ease handler implementation + // this avoids still being in the handler while the DecoToolBox already + // gets destroyed + Application::PostUserEvent( ((MenuBar*)pMenu)->GetCloserHdl(), pMenu ); + } + else + { + std::map<sal_uInt16,AddButtonEntry>::iterator it = m_aAddButtons.find( aCloser.GetCurItemId() ); + if( it != m_aAddButtons.end() ) + { + MenuBar::MenuBarButtonCallbackArg aArg; + aArg.nId = it->first; + aArg.bHighlight = (aCloser.GetHighlightItemId() == it->first); + aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu); + return it->second.m_aSelectLink.Call( &aArg ); + } + } + return 0; +} + +IMPL_LINK( MenuBarWindow, ToolboxEventHdl, VclWindowEvent*, pEvent ) +{ + if( ! pMenu ) + return 0; + + MenuBar::MenuBarButtonCallbackArg aArg; + aArg.nId = 0xffff; + aArg.bHighlight = (pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT); + aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu); + if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT ) + aArg.nId = aCloser.GetHighlightItemId(); + else if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHTOFF ) + { + sal_uInt16 nPos = static_cast< sal_uInt16 >(reinterpret_cast<sal_IntPtr>(pEvent->GetData())); + aArg.nId = aCloser.GetItemId( nPos ); + } + std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( aArg.nId ); + if( it != m_aAddButtons.end() ) + { + it->second.m_aHighlightLink.Call( &aArg ); + } + return 0; +} + +IMPL_LINK( MenuBarWindow, ShowHideListener, VclWindowEvent*, pEvent ) +{ + if( ! pMenu ) + return 0; + + if( pEvent->GetId() == VCLEVENT_WINDOW_SHOW ) + pMenu->ImplCallEventListeners( VCLEVENT_MENU_SHOW, ITEMPOS_INVALID ); + else if( pEvent->GetId() == VCLEVENT_WINDOW_HIDE ) + pMenu->ImplCallEventListeners( VCLEVENT_MENU_HIDE, ITEMPOS_INVALID ); + return 0; +} + +IMPL_LINK_NOARG(MenuBarWindow, FloatHdl) +{ + return pMenu ? ((MenuBar*)pMenu)->GetFloatButtonClickHdl().Call( pMenu ) : 0; +} + +IMPL_LINK_NOARG(MenuBarWindow, HideHdl) +{ + return pMenu ? ((MenuBar*)pMenu)->GetHideButtonClickHdl().Call( pMenu ) : 0; +} + +void MenuBarWindow::ImplCreatePopup( bool bPreSelectFirst ) +{ + MenuItemData* pItemData = pMenu ? pMenu->GetItemList()->GetDataFromPos( nHighlightedItem ) : NULL; + if ( pItemData ) + { + bIgnoreFirstMove = true; + if ( pActivePopup && ( pActivePopup != pItemData->pSubMenu ) ) + { + KillActivePopup(); + } + if ( pItemData->bEnabled && pItemData->pSubMenu && ( nHighlightedItem != ITEMPOS_INVALID ) && ( pItemData->pSubMenu != pActivePopup ) ) + { + pActivePopup = (PopupMenu*)pItemData->pSubMenu; + long nX = 0; + MenuItemData* pData = 0; + for ( sal_uLong n = 0; n < nHighlightedItem; n++ ) + { + pData = pMenu->GetItemList()->GetDataFromPos( n ); + nX += pData->aSz.Width(); + } + pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem ); + Point aItemTopLeft( nX, 0 ); + Point aItemBottomRight( aItemTopLeft ); + aItemBottomRight.X() += pData->aSz.Width(); + + // the menu bar could have height 0 in fullscreen mode: + // so do not use always WindowHeight, as ItemHeight < WindowHeight. + if ( GetSizePixel().Height() ) + { + // #107747# give menuitems the height of the menubar + aItemBottomRight.Y() += GetOutputSizePixel().Height()-1; + } + + // ImplExecute is not modal... + // #99071# do not grab the focus, otherwise it will be restored to the menubar + // when the frame is reactivated later + //GrabFocus(); + pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_NOHORZPLACEMENT, pMenu, bPreSelectFirst ); + if ( pActivePopup ) + { + // does not have a window, if aborted before or if there are no entries + if ( pActivePopup->ImplGetFloatingWindow() ) + pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this ); + else + pActivePopup = NULL; + } + } + } +} + +void MenuBarWindow::KillActivePopup() +{ + if ( pActivePopup ) + { + if( pActivePopup->pWindow != NULL ) + if( ((FloatingWindow *) pActivePopup->pWindow)->IsInCleanUp() ) + return; // kill it later + + if ( pActivePopup->bInCallback ) + pActivePopup->bCanceled = true; + + pActivePopup->bInCallback = true; + pActivePopup->Deactivate(); + pActivePopup->bInCallback = false; + // check for pActivePopup, if stopped by deactivate... + if ( pActivePopup->ImplGetWindow() ) + { + pActivePopup->ImplGetFloatingWindow()->StopExecute(); + pActivePopup->ImplGetFloatingWindow()->doShutdown(); + pActivePopup->pWindow->doLazyDelete(); + pActivePopup->pWindow = NULL; + } + pActivePopup = 0; + } +} + +void MenuBarWindow::PopupClosed( Menu* pPopup ) +{ + if ( pPopup == pActivePopup ) + { + KillActivePopup(); + ChangeHighlightItem( ITEMPOS_INVALID, false, ImplGetFrameWindow()->ImplGetFrameData()->mbHasFocus, false ); + } +} + +void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt ) +{ + mbAutoPopup = true; + sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() ); + if ( ( nEntry != ITEMPOS_INVALID ) && !pActivePopup ) + { + ChangeHighlightItem( nEntry, false ); + } + else + { + KillActivePopup(); + ChangeHighlightItem( ITEMPOS_INVALID, false ); + } +} + +void MenuBarWindow::MouseButtonUp( const MouseEvent& ) +{ +} + +void MenuBarWindow::MouseMove( const MouseEvent& rMEvt ) +{ + if ( rMEvt.IsSynthetic() || rMEvt.IsEnterWindow() ) + return; + + if ( rMEvt.IsLeaveWindow() ) + { + if ( nRolloveredItem != ITEMPOS_INVALID && nRolloveredItem != nHighlightedItem ) + HighlightItem( nRolloveredItem, false ); + + nRolloveredItem = ITEMPOS_INVALID; + return; + } + + sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() ); + if ( nHighlightedItem == ITEMPOS_INVALID ) + { + if ( nRolloveredItem != nEntry ) + { + if ( nRolloveredItem != ITEMPOS_INVALID ) + HighlightItem( nRolloveredItem, false ); + + nRolloveredItem = nEntry; + HighlightItem( nRolloveredItem, true ); + } + return; + } + nRolloveredItem = nEntry; + + if( bIgnoreFirstMove ) + { + bIgnoreFirstMove = false; + return; + } + + if ( ( nEntry != ITEMPOS_INVALID ) + && ( nEntry != nHighlightedItem ) ) + ChangeHighlightItem( nEntry, false ); +} + +void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, bool bSelectEntry, bool bAllowRestoreFocus, bool bDefaultToDocument) +{ + if( ! pMenu ) + return; + + // #57934# close active popup if applicable, as TH's background storage works. + MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n ); + if ( pActivePopup && pActivePopup->ImplGetWindow() && ( !pNextData || ( pActivePopup != pNextData->pSubMenu ) ) ) + KillActivePopup(); // pActivePopup when applicable without pWin, if Rescheduled in Activate() + + // activate menubar only ones per cycle... + bool bJustActivated = false; + if ( ( nHighlightedItem == ITEMPOS_INVALID ) && ( n != ITEMPOS_INVALID ) ) + { + ImplGetSVData()->maWinData.mbNoDeactivate = true; + if( !bStayActive ) + { + // #105406# avoid saving the focus when we already have the focus + bool bNoSaveFocus = (this == ImplGetSVData()->maWinData.mpFocusWin ); + + if( nSaveFocusId ) + { + if( !ImplGetSVData()->maWinData.mbNoSaveFocus ) + { + // we didn't clean up last time + Window::EndSaveFocus( nSaveFocusId, false ); // clean up + nSaveFocusId = 0; + if( !bNoSaveFocus ) + nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated + } + else { + ; // do nothing: we 're activated again from taskpanelist, focus was already saved + } + } + else + { + if( !bNoSaveFocus ) + nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated + } + } + else + bStayActive = false; + pMenu->bInCallback = true; // set here if Activate overloaded + pMenu->Activate(); + pMenu->bInCallback = false; + bJustActivated = true; + } + else if ( ( nHighlightedItem != ITEMPOS_INVALID ) && ( n == ITEMPOS_INVALID ) ) + { + pMenu->bInCallback = true; + pMenu->Deactivate(); + pMenu->bInCallback = false; + ImplGetSVData()->maWinData.mbNoDeactivate = false; + if( !ImplGetSVData()->maWinData.mbNoSaveFocus ) + { + sal_uLong nTempFocusId = nSaveFocusId; + nSaveFocusId = 0; + Window::EndSaveFocus( nTempFocusId, bAllowRestoreFocus ); + // #105406# restore focus to document if we could not save focus before + if( bDefaultToDocument && !nTempFocusId && bAllowRestoreFocus ) + GrabFocusToDocument(); + } + } + + if ( nHighlightedItem != ITEMPOS_INVALID ) + { + if ( nHighlightedItem != nRolloveredItem ) + HighlightItem( nHighlightedItem, false ); + + pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem ); + } + + nHighlightedItem = (sal_uInt16)n; + DBG_ASSERT( ( nHighlightedItem == ITEMPOS_INVALID ) || pMenu->ImplIsVisible( nHighlightedItem ), "ChangeHighlightItem: Not visible!" ); + if ( nHighlightedItem != ITEMPOS_INVALID ) + HighlightItem( nHighlightedItem, true ); + else if ( nRolloveredItem != ITEMPOS_INVALID ) + HighlightItem( nRolloveredItem, true ); + pMenu->SetHighlightItem(nHighlightedItem); + pMenu->ImplCallHighlight(nHighlightedItem); + + if( mbAutoPopup ) + ImplCreatePopup( bSelectEntry ); + + // #58935# #73659# Focus, if no popup underneath... + if ( bJustActivated && !pActivePopup ) + GrabFocus(); +} + +static int ImplGetTopDockingAreaHeight( Window *pWindow ) +{ + // find docking area that is top aligned and return its height + // note: dockingareas are direct children of the SystemWindow + if( pWindow->ImplGetFrameWindow() ) + { + Window *pWin = pWindow->ImplGetFrameWindow()->GetWindow( WINDOW_FIRSTCHILD ); //mpWindowImpl->mpFirstChild; + while( pWin ) + { + if( pWin->IsSystemWindow() ) + { + Window *pChildWin = pWin->GetWindow( WINDOW_FIRSTCHILD ); //mpWindowImpl->mpFirstChild; + while( pChildWin ) + { + DockingAreaWindow *pDockingArea = NULL; + if ( pChildWin->GetType() == WINDOW_DOCKINGAREA ) + pDockingArea = static_cast< DockingAreaWindow* >( pChildWin ); + + if( pDockingArea && pDockingArea->GetAlign() == WINDOWALIGN_TOP && + pDockingArea->IsVisible() && pDockingArea->GetOutputSizePixel().Height() != 0 ) + { + return pDockingArea->GetOutputSizePixel().Height(); + } + + pChildWin = pChildWin->GetWindow( WINDOW_NEXT ); //mpWindowImpl->mpNext; + } + + } + + pWin = pWin->GetWindow( WINDOW_NEXT ); //mpWindowImpl->mpNext; + } + } + return 0; +} + +static void ImplAddNWFSeparator( Window *pThis, const MenubarValue& rMenubarValue ) +{ + // add a separator if + // - we have an adjacent docking area + // - and if toolbars would draw them as well (mbDockingAreaSeparateTB must not be set, see dockingarea.cxx) + if( rMenubarValue.maTopDockingAreaHeight && !ImplGetSVData()->maNWFData.mbDockingAreaSeparateTB && !ImplGetSVData()->maNWFData.mbDockingAreaAvoidTBFrames ) + { + // note: the menubar only provides the upper (dark) half of it, the rest (bright part) is drawn by the docking area + + pThis->SetLineColor( pThis->GetSettings().GetStyleSettings().GetSeparatorColor() ); + Point aPt; + Rectangle aRect( aPt, pThis->GetOutputSizePixel() ); + pThis->DrawLine( aRect.BottomLeft(), aRect.BottomRight() ); + } +} + +void MenuBarWindow::HighlightItem( sal_uInt16 nPos, bool bHighlight ) +{ + if( ! pMenu ) + return; + + long nX = 0; + size_t nCount = pMenu->pItemList->size(); + for ( size_t n = 0; n < nCount; n++ ) + { + MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n ); + if ( n == nPos ) + { + if ( pData->eType != MENUITEM_SEPARATOR ) + { + // #107747# give menuitems the height of the menubar + Rectangle aRect = Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), GetOutputSizePixel().Height()-2 ) ); + Push( PUSH_CLIPREGION ); + IntersectClipRegion( aRect ); + bool bRollover = bHighlight && nPos != nHighlightedItem; + if ( bHighlight ) + { + if( IsNativeControlSupported( CTRL_MENUBAR, PART_MENU_ITEM ) && + IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) ) + { + // draw background (transparency) + MenubarValue aControlValue; + aControlValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); + + if ( !Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() ) + Erase(); + else + { + Point tmp(0,0); + Rectangle aBgRegion( tmp, GetOutputSizePixel() ); + DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, + aBgRegion, + CTRL_STATE_ENABLED, + aControlValue, + OUString() ); + } + + ImplAddNWFSeparator( this, aControlValue ); + + // draw selected item + ControlState nState = CTRL_STATE_ENABLED; + if ( bRollover ) + nState |= CTRL_STATE_ROLLOVER; + else + nState |= CTRL_STATE_SELECTED; + DrawNativeControl( CTRL_MENUBAR, PART_MENU_ITEM, + aRect, + nState, + aControlValue, + OUString() ); + } + else + { + if ( bRollover ) + SetFillColor( GetSettings().GetStyleSettings().GetMenuBarRolloverColor() ); + else + SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() ); + SetLineColor(); + DrawRect( aRect ); + } + } + else + { + if( IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) ) + { + MenubarValue aMenubarValue; + aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); + + if ( !Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() ) + Erase( aRect ); + else + { + // use full window size to get proper gradient + // but clip accordingly + Point aPt; + Rectangle aCtrlRect( aPt, GetOutputSizePixel() ); + + DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED, aMenubarValue, OUString() ); + } + + ImplAddNWFSeparator( this, aMenubarValue ); + } + else + Erase( aRect ); + } + Pop(); + pMenu->ImplPaint( this, 0, 0, pData, bHighlight, false, bRollover ); + } + return; + } + + nX += pData->aSz.Width(); + } +} + +Rectangle MenuBarWindow::ImplGetItemRect( sal_uInt16 nPos ) +{ + Rectangle aRect; + if( pMenu ) + { + long nX = 0; + size_t nCount = pMenu->pItemList->size(); + for ( size_t n = 0; n < nCount; n++ ) + { + MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n ); + if ( n == nPos ) + { + if ( pData->eType != MENUITEM_SEPARATOR ) + // #107747# give menuitems the height of the menubar + aRect = Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), GetOutputSizePixel().Height()-2 ) ); + break; + } + + nX += pData->aSz.Width(); + } + } + return aRect; +} + +void MenuBarWindow::KeyInput( const KeyEvent& rKEvent ) +{ + if ( !ImplHandleKeyEvent( rKEvent ) ) + Window::KeyInput( rKEvent ); +} + +bool MenuBarWindow::ImplHandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu ) +{ + if( ! pMenu ) + return false; + + if ( pMenu->bInCallback ) + return true; // swallow + + bool bDone = false; + sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode(); + + if( GetParent() ) + { + if( GetParent()->GetWindow( WINDOW_CLIENT )->IsSystemWindow() ) + { + SystemWindow *pSysWin = (SystemWindow*)GetParent()->GetWindow( WINDOW_CLIENT ); + if( pSysWin->GetTaskPaneList() ) + if( pSysWin->GetTaskPaneList()->HandleKeyEvent( rKEvent ) ) + return true; + } + } + + if ( nCode == KEY_MENU && !rKEvent.GetKeyCode().IsShift() ) // only F10, not Shift-F10 + { + mbAutoPopup = ImplGetSVData()->maNWFData.mbOpenMenuOnF10; + if ( nHighlightedItem == ITEMPOS_INVALID ) + { + ChangeHighlightItem( 0, false ); + GrabFocus(); + } + else + { + ChangeHighlightItem( ITEMPOS_INVALID, false ); + nSaveFocusId = 0; + } + bDone = true; + } + else if ( bFromMenu ) + { + if ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) || + ( nCode == KEY_HOME ) || ( nCode == KEY_END ) ) + { + sal_uInt16 n = nHighlightedItem; + if ( n == ITEMPOS_INVALID ) + { + if ( nCode == KEY_LEFT) + n = 0; + else + n = pMenu->GetItemCount()-1; + } + + // handling gtk like (aka mbOpenMenuOnF10) + // do not highlight an item when opening a sub menu + // unless there already was a higlighted sub menu item + bool bWasHighlight = false; + if( pActivePopup ) + { + MenuFloatingWindow* pSubWindow = dynamic_cast<MenuFloatingWindow*>(pActivePopup->ImplGetWindow()); + if( pSubWindow ) + bWasHighlight = (pSubWindow->GetHighlightedItem() != ITEMPOS_INVALID); + } + + sal_uInt16 nLoop = n; + + if( nCode == KEY_HOME ) + { n = (sal_uInt16)-1; nLoop = n+1; } + if( nCode == KEY_END ) + { n = pMenu->GetItemCount(); nLoop = n-1; } + + do + { + if ( nCode == KEY_LEFT || nCode == KEY_END ) + { + if ( n ) + n--; + else + n = pMenu->GetItemCount()-1; + } + if ( nCode == KEY_RIGHT || nCode == KEY_HOME ) + { + n++; + if ( n >= pMenu->GetItemCount() ) + n = 0; + } + + MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n ); + if ( ( pData->eType != MENUITEM_SEPARATOR ) && pMenu->ImplIsVisible( n ) ) + { + bool bDoSelect = true; + if( ImplGetSVData()->maNWFData.mbOpenMenuOnF10 ) + bDoSelect = bWasHighlight; + ChangeHighlightItem( n, bDoSelect ); + break; + } + } while ( n != nLoop ); + bDone = true; + } + else if ( nCode == KEY_RETURN ) + { + if( pActivePopup ) KillActivePopup(); + else + if ( !mbAutoPopup ) + { + ImplCreatePopup( true ); + mbAutoPopup = true; + } + bDone = true; + } + else if ( ( nCode == KEY_UP ) || ( nCode == KEY_DOWN ) ) + { + if ( !mbAutoPopup ) + { + ImplCreatePopup( true ); + mbAutoPopup = true; + } + bDone = true; + } + else if ( nCode == KEY_ESCAPE || ( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() ) ) + { + if( pActivePopup ) + { + // bring focus to menu bar without any open popup + mbAutoPopup = false; + sal_uInt16 n = nHighlightedItem; + nHighlightedItem = ITEMPOS_INVALID; + bStayActive = true; + ChangeHighlightItem( n, false ); + bStayActive = false; + KillActivePopup(); + GrabFocus(); + } + else ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits