LCOV - code coverage report
Current view: top level - vcl/source/window - menufloatingwindow.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 84 644 13.0 %
Date: 2014-11-03 Functions: 14 44 31.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "menufloatingwindow.hxx"
      21             : #include "menuitemlist.hxx"
      22             : 
      23             : #include <svdata.hxx>
      24             : #include <vcl/decoview.hxx>
      25             : #include <vcl/settings.hxx>
      26             : #include <window.h>
      27             : 
      28          16 : MenuFloatingWindow::MenuFloatingWindow( Menu* pMen, vcl::Window* pParent, WinBits nStyle ) :
      29          16 :     FloatingWindow( pParent, nStyle )
      30             : {
      31          16 :     mpWindowImpl->mbMenuFloatingWindow= true;
      32          16 :     pMenu               = pMen;
      33          16 :     pActivePopup        = 0;
      34          16 :     nSaveFocusId        = 0;
      35          16 :     bInExecute          = false;
      36          16 :     bScrollMenu         = false;
      37          16 :     nHighlightedItem    = ITEMPOS_INVALID;
      38          16 :     nMBDownPos          = ITEMPOS_INVALID;
      39          16 :     nPosInParent        = ITEMPOS_INVALID;
      40          16 :     nScrollerHeight     = 0;
      41          16 :     nBorder             = EXTRASPACEY;
      42          16 :     nFirstEntry         = 0;
      43          16 :     bScrollUp           = false;
      44          16 :     bScrollDown         = false;
      45          16 :     bIgnoreFirstMove    = true;
      46          16 :     bKeyInput           = false;
      47             : 
      48          16 :     EnableSaveBackground();
      49          16 :     ImplInitMenuWindow( this, true, false );
      50             : 
      51          16 :     SetPopupModeEndHdl( LINK( this, MenuFloatingWindow, PopupEnd ) );
      52             : 
      53          16 :     aHighlightChangedTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, HighlightChanged ) );
      54          16 :     aHighlightChangedTimer.SetTimeout( GetSettings().GetMouseSettings().GetMenuDelay() );
      55          16 :     aSubmenuCloseTimer.SetTimeout( GetSettings().GetMouseSettings().GetMenuDelay() );
      56          16 :     aSubmenuCloseTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, SubmenuClose ) );
      57          16 :     aScrollTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, AutoScroll ) );
      58             : 
      59          16 :     AddEventListener( LINK( this, MenuFloatingWindow, ShowHideListener ) );
      60          16 : }
      61             : 
      62          32 : void MenuFloatingWindow::doShutdown()
      63             : {
      64          32 :     if( pMenu )
      65             :     {
      66             :         // #105373# notify toolkit that highlight was removed
      67             :         // otherwise the entry will not be read when the menu is opened again
      68          16 :         if( nHighlightedItem != ITEMPOS_INVALID )
      69           0 :             pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
      70          16 :         if (!bKeyInput && pMenu && pMenu->pStartedFrom && !pMenu->pStartedFrom->IsMenuBar())
      71             :         {
      72             :             // #102461# remove highlight in parent
      73             :             MenuItemData* pData;
      74           0 :             size_t i, nCount = pMenu->pStartedFrom->pItemList->size();
      75           0 :             for(i = 0; i < nCount; i++)
      76             :             {
      77           0 :                 pData = pMenu->pStartedFrom->pItemList->GetDataFromPos( i );
      78           0 :                 if( pData && ( pData->pSubMenu == pMenu ) )
      79           0 :                     break;
      80             :             }
      81           0 :             if( i < nCount )
      82             :             {
      83           0 :                 MenuFloatingWindow* pPWin = static_cast<MenuFloatingWindow*>(pMenu->pStartedFrom->ImplGetWindow());
      84           0 :                 if( pPWin )
      85           0 :                     pPWin->HighlightItem( i, false );
      86             :             }
      87             :         }
      88             : 
      89             :         // free the reference to the accessible component
      90          16 :         SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >() );
      91             : 
      92          16 :         aHighlightChangedTimer.Stop();
      93             : 
      94             :         // #95056# invalidate screen area covered by system window
      95             :         // so this can be taken into account if the commandhandler performs a scroll operation
      96          16 :         if( GetParent() )
      97             :         {
      98          16 :             Rectangle aInvRect( GetWindowExtentsRelative( GetParent() ) );
      99          16 :             GetParent()->Invalidate( aInvRect );
     100             :         }
     101          16 :         pMenu = NULL;
     102          16 :         RemoveEventListener( LINK( this, MenuFloatingWindow, ShowHideListener ) );
     103             :     }
     104          32 : }
     105             : 
     106          48 : MenuFloatingWindow::~MenuFloatingWindow()
     107             : {
     108          16 :     doShutdown();
     109          32 : }
     110             : 
     111          16 : void MenuFloatingWindow::Resize()
     112             : {
     113          16 :     InitMenuClipRegion();
     114          16 : }
     115             : 
     116          16 : long MenuFloatingWindow::ImplGetStartY() const
     117             : {
     118          16 :     long nY = 0;
     119          16 :     if( pMenu )
     120             :     {
     121          16 :         for ( sal_uInt16 n = 0; n < nFirstEntry; n++ )
     122           0 :             nY += pMenu->GetItemList()->GetDataFromPos( n )->aSz.Height();
     123             :     }
     124          16 :     return -nY;
     125             : }
     126             : 
     127           0 : vcl::Region MenuFloatingWindow::ImplCalcClipRegion( bool bIncludeLogo ) const
     128             : {
     129           0 :     Size aOutSz = GetOutputSizePixel();
     130           0 :     Point aPos;
     131           0 :     Rectangle aRect( aPos, aOutSz );
     132           0 :     aRect.Top() += nScrollerHeight;
     133           0 :     aRect.Bottom() -= nScrollerHeight;
     134             : 
     135           0 :     if ( pMenu && pMenu->pLogo && !bIncludeLogo )
     136           0 :         aRect.Left() += pMenu->pLogo->aBitmap.GetSizePixel().Width();
     137             : 
     138           0 :     vcl::Region aRegion(aRect);
     139           0 :     if ( pMenu && pMenu->pLogo && bIncludeLogo && nScrollerHeight )
     140           0 :         aRegion.Union( Rectangle( Point(), Size( pMenu->pLogo->aBitmap.GetSizePixel().Width(), aOutSz.Height() ) ) );
     141             : 
     142           0 :     return aRegion;
     143             : }
     144             : 
     145          16 : void MenuFloatingWindow::InitMenuClipRegion()
     146             : {
     147          16 :     if ( IsScrollMenu() )
     148             :     {
     149           0 :         SetClipRegion( ImplCalcClipRegion() );
     150             :     }
     151             :     else
     152             :     {
     153          16 :         SetClipRegion();
     154             :     }
     155          16 : }
     156             : 
     157           0 : void MenuFloatingWindow::ImplHighlightItem( const MouseEvent& rMEvt, bool bMBDown )
     158             : {
     159           0 :     if( ! pMenu )
     160           0 :         return;
     161             : 
     162           0 :     long nY = nScrollerHeight + ImplGetSVData()->maNWFData.mnMenuFormatBorderY;
     163           0 :     long nMouseY = rMEvt.GetPosPixel().Y();
     164           0 :     Size aOutSz = GetOutputSizePixel();
     165           0 :     if ( ( nMouseY >= nY ) && ( nMouseY < ( aOutSz.Height() - nY ) ) )
     166             :     {
     167           0 :         bool bHighlighted = false;
     168           0 :         size_t nCount = pMenu->pItemList->size();
     169           0 :         nY += ImplGetStartY();  // ggf. gescrollt.
     170           0 :         for ( size_t n = 0; !bHighlighted && ( n < nCount ); n++ )
     171             :         {
     172           0 :             if ( pMenu->ImplIsVisible( n ) )
     173             :             {
     174           0 :                 MenuItemData* pItemData = pMenu->pItemList->GetDataFromPos( n );
     175           0 :                 long nOldY = nY;
     176           0 :                 nY += pItemData->aSz.Height();
     177           0 :                 if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) && pMenu->ImplIsSelectable( n ) )
     178             :                 {
     179           0 :                     bool bPopupArea = true;
     180           0 :                     if ( pItemData->nBits & MenuItemBits::POPUPSELECT )
     181             :                     {
     182             :                         // only when clicked over the arrow...
     183           0 :                         Size aSz = GetOutputSizePixel();
     184           0 :                         long nFontHeight = GetTextHeight();
     185           0 :                         bPopupArea = ( rMEvt.GetPosPixel().X() >= ( aSz.Width() - nFontHeight - nFontHeight/4 ) );
     186             :                     }
     187             : 
     188           0 :                     if ( bMBDown )
     189             :                     {
     190           0 :                         if ( n != nHighlightedItem )
     191             :                         {
     192           0 :                             ChangeHighlightItem( (sal_uInt16)n, false );
     193             :                         }
     194             : 
     195           0 :                         bool bAllowNewPopup = true;
     196           0 :                         if ( pActivePopup )
     197             :                         {
     198           0 :                             MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
     199           0 :                             bAllowNewPopup = pData && ( pData->pSubMenu != pActivePopup );
     200           0 :                             if ( bAllowNewPopup )
     201           0 :                                 KillActivePopup();
     202             :                         }
     203             : 
     204           0 :                         if ( bPopupArea && bAllowNewPopup )
     205             :                         {
     206           0 :                             HighlightChanged( NULL );
     207             :                         }
     208             :                     }
     209             :                     else
     210             :                     {
     211           0 :                         if ( n != nHighlightedItem )
     212             :                         {
     213           0 :                             ChangeHighlightItem( (sal_uInt16)n, true );
     214             :                         }
     215           0 :                         else if ( pItemData->nBits & MenuItemBits::POPUPSELECT )
     216             :                         {
     217           0 :                             if ( bPopupArea && ( pActivePopup != pItemData->pSubMenu ) )
     218           0 :                                 HighlightChanged( NULL );
     219             :                         }
     220             :                     }
     221           0 :                     bHighlighted = true;
     222             :                 }
     223             :             }
     224             :         }
     225           0 :         if ( !bHighlighted )
     226           0 :             ChangeHighlightItem( ITEMPOS_INVALID, true );
     227             :     }
     228             :     else
     229             :     {
     230           0 :         ImplScroll( rMEvt.GetPosPixel() );
     231           0 :         ChangeHighlightItem( ITEMPOS_INVALID, true );
     232             :     }
     233             : }
     234             : 
     235           0 : IMPL_LINK_NOARG(MenuFloatingWindow, PopupEnd)
     236             : {
     237             :     // "this" will be deleted before the end of this method!
     238           0 :     Menu* pM = pMenu;
     239           0 :     if ( bInExecute )
     240             :     {
     241           0 :         if ( pActivePopup )
     242             :         {
     243             :             //DBG_ASSERT( !pActivePopup->ImplGetWindow(), "PopupEnd, obwohl pActivePopup MIT Window!" );
     244           0 :             KillActivePopup(); // should be ok to just remove it
     245             :             //pActivePopup->bCanceled = true;
     246             :         }
     247           0 :         bInExecute = false;
     248           0 :         pMenu->bInCallback = true;
     249           0 :         pMenu->Deactivate();
     250           0 :         pMenu->bInCallback = false;
     251             :     }
     252             :     else
     253             :     {
     254           0 :         if (pMenu && pMenu->pStartedFrom)
     255           0 :             pMenu->pStartedFrom->ClosePopup(pMenu);
     256             :     }
     257             : 
     258           0 :     if ( pM )
     259           0 :         pM->pStartedFrom = 0;
     260             : 
     261           0 :     return 0;
     262             : }
     263             : 
     264           0 : IMPL_LINK_NOARG(MenuFloatingWindow, AutoScroll)
     265             : {
     266           0 :     ImplScroll( GetPointerPosPixel() );
     267           0 :     return 1;
     268             : }
     269             : 
     270           0 : IMPL_LINK( MenuFloatingWindow, HighlightChanged, Timer*, pTimer )
     271             : {
     272           0 :     if( ! pMenu )
     273           0 :         return 0;
     274             : 
     275           0 :     MenuItemData* pItemData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
     276           0 :     if ( pItemData )
     277             :     {
     278           0 :         if ( pActivePopup && ( pActivePopup != pItemData->pSubMenu ) )
     279             :         {
     280           0 :             sal_uLong nOldFlags = GetPopupModeFlags();
     281           0 :             SetPopupModeFlags( GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE );
     282           0 :             KillActivePopup();
     283           0 :             SetPopupModeFlags( nOldFlags );
     284             :         }
     285           0 :         if ( pItemData->bEnabled && pItemData->pSubMenu && pItemData->pSubMenu->GetItemCount() && ( pItemData->pSubMenu != pActivePopup ) )
     286             :         {
     287           0 :             pActivePopup = static_cast<PopupMenu*>(pItemData->pSubMenu);
     288           0 :             long nY = nScrollerHeight+ImplGetStartY();
     289           0 :             MenuItemData* pData = 0;
     290           0 :             for ( sal_uLong n = 0; n < nHighlightedItem; n++ )
     291             :             {
     292           0 :                 pData = pMenu->pItemList->GetDataFromPos( n );
     293           0 :                 nY += pData->aSz.Height();
     294             :             }
     295           0 :             pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
     296           0 :             Size MySize = GetOutputSizePixel();
     297           0 :             Point aItemTopLeft( 0, nY );
     298           0 :             Point aItemBottomRight( aItemTopLeft );
     299           0 :             aItemBottomRight.X() += MySize.Width();
     300           0 :             aItemBottomRight.Y() += pData->aSz.Height();
     301             : 
     302             :             // shift the popups a little
     303           0 :             aItemTopLeft.X() += 2;
     304           0 :             aItemBottomRight.X() -= 2;
     305           0 :             if ( nHighlightedItem )
     306           0 :                 aItemTopLeft.Y() -= 2;
     307             :             else
     308             :             {
     309             :                 sal_Int32 nL, nT, nR, nB;
     310           0 :                 GetBorder( nL, nT, nR, nB );
     311           0 :                 aItemTopLeft.Y() -= nT;
     312             :             }
     313             : 
     314             :             // pTest: crash due to Reschedule() in call of Activate()
     315             :             // Also it is prevented that submenus are displayed which
     316             :             // were for long in Activate Rescheduled and which should not be
     317             :             // displayed now.
     318           0 :             Menu* pTest = pActivePopup;
     319           0 :             sal_uLong nOldFlags = GetPopupModeFlags();
     320           0 :             SetPopupModeFlags( GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE );
     321           0 :             sal_uInt16 nRet = pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_RIGHT, pMenu, pTimer ? false : true  );
     322           0 :             SetPopupModeFlags( nOldFlags );
     323             : 
     324             :             // nRet != 0, wenn es waerend Activate() abgeschossen wurde...
     325           0 :             if ( !nRet && ( pActivePopup == pTest ) && pActivePopup->ImplGetWindow() )
     326           0 :                 pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this );
     327             :         }
     328             :     }
     329             : 
     330           0 :     return 0;
     331             : }
     332             : 
     333           0 : IMPL_LINK_NOARG(MenuFloatingWindow, SubmenuClose)
     334             : {
     335           0 :     if( pMenu && pMenu->pStartedFrom )
     336             :     {
     337           0 :         MenuFloatingWindow* pWin = static_cast<MenuFloatingWindow*>(pMenu->pStartedFrom->GetWindow());
     338           0 :         if( pWin )
     339           0 :             pWin->KillActivePopup();
     340             :     }
     341           0 :     return 0;
     342             : }
     343             : 
     344         192 : IMPL_LINK( MenuFloatingWindow, ShowHideListener, VclWindowEvent*, pEvent )
     345             : {
     346          96 :     if( ! pMenu )
     347           0 :         return 0;
     348             : 
     349          96 :     if( pEvent->GetId() == VCLEVENT_WINDOW_SHOW )
     350          32 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_SHOW, ITEMPOS_INVALID );
     351          64 :     else if( pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
     352          32 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_HIDE, ITEMPOS_INVALID );
     353          96 :     return 0;
     354             : }
     355             : 
     356           0 : void MenuFloatingWindow::EnableScrollMenu( bool b )
     357             : {
     358           0 :     bScrollMenu = b;
     359           0 :     nScrollerHeight = b ? (sal_uInt16) GetSettings().GetStyleSettings().GetScrollBarSize() /2 : 0;
     360           0 :     bScrollDown = true;
     361           0 :     InitMenuClipRegion();
     362           0 : }
     363             : 
     364           0 : void MenuFloatingWindow::Execute()
     365             : {
     366           0 :     ImplSVData* pSVData = ImplGetSVData();
     367             : 
     368           0 :     pSVData->maAppData.mpActivePopupMenu = static_cast<PopupMenu*>(pMenu);
     369             : 
     370           0 :     bInExecute = true;
     371             : //  bCallingSelect = false;
     372             : 
     373           0 :     while ( bInExecute )
     374           0 :         Application::Yield();
     375             : 
     376           0 :     pSVData->maAppData.mpActivePopupMenu = NULL;
     377           0 : }
     378             : 
     379          16 : void MenuFloatingWindow::StopExecute( sal_uLong nFocusId )
     380             : {
     381             :     // restore focus
     382             :     // (could have been restored in Select)
     383          16 :     if ( nSaveFocusId )
     384             :     {
     385           0 :         Window::EndSaveFocus( nFocusId, false );
     386           0 :         nFocusId = nSaveFocusId;
     387           0 :         if ( nFocusId )
     388             :         {
     389           0 :             nSaveFocusId = 0;
     390           0 :             ImplGetSVData()->maWinData.mbNoDeactivate = false;
     391             :         }
     392             :     }
     393          16 :     ImplEndPopupMode( 0, nFocusId );
     394             : 
     395          16 :     aHighlightChangedTimer.Stop();
     396          16 :     bInExecute = false;
     397          16 :     if ( pActivePopup )
     398             :     {
     399           0 :         KillActivePopup();
     400             :     }
     401             :     // notify parent, needed for accessibility
     402          16 :     if( pMenu && pMenu->pStartedFrom )
     403          16 :         pMenu->pStartedFrom->ImplCallEventListeners( VCLEVENT_MENU_SUBMENUDEACTIVATE, nPosInParent );
     404          16 : }
     405             : 
     406           0 : void MenuFloatingWindow::KillActivePopup( PopupMenu* pThisOnly )
     407             : {
     408           0 :     if ( pActivePopup && ( !pThisOnly || ( pThisOnly == pActivePopup ) ) )
     409             :     {
     410           0 :         if( pActivePopup->pWindow != NULL )
     411           0 :             if( static_cast<FloatingWindow *>(pActivePopup->pWindow)->IsInCleanUp() )
     412           0 :                 return; // kill it later
     413           0 :         if ( pActivePopup->bInCallback )
     414           0 :             pActivePopup->bCanceled = true;
     415             : 
     416             :         // For all actions pActivePopup = 0, if e.g.
     417             :         // PopupModeEndHdl the popups to destroy were called synchronous
     418           0 :         PopupMenu* pPopup = pActivePopup;
     419           0 :         pActivePopup = NULL;
     420           0 :         pPopup->bInCallback = true;
     421           0 :         pPopup->Deactivate();
     422           0 :         pPopup->bInCallback = false;
     423           0 :         if ( pPopup->ImplGetWindow() )
     424             :         {
     425           0 :             pPopup->ImplGetFloatingWindow()->StopExecute();
     426           0 :             pPopup->ImplGetFloatingWindow()->doShutdown();
     427           0 :             pPopup->pWindow->doLazyDelete();
     428           0 :             pPopup->pWindow = NULL;
     429             : 
     430           0 :             Update();
     431             :         }
     432             :     }
     433             : }
     434             : 
     435           0 : void MenuFloatingWindow::EndExecute()
     436             : {
     437           0 :     Menu* pStart = pMenu ? pMenu->ImplGetStartMenu() : NULL;
     438           0 :     sal_uLong nFocusId = 0;
     439           0 :     if (pStart)
     440           0 :         nFocusId = pStart->DeactivateMenuBar(nFocusId);
     441             : 
     442             :     // if started elsewhere, cleanup there as well
     443           0 :     MenuFloatingWindow* pCleanUpFrom = this;
     444           0 :     MenuFloatingWindow* pWin = this;
     445           0 :     while (pWin && !pWin->bInExecute &&
     446           0 :         pWin->pMenu->pStartedFrom && !pWin->pMenu->pStartedFrom->IsMenuBar())
     447             :     {
     448           0 :         pWin = static_cast<PopupMenu*>(pWin->pMenu->pStartedFrom)->ImplGetFloatingWindow();
     449             :     }
     450           0 :     if ( pWin )
     451           0 :         pCleanUpFrom = pWin;
     452             : 
     453             :     // this window will be destroyed => store date locally...
     454           0 :     Menu* pM = pMenu;
     455           0 :     sal_uInt16 nItem = nHighlightedItem;
     456             : 
     457           0 :     pCleanUpFrom->StopExecute( nFocusId );
     458             : 
     459           0 :     if ( nItem != ITEMPOS_INVALID && pM )
     460             :     {
     461           0 :         MenuItemData* pItemData = pM->GetItemList()->GetDataFromPos( nItem );
     462           0 :         if ( pItemData && !pItemData->bIsTemporary )
     463             :         {
     464           0 :             pM->nSelectedId = pItemData->nId;
     465           0 :             if ( pStart )
     466           0 :                 pStart->nSelectedId = pItemData->nId;
     467             : 
     468           0 :             pM->ImplSelect();
     469             :         }
     470             :     }
     471           0 : }
     472             : 
     473           0 : void MenuFloatingWindow::EndExecute( sal_uInt16 nId )
     474             : {
     475             :     size_t nPos;
     476           0 :     if ( pMenu && pMenu->GetItemList()->GetData( nId, nPos ) )
     477           0 :         nHighlightedItem = nPos;
     478             :     else
     479           0 :         nHighlightedItem = ITEMPOS_INVALID;
     480             : 
     481           0 :     EndExecute();
     482           0 : }
     483             : 
     484           0 : void MenuFloatingWindow::MouseButtonDown( const MouseEvent& rMEvt )
     485             : {
     486             :     // TH creates a ToTop on this window, but the active popup
     487             :     // should stay on top...
     488             :     // due to focus change this would close all menus -> don't do it (#94123)
     489             :     //if ( pActivePopup && pActivePopup->ImplGetWindow() && !pActivePopup->ImplGetFloatingWindow()->pActivePopup )
     490             :     //    pActivePopup->ImplGetFloatingWindow()->ToTop( TOTOP_NOGRABFOCUS );
     491             : 
     492           0 :     ImplHighlightItem( rMEvt, true );
     493             : 
     494           0 :     nMBDownPos = nHighlightedItem;
     495           0 : }
     496             : 
     497           0 : void MenuFloatingWindow::MouseButtonUp( const MouseEvent& rMEvt )
     498             : {
     499           0 :     MenuItemData* pData = pMenu ? pMenu->GetItemList()->GetDataFromPos( nHighlightedItem ) : NULL;
     500             :     // nMBDownPos store in local variable and reset immediately,
     501             :     // as it will be too late after EndExecute
     502           0 :     sal_uInt16 _nMBDownPos = nMBDownPos;
     503           0 :     nMBDownPos = ITEMPOS_INVALID;
     504           0 :     if ( pData && pData->bEnabled && ( pData->eType != MenuItemType::SEPARATOR ) )
     505             :     {
     506           0 :         if ( !pData->pSubMenu )
     507             :         {
     508           0 :             EndExecute();
     509             :         }
     510           0 :         else if ( ( pData->nBits & MenuItemBits::POPUPSELECT ) && ( nHighlightedItem == _nMBDownPos ) && ( rMEvt.GetClicks() == 2 ) )
     511             :         {
     512             :             // not when clicked over the arrow...
     513           0 :             Size aSz = GetOutputSizePixel();
     514           0 :             long nFontHeight = GetTextHeight();
     515           0 :             if ( rMEvt.GetPosPixel().X() < ( aSz.Width() - nFontHeight - nFontHeight/4 ) )
     516           0 :                 EndExecute();
     517             :         }
     518             :     }
     519             : 
     520           0 : }
     521             : 
     522           0 : void MenuFloatingWindow::MouseMove( const MouseEvent& rMEvt )
     523             : {
     524           0 :     if ( !IsVisible() || rMEvt.IsSynthetic() || rMEvt.IsEnterWindow() )
     525           0 :         return;
     526             : 
     527           0 :     if ( rMEvt.IsLeaveWindow() )
     528             :     {
     529             :         // #102461# do not remove highlight if a popup menu is open at this position
     530           0 :         MenuItemData* pData = pMenu ? pMenu->pItemList->GetDataFromPos( nHighlightedItem ) : NULL;
     531             :         // close popup with some delayed if we leave somewhere else
     532           0 :         if( pActivePopup && pData && pData->pSubMenu != pActivePopup )
     533           0 :             pActivePopup->ImplGetFloatingWindow()->aSubmenuCloseTimer.Start();
     534             : 
     535           0 :         if( !pActivePopup || (pData && pData->pSubMenu != pActivePopup ) )
     536           0 :             ChangeHighlightItem( ITEMPOS_INVALID, false );
     537             : 
     538           0 :         if ( IsScrollMenu() )
     539           0 :             ImplScroll( rMEvt.GetPosPixel() );
     540             :     }
     541             :     else
     542             :     {
     543           0 :         aSubmenuCloseTimer.Stop();
     544           0 :         if( bIgnoreFirstMove )
     545           0 :             bIgnoreFirstMove = false;
     546             :         else
     547           0 :             ImplHighlightItem( rMEvt, false );
     548             :     }
     549             : }
     550             : 
     551           0 : void MenuFloatingWindow::ImplScroll( bool bUp )
     552             : {
     553           0 :     KillActivePopup();
     554           0 :     Update();
     555             : 
     556           0 :     if( ! pMenu )
     557           0 :         return;
     558             : 
     559           0 :     HighlightItem( nHighlightedItem, false );
     560             : 
     561           0 :     pMenu->ImplKillLayoutData();
     562             : 
     563           0 :     if ( bScrollUp && bUp )
     564             :     {
     565           0 :         nFirstEntry = pMenu->ImplGetPrevVisible( nFirstEntry );
     566             :         DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" );
     567             : 
     568           0 :         long nScrollEntryHeight = pMenu->GetItemList()->GetDataFromPos( nFirstEntry )->aSz.Height();
     569             : 
     570           0 :         if ( !bScrollDown )
     571             :         {
     572           0 :             bScrollDown = true;
     573           0 :             ImplDrawScroller( false );
     574             :         }
     575             : 
     576           0 :         if ( pMenu->ImplGetPrevVisible( nFirstEntry ) == ITEMPOS_INVALID )
     577             :         {
     578           0 :             bScrollUp = false;
     579           0 :             ImplDrawScroller( true );
     580             :         }
     581             : 
     582           0 :         Scroll( 0, nScrollEntryHeight, ImplCalcClipRegion( false ).GetBoundRect(), SCROLL_CLIP );
     583             :     }
     584           0 :     else if ( bScrollDown && !bUp )
     585             :     {
     586           0 :         long nScrollEntryHeight = pMenu->GetItemList()->GetDataFromPos( nFirstEntry )->aSz.Height();
     587             : 
     588           0 :         nFirstEntry = pMenu->ImplGetNextVisible( nFirstEntry );
     589             :         DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" );
     590             : 
     591           0 :         if ( !bScrollUp )
     592             :         {
     593           0 :             bScrollUp = true;
     594           0 :             ImplDrawScroller( true );
     595             :         }
     596             : 
     597           0 :         long nHeight = GetOutputSizePixel().Height();
     598             :         sal_uInt16 nLastVisible;
     599           0 :         static_cast<PopupMenu*>(pMenu)->ImplCalcVisEntries( nHeight, nFirstEntry, &nLastVisible );
     600           0 :         if ( pMenu->ImplGetNextVisible( nLastVisible ) == ITEMPOS_INVALID )
     601             :         {
     602           0 :             bScrollDown = false;
     603           0 :             ImplDrawScroller( false );
     604             :         }
     605             : 
     606           0 :         Scroll( 0, -nScrollEntryHeight, ImplCalcClipRegion( false ).GetBoundRect(), SCROLL_CLIP );
     607             :     }
     608             : 
     609           0 :     HighlightItem( nHighlightedItem, true );
     610             : }
     611             : 
     612           0 : void MenuFloatingWindow::ImplScroll( const Point& rMousePos )
     613             : {
     614           0 :     Size aOutSz = GetOutputSizePixel();
     615             : 
     616           0 :     long nY = nScrollerHeight;
     617           0 :     long nMouseY = rMousePos.Y();
     618           0 :     long nDelta = 0;
     619             : 
     620           0 :     if ( bScrollUp && ( nMouseY < nY ) )
     621             :     {
     622           0 :         ImplScroll( true );
     623           0 :         nDelta = nY - nMouseY;
     624             :     }
     625           0 :     else if ( bScrollDown && ( nMouseY > ( aOutSz.Height() - nY ) ) )
     626             :     {
     627           0 :         ImplScroll( false );
     628           0 :         nDelta = nMouseY - ( aOutSz.Height() - nY );
     629             :     }
     630             : 
     631           0 :     if ( nDelta )
     632             :     {
     633           0 :         aScrollTimer.Stop();    // if scrolled through MouseMove.
     634             :         long nTimeout;
     635           0 :         if ( nDelta < 3 )
     636           0 :             nTimeout = 200;
     637           0 :         else if ( nDelta < 5 )
     638           0 :             nTimeout = 100;
     639           0 :         else if ( nDelta < 8 )
     640           0 :             nTimeout = 70;
     641           0 :         else if ( nDelta < 12 )
     642           0 :             nTimeout = 40;
     643             :         else
     644           0 :             nTimeout = 20;
     645           0 :         aScrollTimer.SetTimeout( nTimeout );
     646           0 :         aScrollTimer.Start();
     647             :     }
     648           0 : }
     649           0 : void MenuFloatingWindow::ChangeHighlightItem( sal_uInt16 n, bool bStartPopupTimer )
     650             : {
     651             :     // #57934# ggf. immediately close the active, as TH's backgroundstorage works.
     652             :     // #65750# we prefer to refrain from the background storage of small lines.
     653             :     //         otherwise the menus are difficult to operate.
     654             :     //  MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
     655             :     //  if ( pActivePopup && pNextData && ( pActivePopup != pNextData->pSubMenu ) )
     656             :     //      KillActivePopup();
     657             : 
     658           0 :     aSubmenuCloseTimer.Stop();
     659           0 :     if( ! pMenu )
     660           0 :         return;
     661             : 
     662           0 :     if ( nHighlightedItem != ITEMPOS_INVALID )
     663             :     {
     664           0 :         HighlightItem( nHighlightedItem, false );
     665           0 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
     666             :     }
     667             : 
     668           0 :     nHighlightedItem = (sal_uInt16)n;
     669             :     DBG_ASSERT( pMenu->ImplIsVisible( nHighlightedItem ) || nHighlightedItem == ITEMPOS_INVALID, "ChangeHighlightItem: Not visible!" );
     670           0 :     if( nHighlightedItem != ITEMPOS_INVALID )
     671             :     {
     672           0 :         if (pMenu->pStartedFrom && !pMenu->pStartedFrom->IsMenuBar())
     673             :         {
     674             :             // #102461# make sure parent entry is highlighted as well
     675             :             MenuItemData* pData;
     676           0 :             size_t i, nCount = pMenu->pStartedFrom->pItemList->size();
     677           0 :             for(i = 0; i < nCount; i++)
     678             :             {
     679           0 :                 pData = pMenu->pStartedFrom->pItemList->GetDataFromPos( i );
     680           0 :                 if( pData && ( pData->pSubMenu == pMenu ) )
     681           0 :                     break;
     682             :             }
     683           0 :             if( i < nCount )
     684             :             {
     685           0 :                 MenuFloatingWindow* pPWin = static_cast<MenuFloatingWindow*>(pMenu->pStartedFrom->ImplGetWindow());
     686           0 :                 if( pPWin && pPWin->nHighlightedItem != i )
     687             :                 {
     688           0 :                     pPWin->HighlightItem( i, true );
     689           0 :                     pPWin->nHighlightedItem = i;
     690             :                 }
     691             :             }
     692             :         }
     693           0 :         HighlightItem( nHighlightedItem, true );
     694           0 :         pMenu->ImplCallHighlight( nHighlightedItem );
     695             :     }
     696             :     else
     697           0 :         pMenu->nSelectedId = 0;
     698             : 
     699           0 :     if ( bStartPopupTimer )
     700             :     {
     701             :         // #102438# Menu items are not selectable
     702             :         // If a menu item is selected by an AT-tool via the XAccessibleAction, XAccessibleValue
     703             :         // or XAccessibleSelection interface, and the parent popup menus are not executed yet,
     704             :         // the parent popup menus must be executed SYNCHRONOUSLY, before the menu item is selected.
     705           0 :         if ( GetSettings().GetMouseSettings().GetMenuDelay() )
     706           0 :             aHighlightChangedTimer.Start();
     707             :         else
     708           0 :             HighlightChanged( &aHighlightChangedTimer );
     709             :     }
     710             : }
     711             : 
     712           0 : void MenuFloatingWindow::HighlightItem( sal_uInt16 nPos, bool bHighlight )
     713             : {
     714           0 :     if( ! pMenu )
     715           0 :         return;
     716             : 
     717           0 :     Size    aSz = GetOutputSizePixel();
     718           0 :     long    nStartY = ImplGetStartY();
     719           0 :     long    nY = nScrollerHeight + nStartY + ImplGetSVData()->maNWFData.mnMenuFormatBorderY;
     720           0 :     long    nX = 0;
     721             : 
     722           0 :     if ( pMenu->pLogo )
     723           0 :         nX = pMenu->pLogo->aBitmap.GetSizePixel().Width();
     724             : 
     725           0 :     int nOuterSpaceX = ImplGetSVData()->maNWFData.mnMenuFormatBorderX;
     726             : 
     727           0 :     size_t nCount = pMenu->pItemList->size();
     728           0 :     for ( size_t n = 0; n < nCount; n++ )
     729             :     {
     730           0 :         MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
     731           0 :         if ( n == nPos )
     732             :         {
     733             :             DBG_ASSERT( pMenu->ImplIsVisible( n ), "Highlight: Item not visible!" );
     734           0 :             if ( pData->eType != MenuItemType::SEPARATOR )
     735             :             {
     736           0 :                 bool bRestoreLineColor = false;
     737           0 :                 Color oldLineColor;
     738           0 :                 bool bDrawItemRect = true;
     739             : 
     740           0 :                 Rectangle aItemRect( Point( nX+nOuterSpaceX, nY ), Size( aSz.Width()-2*nOuterSpaceX, pData->aSz.Height() ) );
     741           0 :                 if ( pData->nBits & MenuItemBits::POPUPSELECT )
     742             :                 {
     743           0 :                     long nFontHeight = GetTextHeight();
     744           0 :                     aItemRect.Right() -= nFontHeight + nFontHeight/4;
     745             :                 }
     746             : 
     747           0 :                 if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
     748             :                 {
     749           0 :                     Size aPxSize( GetOutputSizePixel() );
     750           0 :                     Push( PushFlags::CLIPREGION );
     751           0 :                     IntersectClipRegion( Rectangle( Point( nX, nY ), Size( aSz.Width(), pData->aSz.Height() ) ) );
     752           0 :                     Rectangle aCtrlRect( Point( nX, 0 ), Size( aPxSize.Width()-nX, aPxSize.Height() ) );
     753           0 :                     MenupopupValue aVal( pMenu->nTextPos-GUTTERBORDER, aItemRect );
     754             :                     DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
     755             :                                        aCtrlRect,
     756             :                                        CTRL_STATE_ENABLED,
     757             :                                        aVal,
     758           0 :                                        OUString() );
     759           0 :                     if( bHighlight &&
     760           0 :                         IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) )
     761             :                     {
     762           0 :                         bDrawItemRect = false;
     763           0 :                         if( !DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM,
     764             :                                                         aItemRect,
     765             :                                                         CTRL_STATE_SELECTED | ( pData->bEnabled? CTRL_STATE_ENABLED: 0 ),
     766             :                                                         aVal,
     767           0 :                                                         OUString() ) )
     768             :                         {
     769           0 :                             bDrawItemRect = bHighlight;
     770             :                         }
     771             :                     }
     772             :                     else
     773           0 :                         bDrawItemRect = bHighlight;
     774           0 :                     Pop();
     775             :                 }
     776           0 :                 if( bDrawItemRect )
     777             :                 {
     778           0 :                     if ( bHighlight )
     779             :                     {
     780           0 :                         if( pData->bEnabled )
     781           0 :                             SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
     782             :                         else
     783             :                         {
     784           0 :                             SetFillColor();
     785           0 :                             oldLineColor = GetLineColor();
     786           0 :                             SetLineColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
     787           0 :                             bRestoreLineColor = true;
     788             :                         }
     789             :                     }
     790             :                     else
     791           0 :                         SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
     792             : 
     793           0 :                     DrawRect( aItemRect );
     794             :                 }
     795           0 :                 pMenu->ImplPaint( this, nScrollerHeight, nStartY, pData, bHighlight );
     796           0 :                 if( bRestoreLineColor )
     797           0 :                     SetLineColor( oldLineColor );
     798             :             }
     799           0 :             return;
     800             :         }
     801             : 
     802           0 :         nY += pData->aSz.Height();
     803             :     }
     804             : }
     805             : 
     806           0 : Rectangle MenuFloatingWindow::ImplGetItemRect( sal_uInt16 nPos )
     807             : {
     808           0 :     if( ! pMenu )
     809           0 :         return Rectangle();
     810             : 
     811           0 :     Rectangle aRect;
     812           0 :     Size    aSz = GetOutputSizePixel();
     813           0 :     long    nStartY = ImplGetStartY();
     814           0 :     long    nY = nScrollerHeight+nStartY;
     815           0 :     long    nX = 0;
     816             : 
     817           0 :     if ( pMenu->pLogo )
     818           0 :         nX = pMenu->pLogo->aBitmap.GetSizePixel().Width();
     819             : 
     820           0 :     size_t nCount = pMenu->pItemList->size();
     821           0 :     for ( size_t n = 0; n < nCount; n++ )
     822             :     {
     823           0 :         MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
     824           0 :         if ( n == nPos )
     825             :         {
     826             :             DBG_ASSERT( pMenu->ImplIsVisible( n ), "ImplGetItemRect: Item not visible!" );
     827           0 :             if ( pData->eType != MenuItemType::SEPARATOR )
     828             :             {
     829           0 :                 aRect = Rectangle( Point( nX, nY ), Size( aSz.Width(), pData->aSz.Height() ) );
     830           0 :                 if ( pData->nBits & MenuItemBits::POPUPSELECT )
     831             :                 {
     832           0 :                     long nFontHeight = GetTextHeight();
     833           0 :                     aRect.Right() -= nFontHeight + nFontHeight/4;
     834             :                 }
     835             :             }
     836           0 :             break;
     837             :         }
     838           0 :         nY += pData->aSz.Height();
     839             :     }
     840           0 :     return aRect;
     841             : }
     842             : 
     843           0 : void MenuFloatingWindow::ImplCursorUpDown( bool bUp, bool bHomeEnd )
     844             : {
     845           0 :     if( ! pMenu )
     846           0 :         return;
     847             : 
     848           0 :     const StyleSettings& rSettings = GetSettings().GetStyleSettings();
     849             : 
     850           0 :     sal_uInt16 n = nHighlightedItem;
     851           0 :     if ( n == ITEMPOS_INVALID )
     852             :     {
     853           0 :         if ( bUp )
     854           0 :             n = 0;
     855             :         else
     856           0 :             n = pMenu->GetItemCount()-1;
     857             :     }
     858             : 
     859           0 :     sal_uInt16 nLoop = n;
     860             : 
     861           0 :     if( bHomeEnd )
     862             :     {
     863             :         // absolute positioning
     864           0 :         if( bUp )
     865             :         {
     866           0 :             n = pMenu->GetItemCount();
     867           0 :             nLoop = n-1;
     868             :         }
     869             :         else
     870             :         {
     871           0 :             n = (sal_uInt16)-1;
     872           0 :             nLoop = n+1;
     873             :         }
     874             :     }
     875             : 
     876           0 :     do
     877             :     {
     878           0 :         if ( bUp )
     879             :         {
     880           0 :             if ( n )
     881           0 :                 n--;
     882             :             else
     883           0 :                 if ( !IsScrollMenu() || ( nHighlightedItem == ITEMPOS_INVALID ) )
     884           0 :                     n = pMenu->GetItemCount()-1;
     885             :                 else
     886           0 :                     break;
     887             :         }
     888             :         else
     889             :         {
     890           0 :             n++;
     891           0 :             if ( n >= pMenu->GetItemCount() )
     892             :             {
     893           0 :                 if ( !IsScrollMenu() || ( nHighlightedItem == ITEMPOS_INVALID ) )
     894           0 :                     n = 0;
     895             :                 else
     896           0 :                     break;
     897             :             }
     898             :         }
     899             : 
     900           0 :         MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n );
     901           0 :         if ( ( pData->bEnabled || !rSettings.GetSkipDisabledInMenus() )
     902           0 :               && ( pData->eType != MenuItemType::SEPARATOR ) && pMenu->ImplIsVisible( n ) && pMenu->ImplIsSelectable( n ) )
     903             :         {
     904             :             // Is selection in visible area?
     905           0 :             if ( IsScrollMenu() )
     906             :             {
     907           0 :                 ChangeHighlightItem( ITEMPOS_INVALID, false );
     908             : 
     909           0 :                 while ( n < nFirstEntry )
     910           0 :                     ImplScroll( true );
     911             : 
     912           0 :                 Size aOutSz = GetOutputSizePixel();
     913             :                 sal_uInt16 nLastVisible;
     914           0 :                 static_cast<PopupMenu*>(pMenu)->ImplCalcVisEntries( aOutSz.Height(), nFirstEntry, &nLastVisible );
     915           0 :                 while ( n > nLastVisible )
     916             :                 {
     917           0 :                     ImplScroll( false );
     918           0 :                     static_cast<PopupMenu*>(pMenu)->ImplCalcVisEntries( aOutSz.Height(), nFirstEntry, &nLastVisible );
     919             :                 }
     920             :             }
     921           0 :             ChangeHighlightItem( n, false );
     922           0 :             break;
     923             :         }
     924             :     } while ( n != nLoop );
     925             : }
     926             : 
     927           0 : void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent )
     928             : {
     929           0 :     ImplDelData aDelData;
     930           0 :     ImplAddDel( &aDelData );
     931             : 
     932           0 :     sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
     933           0 :     bKeyInput = true;
     934           0 :     switch ( nCode )
     935             :     {
     936             :         case KEY_UP:
     937             :         case KEY_DOWN:
     938             :         {
     939           0 :             ImplCursorUpDown( nCode == KEY_UP );
     940             :         }
     941           0 :         break;
     942             :         case KEY_END:
     943             :         case KEY_HOME:
     944             :         {
     945           0 :             ImplCursorUpDown( nCode == KEY_END, true );
     946             :         }
     947           0 :         break;
     948             :         case KEY_F6:
     949             :         case KEY_ESCAPE:
     950             :         {
     951             :             // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document
     952           0 :             if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() )
     953           0 :                 break;
     954           0 :             if( pMenu )
     955             :             {
     956           0 :                 if ( !pMenu->pStartedFrom )
     957             :                 {
     958           0 :                     StopExecute();
     959           0 :                     KillActivePopup();
     960             :                 }
     961           0 :                 else if (pMenu->pStartedFrom->IsMenuBar())
     962             :                 {
     963           0 :                     pMenu->pStartedFrom->MenuBarKeyInput(rKEvent);
     964             :                 }
     965             :                 else
     966             :                 {
     967           0 :                     StopExecute();
     968           0 :                     PopupMenu* pPopupMenu = static_cast<PopupMenu*>(pMenu->pStartedFrom);
     969           0 :                     MenuFloatingWindow* pFloat = pPopupMenu->ImplGetFloatingWindow();
     970           0 :                     pFloat->GrabFocus();
     971           0 :                     pFloat->KillActivePopup();
     972           0 :                     pPopupMenu->ImplCallHighlight(pFloat->nHighlightedItem);
     973             :                 }
     974             :             }
     975             :         }
     976           0 :         break;
     977             :         case KEY_LEFT:
     978             :         {
     979           0 :             if ( pMenu && pMenu->pStartedFrom )
     980             :             {
     981           0 :                 StopExecute();
     982           0 :                 if (pMenu->pStartedFrom->IsMenuBar())
     983             :                 {
     984           0 :                     pMenu->pStartedFrom->MenuBarKeyInput(rKEvent);
     985             :                 }
     986             :                 else
     987             :                 {
     988           0 :                     MenuFloatingWindow* pFloat = static_cast<PopupMenu*>(pMenu->pStartedFrom)->ImplGetFloatingWindow();
     989           0 :                     pFloat->GrabFocus();
     990           0 :                     pFloat->KillActivePopup();
     991           0 :                     sal_uInt16 highlightItem = pFloat->GetHighlightedItem();
     992           0 :                     pFloat->ChangeHighlightItem(highlightItem, false);
     993             :                 }
     994             :             }
     995             :         }
     996           0 :         break;
     997             :         case KEY_RIGHT:
     998             :         {
     999           0 :             if( pMenu )
    1000             :             {
    1001           0 :                 bool bDone = false;
    1002           0 :                 if ( nHighlightedItem != ITEMPOS_INVALID )
    1003             :                 {
    1004           0 :                     MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
    1005           0 :                     if ( pData && pData->pSubMenu )
    1006             :                     {
    1007           0 :                         HighlightChanged( 0 );
    1008           0 :                         bDone = true;
    1009             :                     }
    1010             :                 }
    1011           0 :                 if ( !bDone )
    1012             :                 {
    1013           0 :                     Menu* pStart = pMenu->ImplGetStartMenu();
    1014           0 :                     if (pStart && pStart->IsMenuBar())
    1015             :                     {
    1016             :                         // Forward...
    1017           0 :                         pStart->ImplGetWindow()->KeyInput( rKEvent );
    1018             :                     }
    1019             :                 }
    1020             :             }
    1021             :         }
    1022           0 :         break;
    1023             :         case KEY_RETURN:
    1024             :         {
    1025           0 :             if( pMenu )
    1026             :             {
    1027           0 :                 MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
    1028           0 :                 if ( pData && pData->bEnabled )
    1029             :                 {
    1030           0 :                     if ( pData->pSubMenu )
    1031           0 :                         HighlightChanged( 0 );
    1032             :                     else
    1033           0 :                         EndExecute();
    1034             :                 }
    1035             :                 else
    1036           0 :                     StopExecute();
    1037             :             }
    1038             :         }
    1039           0 :         break;
    1040             :         case KEY_MENU:
    1041             :         {
    1042           0 :             if( pMenu )
    1043             :             {
    1044           0 :                 Menu* pStart = pMenu->ImplGetStartMenu();
    1045           0 :                 if (pStart && pStart->IsMenuBar())
    1046             :                 {
    1047             :                     // Forward...
    1048           0 :                     pStart->ImplGetWindow()->KeyInput( rKEvent );
    1049             :                 }
    1050             :             }
    1051             :         }
    1052           0 :         break;
    1053             :         default:
    1054             :         {
    1055           0 :             sal_Unicode nCharCode = rKEvent.GetCharCode();
    1056           0 :             sal_uInt16 nPos = 0;
    1057           0 :             sal_uInt16 nDuplicates = 0;
    1058           0 :             MenuItemData* pData = (nCharCode && pMenu) ? pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nPos, nDuplicates, nHighlightedItem ) : NULL;
    1059           0 :             if ( pData )
    1060             :             {
    1061           0 :                 if ( pData->pSubMenu || nDuplicates > 1 )
    1062             :                 {
    1063           0 :                     ChangeHighlightItem( nPos, false );
    1064           0 :                     HighlightChanged( 0 );
    1065             :                 }
    1066             :                 else
    1067             :                 {
    1068           0 :                     nHighlightedItem = nPos;
    1069           0 :                     EndExecute();
    1070             :                 }
    1071             :             }
    1072             :             else
    1073           0 :                 FloatingWindow::KeyInput( rKEvent );
    1074             :         }
    1075             :     }
    1076             :     // #105474# check if menu window was not destroyed
    1077           0 :     if ( !aDelData.IsDead() )
    1078             :     {
    1079           0 :         ImplRemoveDel( &aDelData );
    1080           0 :         bKeyInput = false;
    1081           0 :     }
    1082           0 : }
    1083             : 
    1084          14 : void MenuFloatingWindow::Paint( const Rectangle& )
    1085             : {
    1086          14 :     if( ! pMenu )
    1087          14 :         return;
    1088             : 
    1089          14 :     if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
    1090             :     {
    1091           0 :         SetClipRegion();
    1092           0 :         long nX = pMenu->pLogo ? pMenu->pLogo->aBitmap.GetSizePixel().Width() : 0;
    1093           0 :         Size aPxSize( GetOutputSizePixel() );
    1094           0 :         aPxSize.Width() -= nX;
    1095           0 :         ImplControlValue aVal( pMenu->nTextPos-GUTTERBORDER );
    1096             :         DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
    1097             :                            Rectangle( Point( nX, 0 ), aPxSize ),
    1098             :                            CTRL_STATE_ENABLED,
    1099             :                            aVal,
    1100           0 :                            OUString() );
    1101           0 :         InitMenuClipRegion();
    1102             :     }
    1103          14 :     if ( IsScrollMenu() )
    1104             :     {
    1105           0 :         ImplDrawScroller( true );
    1106           0 :         ImplDrawScroller( false );
    1107             :     }
    1108          14 :     SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
    1109          14 :     pMenu->ImplPaint( this, nScrollerHeight, ImplGetStartY() );
    1110          14 :     if ( nHighlightedItem != ITEMPOS_INVALID )
    1111           0 :         HighlightItem( nHighlightedItem, true );
    1112             : }
    1113             : 
    1114           0 : void MenuFloatingWindow::ImplDrawScroller( bool bUp )
    1115             : {
    1116           0 :     if( ! pMenu )
    1117           0 :         return;
    1118             : 
    1119           0 :     SetClipRegion();
    1120             : 
    1121           0 :     Size aOutSz = GetOutputSizePixel();
    1122           0 :     long nY = bUp ? 0 : ( aOutSz.Height() - nScrollerHeight );
    1123           0 :     long nX = pMenu->pLogo ? pMenu->pLogo->aBitmap.GetSizePixel().Width() : 0;
    1124           0 :     Rectangle aRect( Point( nX, nY ), Size( aOutSz.Width()-nX, nScrollerHeight ) );
    1125             : 
    1126           0 :     DecorationView aDecoView( this );
    1127           0 :     SymbolType eSymbol = bUp ? SymbolType::SPIN_UP : SymbolType::SPIN_DOWN;
    1128             : 
    1129           0 :     sal_uInt16 nStyle = 0;
    1130           0 :     if ( ( bUp && !bScrollUp ) || ( !bUp && !bScrollDown ) )
    1131           0 :         nStyle |= SYMBOL_DRAW_DISABLE;
    1132             : 
    1133           0 :     aDecoView.DrawSymbol( aRect, eSymbol, GetSettings().GetStyleSettings().GetButtonTextColor(), nStyle );
    1134             : 
    1135           0 :     InitMenuClipRegion();
    1136             : }
    1137             : 
    1138           0 : void MenuFloatingWindow::RequestHelp( const HelpEvent& rHEvt )
    1139             : {
    1140           0 :     sal_uInt16 nId = nHighlightedItem;
    1141           0 :     Menu* pM = pMenu;
    1142           0 :     vcl::Window* pW = this;
    1143             : 
    1144             :     // #102618# Get item rect before destroying the window in EndExecute() call
    1145           0 :     Rectangle aHighlightRect( ImplGetItemRect( nHighlightedItem ) );
    1146             : 
    1147           0 :     if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) )
    1148             :     {
    1149           0 :         nHighlightedItem = ITEMPOS_INVALID;
    1150           0 :         EndExecute();
    1151           0 :         pW = NULL;
    1152             :     }
    1153             : 
    1154           0 :     if( !ImplHandleHelpEvent( pW, pM, nId, rHEvt, aHighlightRect ) )
    1155           0 :         Window::RequestHelp( rHEvt );
    1156           0 : }
    1157             : 
    1158          48 : void MenuFloatingWindow::StateChanged( StateChangedType nType )
    1159             : {
    1160          48 :     FloatingWindow::StateChanged( nType );
    1161             : 
    1162          48 :     if ( ( nType == StateChangedType::CONTROLFOREGROUND ) || ( nType == StateChangedType::CONTROLBACKGROUND ) )
    1163             :     {
    1164           0 :         ImplInitMenuWindow( this, false, false );
    1165           0 :         Invalidate();
    1166             :     }
    1167          48 : }
    1168             : 
    1169           0 : void MenuFloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
    1170             : {
    1171           0 :     FloatingWindow::DataChanged( rDCEvt );
    1172             : 
    1173           0 :     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
    1174           0 :          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
    1175           0 :          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
    1176           0 :           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    1177             :     {
    1178           0 :         ImplInitMenuWindow( this, false, false );
    1179           0 :         Invalidate();
    1180             :     }
    1181           0 : }
    1182             : 
    1183           0 : void MenuFloatingWindow::Command( const CommandEvent& rCEvt )
    1184             : {
    1185           0 :     if ( rCEvt.GetCommand() == COMMAND_WHEEL )
    1186             :     {
    1187           0 :         const CommandWheelData* pData = rCEvt.GetWheelData();
    1188           0 :         if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
    1189             :         {
    1190             : //          ImplCursorUpDown( pData->GetDelta() > 0L );
    1191           0 :             ImplScroll( pData->GetDelta() > 0L );
    1192           0 :             MouseMove( MouseEvent( GetPointerPosPixel(), 0 ) );
    1193             :         }
    1194             :     }
    1195           0 : }
    1196             : 
    1197           0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > MenuFloatingWindow::CreateAccessible()
    1198             : {
    1199           0 :     ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc;
    1200             : 
    1201           0 :     if ( pMenu && !pMenu->pStartedFrom )
    1202           0 :         xAcc = pMenu->GetAccessible();
    1203             : 
    1204           0 :     return xAcc;
    1205        1233 : }
    1206             : 
    1207             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10