LCOV - code coverage report
Current view: top level - vcl/source/window - menubarwindow.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 316 673 47.0 %
Date: 2015-06-13 12:38:46 Functions: 30 53 56.6 %
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 "menubarwindow.hxx"
      21             : #include "menuitemlist.hxx"
      22             : #include "menufloatingwindow.hxx"
      23             : 
      24             : #include <vcl/dockingarea.hxx>
      25             : #include <vcl/settings.hxx>
      26             : #include <vcl/taskpanelist.hxx>
      27             : 
      28             : #include <salframe.hxx>
      29             : #include <salmenu.hxx>
      30             : #include <svdata.hxx>
      31             : #include <svids.hrc>
      32             : #include <window.h>
      33             : 
      34             : // document closing button
      35             : #define IID_DOCUMENTCLOSE 1
      36             : 
      37        3199 : DecoToolBox::DecoToolBox( vcl::Window* pParent, WinBits nStyle ) :
      38        3199 :     ToolBox( pParent, nStyle )
      39             : {
      40        3199 :     ImplInit();
      41        3199 : }
      42             : 
      43        3199 : void DecoToolBox::ImplInit()
      44             : {
      45        3199 :     lastSize = -1;
      46        3199 :     calcMinSize();
      47        3199 : }
      48             : 
      49           3 : void DecoToolBox::DataChanged( const DataChangedEvent& rDCEvt )
      50             : {
      51           3 :     Window::DataChanged( rDCEvt );
      52             : 
      53           3 :     if ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
      54             :     {
      55           0 :         calcMinSize();
      56           0 :         SetBackground();
      57           0 :         SetImages( 0, true);
      58             :     }
      59           3 : }
      60             : 
      61        3199 : void DecoToolBox::calcMinSize()
      62             : {
      63        3199 :     ScopedVclPtrInstance<ToolBox> aTbx( GetParent() );
      64        3199 :     if( GetItemCount() == 0 )
      65             :     {
      66        3199 :         ResMgr* pResMgr = ImplGetResMgr();
      67             : 
      68        3199 :         Bitmap aBitmap;
      69        3199 :         if( pResMgr )
      70        3199 :             aBitmap = Bitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) );
      71        3199 :         aTbx->InsertItem( IID_DOCUMENTCLOSE, Image( aBitmap ) );
      72             :     }
      73             :     else
      74             :     {
      75           0 :         sal_uInt16 nItems = GetItemCount();
      76           0 :         for( sal_uInt16 i = 0; i < nItems; i++ )
      77             :         {
      78           0 :             sal_uInt16 nId = GetItemId( i );
      79           0 :             aTbx->InsertItem( nId, GetItemImage( nId ) );
      80             :         }
      81             :     }
      82        3199 :     aTbx->SetOutStyle( TOOLBOX_STYLE_FLAT );
      83        3199 :     maMinSize = aTbx->CalcWindowSizePixel();
      84             : 
      85        3199 :     aTbx.disposeAndClear();
      86        3199 : }
      87             : 
      88        3184 : void DecoToolBox::SetImages( long nMaxHeight, bool bForce )
      89             : {
      90        3184 :     long border = getMinSize().Height() - maImage.GetSizePixel().Height();
      91             : 
      92        3184 :     if( !nMaxHeight && lastSize != -1 )
      93           0 :         nMaxHeight = lastSize + border; // don't change anything if called with 0
      94             : 
      95        3184 :     if( nMaxHeight < getMinSize().Height() )
      96           1 :         nMaxHeight = getMinSize().Height();
      97             : 
      98        3184 :     if( (lastSize != nMaxHeight - border) || bForce )
      99             :     {
     100        3131 :         lastSize = nMaxHeight - border;
     101             : 
     102        3131 :         Color       aEraseColor( 255, 255, 255, 255 );
     103        3131 :         BitmapEx    aBmpExDst( maImage.GetBitmapEx() );
     104        6262 :         BitmapEx    aBmpExSrc( aBmpExDst );
     105             : 
     106        3131 :         aEraseColor.SetTransparency( 255 );
     107        3131 :         aBmpExDst.Erase( aEraseColor );
     108        3131 :         aBmpExDst.SetSizePixel( Size( lastSize, lastSize ) );
     109             : 
     110        3131 :         Rectangle aSrcRect( Point(0,0), maImage.GetSizePixel() );
     111        6262 :         Rectangle aDestRect( Point((lastSize - maImage.GetSizePixel().Width())/2,
     112        6262 :                                 (lastSize - maImage.GetSizePixel().Height())/2 ),
     113       12524 :                             maImage.GetSizePixel() );
     114             : 
     115        3131 :         aBmpExDst.CopyPixel( aDestRect, aSrcRect, &aBmpExSrc );
     116        6262 :         SetItemImage( IID_DOCUMENTCLOSE, Image( aBmpExDst ) );
     117             :     }
     118        3184 : }
     119             : 
     120        3199 : MenuBarWindow::MenuBarWindow( vcl::Window* pParent ) :
     121             :     Window( pParent, 0 ),
     122             :     aCloseBtn(VclPtr<DecoToolBox>::Create(this)),
     123             :     aFloatBtn(VclPtr<PushButton>::Create(this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE)),
     124        3199 :     aHideBtn(VclPtr<PushButton>::Create(this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE))
     125             : {
     126        3199 :     SetType(WINDOW_MENUBARWINDOW);
     127        3199 :     pMenu = NULL;
     128        3199 :     pActivePopup = NULL;
     129        3199 :     nSaveFocusId = 0;
     130        3199 :     nHighlightedItem = ITEMPOS_INVALID;
     131        3199 :     nRolloveredItem = ITEMPOS_INVALID;
     132        3199 :     mbAutoPopup = true;
     133        3199 :     nSaveFocusId = 0;
     134        3199 :     bIgnoreFirstMove = true;
     135        3199 :     bStayActive = false;
     136             : 
     137        3199 :     ResMgr* pResMgr = ImplGetResMgr();
     138             : 
     139        3199 :     if(pResMgr)
     140             :     {
     141        3199 :         BitmapEx aBitmap(ResId(SV_RESID_BITMAP_CLOSEDOC, *pResMgr));
     142        3199 :         aCloseBtn->maImage = Image(aBitmap);
     143             : 
     144        3199 :         aCloseBtn->SetOutStyle(TOOLBOX_STYLE_FLAT);
     145        3199 :         aCloseBtn->SetBackground();
     146        3199 :         aCloseBtn->SetPaintTransparent(true);
     147        3199 :         aCloseBtn->SetParentClipMode(ParentClipMode::NoClip);
     148             : 
     149        3199 :         aCloseBtn->InsertItem(IID_DOCUMENTCLOSE, aCloseBtn->maImage, ToolBoxItemBits::NONE);
     150        3199 :         aCloseBtn->SetSelectHdl(LINK(this, MenuBarWindow, CloseHdl));
     151        3199 :         aCloseBtn->AddEventListener(LINK(this, MenuBarWindow, ToolboxEventHdl));
     152        3199 :         aCloseBtn->SetQuickHelpText(IID_DOCUMENTCLOSE, ResId(SV_HELPTEXT_CLOSEDOCUMENT, *pResMgr).toString());
     153             : 
     154        3199 :         aFloatBtn->SetClickHdl( LINK( this, MenuBarWindow, FloatHdl ) );
     155        3199 :         aFloatBtn->SetSymbol( SymbolType::FLOAT );
     156        3199 :         aFloatBtn->SetQuickHelpText( ResId(SV_HELPTEXT_RESTORE, *pResMgr).toString() );
     157             : 
     158        3199 :         aHideBtn->SetClickHdl( LINK( this, MenuBarWindow, HideHdl ) );
     159        3199 :         aHideBtn->SetSymbol( SymbolType::HIDE );
     160        3199 :         aHideBtn->SetQuickHelpText( ResId(SV_HELPTEXT_MINIMIZE, *pResMgr).toString() );
     161             :     }
     162             : 
     163        3199 :     ImplInitStyleSettings();
     164             : 
     165        3199 :     AddEventListener(LINK(this, MenuBarWindow, ShowHideListener));
     166        3199 : }
     167             : 
     168        9579 : MenuBarWindow::~MenuBarWindow()
     169             : {
     170        3193 :     disposeOnce();
     171        6386 : }
     172             : 
     173        3193 : void MenuBarWindow::dispose()
     174             : {
     175        3193 :     aCloseBtn->RemoveEventListener(LINK(this, MenuBarWindow, ToolboxEventHdl));
     176        3193 :     RemoveEventListener(LINK(this, MenuBarWindow, ShowHideListener));
     177             : 
     178        3193 :     aHideBtn.disposeAndClear();
     179        3193 :     aFloatBtn.disposeAndClear();
     180        3193 :     aCloseBtn.disposeAndClear();
     181             : 
     182        3193 :     Window::dispose();
     183        3193 : }
     184             : 
     185        3200 : void MenuBarWindow::SetMenu( MenuBar* pMen )
     186             : {
     187        3200 :     pMenu = pMen;
     188        3200 :     KillActivePopup();
     189        3200 :     nHighlightedItem = ITEMPOS_INVALID;
     190        3200 :     if (pMen)
     191             :     {
     192        3200 :         aCloseBtn->ShowItem(IID_DOCUMENTCLOSE, pMen->HasCloseButton());
     193        3200 :         aCloseBtn->Show(pMen->HasCloseButton() || !m_aAddButtons.empty());
     194        3200 :         aFloatBtn->Show(pMen->HasFloatButton());
     195        3200 :         aHideBtn->Show(pMen->HasHideButton());
     196             :     }
     197        3200 :     Invalidate();
     198             : 
     199             :     // show and connect native menubar
     200        3200 :     if( pMenu && pMenu->ImplGetSalMenu() )
     201             :     {
     202           2 :         if( pMenu->ImplGetSalMenu()->VisibleMenuBar() )
     203           0 :             ImplGetFrame()->SetMenu( pMenu->ImplGetSalMenu() );
     204             : 
     205           2 :         pMenu->ImplGetSalMenu()->SetFrame( ImplGetFrame() );
     206             :     }
     207        3200 : }
     208             : 
     209        3200 : void MenuBarWindow::SetHeight(long nHeight)
     210             : {
     211        3200 :     setPosSizePixel(0, 0, 0, nHeight, PosSizeFlags::Height);
     212        3200 : }
     213             : 
     214        3211 : void MenuBarWindow::ShowButtons( bool bClose, bool bFloat, bool bHide )
     215             : {
     216        3211 :     aCloseBtn->ShowItem(IID_DOCUMENTCLOSE, bClose);
     217        3211 :     aCloseBtn->Show(bClose || !m_aAddButtons.empty());
     218        3211 :     aFloatBtn->Show( bFloat );
     219        3211 :     aHideBtn->Show( bHide );
     220        3211 :     Resize();
     221        3211 : }
     222             : 
     223        3368 : Size MenuBarWindow::MinCloseButtonSize()
     224             : {
     225        3368 :     return aCloseBtn->getMinSize();
     226             : }
     227             : 
     228           0 : IMPL_LINK_NOARG_TYPED(MenuBarWindow, CloseHdl, ToolBox *, void)
     229             : {
     230           0 :     if( ! pMenu )
     231           0 :         return;
     232             : 
     233           0 :     if( aCloseBtn->GetCurItemId() == IID_DOCUMENTCLOSE )
     234             :     {
     235             :         // #i106052# call close hdl asynchronously to ease handler implementation
     236             :         // this avoids still being in the handler while the DecoToolBox already
     237             :         // gets destroyed
     238           0 :         Application::PostUserEvent(static_cast<MenuBar*>(pMenu)->GetCloseButtonClickHdl(), pMenu);
     239             :     }
     240             :     else
     241             :     {
     242           0 :         std::map<sal_uInt16,AddButtonEntry>::iterator it = m_aAddButtons.find(aCloseBtn->GetCurItemId());
     243           0 :         if( it != m_aAddButtons.end() )
     244             :         {
     245             :             MenuBar::MenuBarButtonCallbackArg aArg;
     246           0 :             aArg.nId = it->first;
     247           0 :             aArg.bHighlight = (aCloseBtn->GetHighlightItemId() == it->first);
     248           0 :             aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
     249           0 :             it->second.m_aSelectLink.Call( &aArg );
     250             :         }
     251             :     }
     252             : }
     253             : 
     254       59794 : IMPL_LINK( MenuBarWindow, ToolboxEventHdl, VclWindowEvent*, pEvent )
     255             : {
     256       29897 :     if( ! pMenu )
     257           0 :         return 0;
     258             : 
     259             :     MenuBar::MenuBarButtonCallbackArg aArg;
     260       29897 :     aArg.nId = 0xffff;
     261       29897 :     aArg.bHighlight = (pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT);
     262       29897 :     aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
     263       29897 :     if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT )
     264           0 :         aArg.nId = aCloseBtn->GetHighlightItemId();
     265       29897 :     else if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHTOFF )
     266             :     {
     267           0 :         sal_uInt16 nPos = static_cast< sal_uInt16 >(reinterpret_cast<sal_IntPtr>(pEvent->GetData()));
     268           0 :         aArg.nId = aCloseBtn->GetItemId(nPos);
     269             :     }
     270       29897 :     std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( aArg.nId );
     271       29897 :     if( it != m_aAddButtons.end() )
     272             :     {
     273           0 :         it->second.m_aHighlightLink.Call( &aArg );
     274             :     }
     275       29897 :     return 0;
     276             : }
     277             : 
     278       23678 : IMPL_LINK( MenuBarWindow, ShowHideListener, VclWindowEvent*, pEvent )
     279             : {
     280       11839 :     if( ! pMenu )
     281           0 :         return 0;
     282             : 
     283       11839 :     if( pEvent->GetId() == VCLEVENT_WINDOW_SHOW )
     284        4010 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_SHOW, ITEMPOS_INVALID );
     285        7829 :     else if( pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
     286           0 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_HIDE, ITEMPOS_INVALID );
     287       11839 :     return 0;
     288             : }
     289             : 
     290           0 : IMPL_LINK_NOARG(MenuBarWindow, FloatHdl)
     291             : {
     292           0 :     return pMenu ? static_cast<MenuBar*>(pMenu)->GetFloatButtonClickHdl().Call( pMenu ) : 0;
     293             : }
     294             : 
     295           0 : IMPL_LINK_NOARG(MenuBarWindow, HideHdl)
     296             : {
     297           0 :     return pMenu ? static_cast<MenuBar*>(pMenu)->GetHideButtonClickHdl().Call( pMenu ) : 0;
     298             : }
     299             : 
     300          24 : void MenuBarWindow::ImplCreatePopup( bool bPreSelectFirst )
     301             : {
     302          24 :     MenuItemData* pItemData = pMenu ? pMenu->GetItemList()->GetDataFromPos( nHighlightedItem ) : NULL;
     303          24 :     if ( pItemData )
     304             :     {
     305           8 :         bIgnoreFirstMove = true;
     306           8 :         if ( pActivePopup && ( pActivePopup != pItemData->pSubMenu ) )
     307             :         {
     308           0 :             KillActivePopup();
     309             :         }
     310          16 :         if ( pItemData->bEnabled && pItemData->pSubMenu && ( nHighlightedItem != ITEMPOS_INVALID ) &&
     311           8 :              ( pItemData->pSubMenu != pActivePopup ) )
     312             :         {
     313           8 :             pActivePopup = static_cast<PopupMenu*>(pItemData->pSubMenu);
     314           8 :             long nX = 0;
     315           8 :             MenuItemData* pData = 0;
     316          19 :             for ( sal_uLong n = 0; n < nHighlightedItem; n++ )
     317             :             {
     318          11 :                 pData = pMenu->GetItemList()->GetDataFromPos( n );
     319          11 :                 nX += pData->aSz.Width();
     320             :             }
     321           8 :             pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
     322           8 :             Point aItemTopLeft( nX, 0 );
     323           8 :             Point aItemBottomRight( aItemTopLeft );
     324           8 :             aItemBottomRight.X() += pData->aSz.Width();
     325             : 
     326             :             // the menu bar could have height 0 in fullscreen mode:
     327             :             // so do not use always WindowHeight, as ItemHeight < WindowHeight.
     328           8 :             if ( GetSizePixel().Height() )
     329             :             {
     330             :                 // #107747# give menuitems the height of the menubar
     331           8 :                 aItemBottomRight.Y() += GetOutputSizePixel().Height()-1;
     332             :             }
     333             : 
     334             :             // ImplExecute is not modal...
     335             :             // #99071# do not grab the focus, otherwise it will be restored to the menubar
     336             :             // when the frame is reactivated later
     337             :             //GrabFocus();
     338           8 :             pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FloatWinPopupFlags::Down | FloatWinPopupFlags::NoHorzPlacement, pMenu, bPreSelectFirst );
     339             :             // does not have a window, if aborted before or if there are no entries
     340           8 :             if ( pActivePopup->ImplGetFloatingWindow() )
     341           8 :                 pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this );
     342             :             else
     343           0 :                 pActivePopup = nullptr;
     344             :         }
     345             :     }
     346          24 : }
     347             : 
     348        6401 : void MenuBarWindow::KillActivePopup()
     349             : {
     350        6401 :     if ( pActivePopup )
     351             :     {
     352           8 :         if( pActivePopup->pWindow )
     353           8 :             if( static_cast<FloatingWindow *>(pActivePopup->pWindow.get())->IsInCleanUp() )
     354        6401 :                 return; // kill it later
     355             : 
     356           8 :         if ( pActivePopup->bInCallback )
     357           0 :             pActivePopup->bCanceled = true;
     358             : 
     359           8 :         pActivePopup->bInCallback = true;
     360           8 :         pActivePopup->Deactivate();
     361           8 :         pActivePopup->bInCallback = false;
     362             :         // check for pActivePopup, if stopped by deactivate...
     363           8 :         if ( pActivePopup->ImplGetWindow() )
     364             :         {
     365           8 :             pActivePopup->ImplGetFloatingWindow()->StopExecute();
     366           8 :             pActivePopup->ImplGetFloatingWindow()->doShutdown();
     367           8 :             pActivePopup->pWindow->doLazyDelete();
     368           8 :             pActivePopup->pWindow = NULL;
     369             :         }
     370           8 :         pActivePopup = 0;
     371             :     }
     372             : }
     373             : 
     374           0 : void MenuBarWindow::PopupClosed( Menu* pPopup )
     375             : {
     376           0 :     if ( pPopup == pActivePopup )
     377             :     {
     378           0 :         KillActivePopup();
     379           0 :         ChangeHighlightItem( ITEMPOS_INVALID, false, ImplGetFrameWindow()->ImplGetFrameData()->mbHasFocus, false );
     380             :     }
     381           0 : }
     382             : 
     383           0 : void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt )
     384             : {
     385           0 :     mbAutoPopup = true;
     386           0 :     sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
     387           0 :     if ( ( nEntry != ITEMPOS_INVALID ) && !pActivePopup )
     388             :     {
     389           0 :         ChangeHighlightItem( nEntry, false );
     390             :     }
     391             :     else
     392             :     {
     393           0 :         KillActivePopup();
     394           0 :         ChangeHighlightItem( ITEMPOS_INVALID, false );
     395             :     }
     396           0 : }
     397             : 
     398           0 : void MenuBarWindow::MouseButtonUp( const MouseEvent& )
     399             : {
     400           0 : }
     401             : 
     402           0 : void MenuBarWindow::MouseMove( const MouseEvent& rMEvt )
     403             : {
     404           0 :     if ( rMEvt.IsSynthetic() || rMEvt.IsEnterWindow() )
     405           0 :         return;
     406             : 
     407           0 :     if ( rMEvt.IsLeaveWindow() )
     408             :     {
     409           0 :         if ( nRolloveredItem != ITEMPOS_INVALID && nRolloveredItem != nHighlightedItem )
     410           0 :             Invalidate(); //HighlightItem( nRolloveredItem, false );
     411             : 
     412           0 :         nRolloveredItem = ITEMPOS_INVALID;
     413           0 :         return;
     414             :     }
     415             : 
     416           0 :     sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
     417           0 :     if ( nHighlightedItem == ITEMPOS_INVALID )
     418             :     {
     419           0 :         if ( nRolloveredItem != nEntry  )
     420             :         {
     421           0 :             if ( nRolloveredItem != ITEMPOS_INVALID )
     422           0 :                 Invalidate(); //HighlightItem( nRolloveredItem, false );
     423             : 
     424           0 :             nRolloveredItem = nEntry;
     425           0 :             Invalidate(); //HighlightItem( nRolloveredItem, true );
     426             :         }
     427           0 :         return;
     428             :     }
     429           0 :     nRolloveredItem = nEntry;
     430             : 
     431           0 :     if( bIgnoreFirstMove )
     432             :     {
     433           0 :         bIgnoreFirstMove = false;
     434           0 :         return;
     435             :     }
     436             : 
     437           0 :     if ( ( nEntry != ITEMPOS_INVALID )
     438           0 :        && ( nEntry != nHighlightedItem ) )
     439           0 :         ChangeHighlightItem( nEntry, false );
     440             : }
     441             : 
     442          26 : void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, bool bSelectEntry, bool bAllowRestoreFocus, bool bDefaultToDocument)
     443             : {
     444          26 :     if( ! pMenu )
     445          26 :         return;
     446             : 
     447             :     // #57934# close active popup if applicable, as TH's background storage works.
     448          26 :     MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
     449          26 :     if ( pActivePopup && pActivePopup->ImplGetWindow() && ( !pNextData || ( pActivePopup != pNextData->pSubMenu ) ) )
     450           0 :         KillActivePopup(); // pActivePopup when applicable without pWin, if Rescheduled in  Activate()
     451             : 
     452             :     // activate menubar only ones per cycle...
     453          26 :     bool bJustActivated = false;
     454          26 :     if ( ( nHighlightedItem == ITEMPOS_INVALID ) && ( n != ITEMPOS_INVALID ) )
     455             :     {
     456          10 :         ImplGetSVData()->maWinData.mbNoDeactivate = true;
     457          10 :         if( !bStayActive )
     458             :         {
     459             :             // #105406# avoid saving the focus when we already have the focus
     460          10 :             bool bNoSaveFocus = (this == ImplGetSVData()->maWinData.mpFocusWin.get() );
     461             : 
     462          10 :             if( nSaveFocusId )
     463             :             {
     464           0 :                 if( !ImplGetSVData()->maWinData.mbNoSaveFocus )
     465             :                 {
     466             :                     // we didn't clean up last time
     467           0 :                     Window::EndSaveFocus( nSaveFocusId, false );    // clean up
     468           0 :                     nSaveFocusId = 0;
     469           0 :                     if( !bNoSaveFocus )
     470           0 :                         nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated
     471             :                 }
     472             :                 else {
     473             :                     ; // do nothing: we 're activated again from taskpanelist, focus was already saved
     474             :                 }
     475             :             }
     476             :             else
     477             :             {
     478          10 :                 if( !bNoSaveFocus )
     479           8 :                     nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated
     480             :             }
     481             :         }
     482             :         else
     483           0 :             bStayActive = false;
     484          10 :         pMenu->bInCallback = true;  // set here if Activate overridden
     485          10 :         pMenu->Activate();
     486          10 :         pMenu->bInCallback = false;
     487          10 :         bJustActivated = true;
     488             :     }
     489          16 :     else if ( ( nHighlightedItem != ITEMPOS_INVALID ) && ( n == ITEMPOS_INVALID ) )
     490             :     {
     491          16 :         pMenu->bInCallback = true;
     492          16 :         pMenu->Deactivate();
     493          16 :         pMenu->bInCallback = false;
     494          16 :         ImplGetSVData()->maWinData.mbNoDeactivate = false;
     495          16 :         if( !ImplGetSVData()->maWinData.mbNoSaveFocus )
     496             :         {
     497          16 :             sal_uLong nTempFocusId = nSaveFocusId;
     498          16 :             nSaveFocusId = 0;
     499          16 :             Window::EndSaveFocus( nTempFocusId, bAllowRestoreFocus );
     500             :             // #105406# restore focus to document if we could not save focus before
     501          16 :             if( bDefaultToDocument && !nTempFocusId && bAllowRestoreFocus )
     502           2 :                 GrabFocusToDocument();
     503             :         }
     504             :     }
     505             : 
     506          26 :     if ( nHighlightedItem != ITEMPOS_INVALID )
     507             :     {
     508           8 :         if ( nHighlightedItem != nRolloveredItem )
     509           8 :             Invalidate(); //HighlightItem( nHighlightedItem, false );
     510             : 
     511           8 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
     512             :     }
     513             : 
     514          26 :     nHighlightedItem = (sal_uInt16)n;
     515             :     DBG_ASSERT( ( nHighlightedItem == ITEMPOS_INVALID ) || pMenu->ImplIsVisible( nHighlightedItem ), "ChangeHighlightItem: Not visible!" );
     516          26 :     if ( nHighlightedItem != ITEMPOS_INVALID )
     517          10 :         Invalidate(); //HighlightItem( nHighlightedItem, true );
     518          16 :     else if ( nRolloveredItem != ITEMPOS_INVALID )
     519           0 :         Invalidate(); //HighlightItem( nRolloveredItem, true );
     520          26 :     pMenu->ImplCallHighlight(nHighlightedItem);
     521             : 
     522          26 :     if( mbAutoPopup )
     523          24 :         ImplCreatePopup( bSelectEntry );
     524             : 
     525             :     // #58935# #73659# Focus, if no popup underneath...
     526          26 :     if ( bJustActivated && !pActivePopup )
     527           2 :         GrabFocus();
     528             : }
     529             : 
     530           0 : static int ImplGetTopDockingAreaHeight( vcl::Window *pWindow )
     531             : {
     532             :     // find docking area that is top aligned and return its height
     533             :     // note: dockingareas are direct children of the SystemWindow
     534           0 :     if( pWindow->ImplGetFrameWindow() )
     535             :     {
     536           0 :         vcl::Window *pWin = pWindow->ImplGetFrameWindow()->GetWindow( GetWindowType::FirstChild ); //mpWindowImpl->mpFirstChild;
     537           0 :         while( pWin )
     538             :         {
     539           0 :             if( pWin->IsSystemWindow() )
     540             :             {
     541           0 :                 vcl::Window *pChildWin = pWin->GetWindow( GetWindowType::FirstChild ); //mpWindowImpl->mpFirstChild;
     542           0 :                 while( pChildWin )
     543             :                 {
     544           0 :                     DockingAreaWindow *pDockingArea = NULL;
     545           0 :                     if ( pChildWin->GetType() == WINDOW_DOCKINGAREA )
     546           0 :                         pDockingArea = static_cast< DockingAreaWindow* >( pChildWin );
     547             : 
     548           0 :                     if( pDockingArea && pDockingArea->GetAlign() == WINDOWALIGN_TOP &&
     549           0 :                         pDockingArea->IsVisible() && pDockingArea->GetOutputSizePixel().Height() != 0 )
     550             :                     {
     551           0 :                         return pDockingArea->GetOutputSizePixel().Height();
     552             :                     }
     553             : 
     554           0 :                     pChildWin = pChildWin->GetWindow( GetWindowType::Next ); //mpWindowImpl->mpNext;
     555             :                 }
     556             : 
     557             :             }
     558             : 
     559           0 :             pWin = pWin->GetWindow( GetWindowType::Next ); //mpWindowImpl->mpNext;
     560             :         }
     561             :     }
     562           0 :     return 0;
     563             : }
     564             : 
     565           0 : static void ImplAddNWFSeparator( vcl::RenderContext& rRenderContext, const MenubarValue& rMenubarValue )
     566             : {
     567             :     // add a separator if
     568             :     // - we have an adjacent docking area
     569             :     // - and if toolbars would draw them as well (mbDockingAreaSeparateTB must not be set, see dockingarea.cxx)
     570           0 :     if (rMenubarValue.maTopDockingAreaHeight
     571           0 :       && !ImplGetSVData()->maNWFData.mbDockingAreaSeparateTB
     572           0 :       && !ImplGetSVData()->maNWFData.mbDockingAreaAvoidTBFrames)
     573             :     {
     574             :         // note: the menubar only provides the upper (dark) half of it, the rest (bright part) is drawn by the docking area
     575             : 
     576           0 :         rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetSeparatorColor());
     577           0 :         Point aPt;
     578           0 :         Rectangle aRect(aPt, rRenderContext.GetOutputSizePixel());
     579           0 :         rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
     580             :     }
     581           0 : }
     582             : 
     583           8 : void MenuBarWindow::HighlightItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHighlight)
     584             : {
     585           8 :     if (!pMenu)
     586           0 :         return;
     587             : 
     588           8 :     long nX = 0;
     589           8 :     size_t nCount = pMenu->pItemList->size();
     590          19 :     for (size_t n = 0; n < nCount; n++)
     591             :     {
     592          19 :         MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
     593          19 :         if (n == nPos)
     594             :         {
     595           8 :             if (pData->eType != MenuItemType::SEPARATOR)
     596             :             {
     597             :                 // #107747# give menuitems the height of the menubar
     598           8 :                 Rectangle aRect = Rectangle(Point(nX, 1), Size(pData->aSz.Width(), GetOutputSizePixel().Height() - 2));
     599           8 :                 rRenderContext.Push(PushFlags::CLIPREGION);
     600           8 :                 rRenderContext.IntersectClipRegion(aRect);
     601           8 :                 bool bRollover = bHighlight && nPos != nHighlightedItem;
     602           8 :                 if (bHighlight)
     603             :                 {
     604           8 :                     if (rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_MENU_ITEM) &&
     605           0 :                         rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
     606             :                     {
     607             :                         // draw background (transparency)
     608           0 :                         MenubarValue aControlValue;
     609           0 :                         aControlValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this );
     610             : 
     611           0 :                         if (!Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() )
     612           0 :                             Erase(rRenderContext);
     613             :                         else
     614             :                         {
     615           0 :                             Rectangle aBgRegion(Point(), rRenderContext.GetOutputSizePixel());
     616             :                             rRenderContext.DrawNativeControl(CTRL_MENUBAR, PART_ENTIRE_CONTROL, aBgRegion,
     617           0 :                                                              ControlState::ENABLED, aControlValue, OUString());
     618             :                         }
     619             : 
     620           0 :                         ImplAddNWFSeparator(rRenderContext, aControlValue);
     621             : 
     622             :                         // draw selected item
     623           0 :                         ControlState nState = ControlState::ENABLED;
     624           0 :                         if (bRollover)
     625           0 :                             nState |= ControlState::ROLLOVER;
     626             :                         else
     627           0 :                             nState |= ControlState::SELECTED;
     628             :                         rRenderContext.DrawNativeControl(CTRL_MENUBAR, PART_MENU_ITEM,
     629           0 :                                                          aRect, nState, aControlValue, OUString() );
     630             :                     }
     631             :                     else
     632             :                     {
     633           8 :                         if (bRollover)
     634           0 :                             rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuBarRolloverColor());
     635             :                         else
     636           8 :                             rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuHighlightColor());
     637           8 :                         rRenderContext.SetLineColor();
     638           8 :                         rRenderContext.DrawRect(aRect);
     639             :                     }
     640             :                 }
     641             :                 else
     642             :                 {
     643           0 :                     if (rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
     644             :                     {
     645           0 :                         MenubarValue aMenubarValue;
     646           0 :                         aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this );
     647             : 
     648           0 :                         if (!Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty())
     649           0 :                             rRenderContext.Erase(aRect);
     650             :                         else
     651             :                         {
     652             :                             // use full window size to get proper gradient
     653             :                             // but clip accordingly
     654           0 :                             Point aPt;
     655           0 :                             Rectangle aCtrlRect(aPt, rRenderContext.GetOutputSizePixel());
     656             : 
     657             :                             rRenderContext.DrawNativeControl(CTRL_MENUBAR, PART_ENTIRE_CONTROL,
     658           0 :                                                              aCtrlRect, ControlState::ENABLED, aMenubarValue, OUString());
     659             :                         }
     660             : 
     661           0 :                         ImplAddNWFSeparator(rRenderContext, aMenubarValue);
     662             :                     }
     663             :                     else
     664           0 :                         rRenderContext.Erase(aRect);
     665             :                 }
     666           8 :                 rRenderContext.Pop();
     667           8 :                 pMenu->ImplPaint(rRenderContext, 0, 0, pData, bHighlight, false, bRollover);
     668             :             }
     669           8 :             return;
     670             :         }
     671             : 
     672          11 :         nX += pData->aSz.Width();
     673             :     }
     674             : }
     675             : 
     676           0 : Rectangle MenuBarWindow::ImplGetItemRect( sal_uInt16 nPos )
     677             : {
     678           0 :     Rectangle aRect;
     679           0 :     if( pMenu )
     680             :     {
     681           0 :         long nX = 0;
     682           0 :         size_t nCount = pMenu->pItemList->size();
     683           0 :         for ( size_t n = 0; n < nCount; n++ )
     684             :         {
     685           0 :             MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
     686           0 :             if ( n == nPos )
     687             :             {
     688           0 :                 if ( pData->eType != MenuItemType::SEPARATOR )
     689             :                     // #107747# give menuitems the height of the menubar
     690           0 :                     aRect = Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), GetOutputSizePixel().Height()-2 ) );
     691           0 :                 break;
     692             :             }
     693             : 
     694           0 :             nX += pData->aSz.Width();
     695             :         }
     696             :     }
     697           0 :     return aRect;
     698             : }
     699             : 
     700           0 : void MenuBarWindow::KeyInput( const KeyEvent& rKEvent )
     701             : {
     702           0 :     if ( !HandleKeyEvent( rKEvent ) )
     703           0 :         Window::KeyInput( rKEvent );
     704           0 : }
     705             : 
     706           0 : bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
     707             : {
     708           0 :     if( ! pMenu )
     709           0 :         return false;
     710             : 
     711           0 :     if ( pMenu->bInCallback )
     712           0 :         return true;    // swallow
     713             : 
     714           0 :     bool bDone = false;
     715           0 :     sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
     716             : 
     717           0 :     if( GetParent() )
     718             :     {
     719           0 :         if( GetParent()->GetWindow( GetWindowType::Client )->IsSystemWindow() )
     720             :         {
     721           0 :             SystemWindow *pSysWin = static_cast<SystemWindow*>(GetParent()->GetWindow( GetWindowType::Client ));
     722           0 :             if( pSysWin->GetTaskPaneList() )
     723           0 :                 if( pSysWin->GetTaskPaneList()->HandleKeyEvent( rKEvent ) )
     724           0 :                     return true;
     725             :         }
     726             :     }
     727             : 
     728           0 :     if ( nCode == KEY_MENU && !rKEvent.GetKeyCode().IsShift() ) // only F10, not Shift-F10
     729             :     {
     730           0 :         mbAutoPopup = ImplGetSVData()->maNWFData.mbOpenMenuOnF10;
     731           0 :         if ( nHighlightedItem == ITEMPOS_INVALID )
     732             :         {
     733           0 :             ChangeHighlightItem( 0, false );
     734           0 :             GrabFocus();
     735             :         }
     736             :         else
     737             :         {
     738           0 :             ChangeHighlightItem( ITEMPOS_INVALID, false );
     739           0 :             nSaveFocusId = 0;
     740             :         }
     741           0 :         bDone = true;
     742             :     }
     743           0 :     else if ( bFromMenu )
     744             :     {
     745           0 :         if ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) ||
     746           0 :             ( nCode == KEY_HOME ) || ( nCode == KEY_END ) )
     747             :         {
     748           0 :             sal_uInt16 n = nHighlightedItem;
     749           0 :             if ( n == ITEMPOS_INVALID )
     750             :             {
     751           0 :                 if ( nCode == KEY_LEFT)
     752           0 :                     n = 0;
     753             :                 else
     754           0 :                     n = pMenu->GetItemCount()-1;
     755             :             }
     756             : 
     757             :             // handling gtk like (aka mbOpenMenuOnF10)
     758             :             // do not highlight an item when opening a sub menu
     759             :             // unless there already was a higlighted sub menu item
     760           0 :             bool bWasHighlight = false;
     761           0 :             if( pActivePopup )
     762             :             {
     763           0 :                 MenuFloatingWindow* pSubWindow = dynamic_cast<MenuFloatingWindow*>(pActivePopup->ImplGetWindow());
     764           0 :                 if( pSubWindow )
     765           0 :                     bWasHighlight = (pSubWindow->GetHighlightedItem() != ITEMPOS_INVALID);
     766             :             }
     767             : 
     768           0 :             sal_uInt16 nLoop = n;
     769             : 
     770           0 :             if( nCode == KEY_HOME )
     771           0 :                 { n = (sal_uInt16)-1; nLoop = n+1; }
     772           0 :             if( nCode == KEY_END )
     773           0 :                 { n = pMenu->GetItemCount(); nLoop = n-1; }
     774             : 
     775           0 :             do
     776             :             {
     777           0 :                 if ( nCode == KEY_LEFT || nCode == KEY_END )
     778             :                 {
     779           0 :                     if ( n )
     780           0 :                         n--;
     781             :                     else
     782           0 :                         n = pMenu->GetItemCount()-1;
     783             :                 }
     784           0 :                 if ( nCode == KEY_RIGHT || nCode == KEY_HOME )
     785             :                 {
     786           0 :                     n++;
     787           0 :                     if ( n >= pMenu->GetItemCount() )
     788           0 :                         n = 0;
     789             :                 }
     790             : 
     791           0 :                 MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( n );
     792           0 :                 if ( ( pData->eType != MenuItemType::SEPARATOR ) && pMenu->ImplIsVisible( n ) )
     793             :                 {
     794           0 :                     bool bDoSelect = true;
     795           0 :                     if( ImplGetSVData()->maNWFData.mbOpenMenuOnF10 )
     796           0 :                         bDoSelect = bWasHighlight;
     797           0 :                     ChangeHighlightItem( n, bDoSelect );
     798           0 :                     break;
     799             :                 }
     800             :             } while ( n != nLoop );
     801           0 :             bDone = true;
     802             :         }
     803           0 :         else if ( nCode == KEY_RETURN )
     804             :         {
     805           0 :             if( pActivePopup ) KillActivePopup();
     806             :             else
     807           0 :                 if ( !mbAutoPopup )
     808             :                 {
     809           0 :                     ImplCreatePopup( true );
     810           0 :                     mbAutoPopup = true;
     811             :                 }
     812           0 :             bDone = true;
     813             :         }
     814           0 :         else if ( ( nCode == KEY_UP ) || ( nCode == KEY_DOWN ) )
     815             :         {
     816           0 :             if ( !mbAutoPopup )
     817             :             {
     818           0 :                 ImplCreatePopup( true );
     819           0 :                 mbAutoPopup = true;
     820             :             }
     821           0 :             bDone = true;
     822             :         }
     823           0 :         else if ( nCode == KEY_ESCAPE || ( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() ) )
     824             :         {
     825           0 :             if( pActivePopup )
     826             :             {
     827             :                 // bring focus to menu bar without any open popup
     828           0 :                 mbAutoPopup = false;
     829           0 :                 sal_uInt16 n = nHighlightedItem;
     830           0 :                 nHighlightedItem = ITEMPOS_INVALID;
     831           0 :                 bStayActive = true;
     832           0 :                 ChangeHighlightItem( n, false );
     833           0 :                 bStayActive = false;
     834           0 :                 KillActivePopup();
     835           0 :                 GrabFocus();
     836             :             }
     837             :             else
     838           0 :                 ChangeHighlightItem( ITEMPOS_INVALID, false );
     839             : 
     840           0 :             if( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() )
     841             :             {
     842             :                 // put focus into document
     843           0 :                 GrabFocusToDocument();
     844             :             }
     845             : 
     846           0 :             bDone = true;
     847             :         }
     848             :     }
     849             : 
     850           0 :     if ( !bDone && ( bFromMenu || rKEvent.GetKeyCode().IsMod2() ) )
     851             :     {
     852           0 :         sal_Unicode nCharCode = rKEvent.GetCharCode();
     853           0 :         if ( nCharCode )
     854             :         {
     855             :             sal_uInt16 nEntry, nDuplicates;
     856           0 :             MenuItemData* pData = pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nEntry, nDuplicates, nHighlightedItem );
     857           0 :             if ( pData && (nEntry != ITEMPOS_INVALID) )
     858             :             {
     859           0 :                 mbAutoPopup = true;
     860           0 :                 ChangeHighlightItem( nEntry, true );
     861           0 :                 bDone = true;
     862             :             }
     863             :         }
     864             :     }
     865           0 :     return bDone;
     866             : }
     867             : 
     868        1207 : void MenuBarWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
     869             : {
     870        1207 :     if (!pMenu)
     871           0 :         return;
     872             : 
     873        1207 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     874             : 
     875             :     // no VCL paint if native menus
     876        1207 :     if (pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar())
     877             :     {
     878           0 :         ImplGetFrame()->DrawMenuBar();
     879           0 :         return;
     880             :     }
     881             : 
     882        1207 :     if (rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
     883             :     {
     884           0 :         MenubarValue aMenubarValue;
     885           0 :         aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight(this);
     886             : 
     887           0 :         if (!rStyleSettings.GetPersonaHeader().IsEmpty())
     888           0 :             Erase(rRenderContext);
     889             :         else
     890             :         {
     891           0 :             Point aPt;
     892           0 :             Rectangle aCtrlRegion( aPt, GetOutputSizePixel() );
     893             : 
     894             :             rRenderContext.DrawNativeControl(CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRegion,
     895           0 :                                              ControlState::ENABLED, aMenubarValue, OUString());
     896             :         }
     897             : 
     898           0 :         ImplAddNWFSeparator(rRenderContext, aMenubarValue);
     899             :     }
     900        1207 :     rRenderContext.SetFillColor(rStyleSettings.GetMenuColor());
     901             : 
     902        1207 :     pMenu->ImplPaint(rRenderContext, 0);
     903        1207 :     if (nHighlightedItem != ITEMPOS_INVALID)
     904           8 :         HighlightItem(rRenderContext, nHighlightedItem, true);
     905             : 
     906             :     // in high contrast mode draw a separating line on the lower edge
     907        2414 :     if (!rRenderContext.IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) &&
     908        1207 :         rStyleSettings.GetHighContrastMode())
     909             :     {
     910           0 :         rRenderContext.Push(PushFlags::LINECOLOR | PushFlags::MAPMODE);
     911           0 :         rRenderContext.SetLineColor(Color(COL_WHITE));
     912           0 :         rRenderContext.SetMapMode(MapMode(MAP_PIXEL));
     913           0 :         Size aSize = GetSizePixel();
     914           0 :         rRenderContext.DrawLine(Point(0, aSize.Height() - 1),
     915           0 :                                 Point(aSize.Width() - 1, aSize.Height() - 1));
     916           0 :         rRenderContext.Pop();
     917             :     }
     918             : }
     919             : 
     920        6436 : void MenuBarWindow::Resize()
     921             : {
     922        6436 :     Size aOutSz = GetOutputSizePixel();
     923        6436 :     long n      = aOutSz.Height()-4;
     924        6436 :     long nX     = aOutSz.Width()-3;
     925        6436 :     long nY     = 2;
     926             : 
     927        6436 :     if ( aCloseBtn->IsVisible() )
     928             :     {
     929        3184 :         aCloseBtn->Hide();
     930        3184 :         aCloseBtn->SetImages(n);
     931        3184 :         Size aTbxSize( aCloseBtn->CalcWindowSizePixel() );
     932        3184 :         nX -= aTbxSize.Width();
     933        3184 :         long nTbxY = (aOutSz.Height() - aTbxSize.Height())/2;
     934        3184 :         aCloseBtn->setPosSizePixel(nX, nTbxY, aTbxSize.Width(), aTbxSize.Height());
     935        3184 :         nX -= 3;
     936        3184 :         aCloseBtn->Show();
     937             :     }
     938        6436 :     if ( aFloatBtn->IsVisible() )
     939             :     {
     940           0 :         nX -= n;
     941           0 :         aFloatBtn->setPosSizePixel( nX, nY, n, n );
     942             :     }
     943        6436 :     if ( aHideBtn->IsVisible() )
     944             :     {
     945           0 :         nX -= n;
     946           0 :         aHideBtn->setPosSizePixel( nX, nY, n, n );
     947             :     }
     948             : 
     949        6436 :     aFloatBtn->SetSymbol( SymbolType::FLOAT );
     950        6436 :     aHideBtn->SetSymbol( SymbolType::HIDE );
     951             : 
     952        6436 :     Invalidate();
     953        6436 : }
     954             : 
     955           0 : sal_uInt16 MenuBarWindow::ImplFindEntry( const Point& rMousePos ) const
     956             : {
     957           0 :     if( pMenu )
     958             :     {
     959           0 :         long nX = 0;
     960           0 :         size_t nCount = pMenu->pItemList->size();
     961           0 :         for ( size_t n = 0; n < nCount; n++ )
     962             :         {
     963           0 :             MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
     964           0 :             if ( pMenu->ImplIsVisible( n ) )
     965             :             {
     966           0 :                 nX += pData->aSz.Width();
     967           0 :                 if ( nX > rMousePos.X() )
     968           0 :                     return (sal_uInt16)n;
     969             :             }
     970             :         }
     971             :     }
     972           0 :     return ITEMPOS_INVALID;
     973             : }
     974             : 
     975           0 : void MenuBarWindow::RequestHelp( const HelpEvent& rHEvt )
     976             : {
     977           0 :     sal_uInt16 nId = nHighlightedItem;
     978           0 :     if ( rHEvt.GetMode() & (HelpEventMode::CONTEXT | HelpEventMode::EXTENDED) )
     979           0 :         ChangeHighlightItem( ITEMPOS_INVALID, true );
     980             : 
     981           0 :     Rectangle aHighlightRect( ImplGetItemRect( nHighlightedItem ) );
     982           0 :     if( !ImplHandleHelpEvent( this, pMenu, nId, rHEvt, aHighlightRect ) )
     983           0 :         Window::RequestHelp( rHEvt );
     984           0 : }
     985             : 
     986        7721 : void MenuBarWindow::StateChanged( StateChangedType nType )
     987             : {
     988        7721 :     Window::StateChanged( nType );
     989             : 
     990        7721 :     if (nType == StateChangedType::ControlForeground ||
     991             :         nType == StateChangedType::ControlBackground)
     992             :     {
     993           0 :         ApplySettings(*this);
     994           0 :         Invalidate();
     995             :     }
     996        7721 :     else if(pMenu)
     997             :     {
     998        7721 :         pMenu->ImplKillLayoutData();
     999             :     }
    1000        7721 : }
    1001             : 
    1002           0 : void MenuBarWindow::LayoutChanged()
    1003             : {
    1004           0 :     if (!pMenu)
    1005           0 :         return;
    1006             : 
    1007           0 :     ApplySettings(*this);
    1008             : 
    1009             :     // if the font was changed.
    1010           0 :     long nHeight = pMenu->ImplCalcSize(this).Height();
    1011             : 
    1012             :     // depending on the native implementation or the displayable flag
    1013             :     // the menubar windows is suppressed (ie, height=0)
    1014           0 :     if (!static_cast<MenuBar*>(pMenu)->IsDisplayable() ||
    1015           0 :         (pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar()))
    1016             :     {
    1017           0 :         nHeight = 0;
    1018             :     }
    1019           0 :     setPosSizePixel(0, 0, 0, nHeight, PosSizeFlags::Height);
    1020           0 :     GetParent()->Resize();
    1021           0 :     Invalidate();
    1022           0 :     Resize();
    1023             : 
    1024           0 :     pMenu->ImplKillLayoutData();
    1025             : }
    1026             : 
    1027        1207 : void MenuBarWindow::ApplySettings(vcl::RenderContext& rRenderContext)
    1028             : {
    1029        1207 :     Window::ApplySettings(rRenderContext);
    1030        1207 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
    1031             : 
    1032        1207 :     SetPointFont(rRenderContext, rStyleSettings.GetMenuFont());
    1033             : 
    1034        1207 :     const BitmapEx& rPersonaBitmap = Application::GetSettings().GetStyleSettings().GetPersonaHeader();
    1035        1207 :     if (!rPersonaBitmap.IsEmpty())
    1036             :     {
    1037           0 :         Wallpaper aWallpaper(rPersonaBitmap);
    1038           0 :         aWallpaper.SetStyle(WALLPAPER_TOPRIGHT);
    1039           0 :         aWallpaper.SetColor(Application::GetSettings().GetStyleSettings().GetWorkspaceColor());
    1040             : 
    1041           0 :         rRenderContext.SetBackground(aWallpaper);
    1042           0 :         SetPaintTransparent(false);
    1043           0 :         SetParentClipMode(ParentClipMode::NONE);
    1044             :     }
    1045        1207 :     else if (rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
    1046             :     {
    1047           0 :         rRenderContext.SetBackground(); // background will be drawn by NWF
    1048             :     }
    1049             :     else
    1050             :     {
    1051        1207 :         Wallpaper aWallpaper;
    1052        1207 :         aWallpaper.SetStyle(WALLPAPER_APPLICATIONGRADIENT);
    1053        1207 :         rRenderContext.SetBackground(aWallpaper);
    1054        1207 :         SetPaintTransparent(false);
    1055        1207 :         SetParentClipMode(ParentClipMode::NONE);
    1056             :     }
    1057             : 
    1058        1207 :     rRenderContext.SetTextColor(rStyleSettings.GetMenuBarTextColor());
    1059        1207 :     rRenderContext.SetTextFillColor();
    1060        1207 :     rRenderContext.SetLineColor();
    1061        1207 : }
    1062             : 
    1063        3199 : void MenuBarWindow::ImplInitStyleSettings()
    1064             : {
    1065        3201 :     if (IsNativeControlSupported(CTRL_MENUBAR, PART_MENU_ITEM) &&
    1066           2 :         IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
    1067             :     {
    1068           2 :         AllSettings aSettings(GetSettings());
    1069           2 :         ImplGetFrame()->UpdateSettings(aSettings); // to update persona
    1070           4 :         StyleSettings aStyle(aSettings.GetStyleSettings());
    1071           2 :         Color aHighlightTextColor = ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor;
    1072           2 :         if (aHighlightTextColor != Color(COL_TRANSPARENT))
    1073             :         {
    1074           0 :             aStyle.SetMenuHighlightTextColor(aHighlightTextColor);
    1075             :         }
    1076           2 :         aSettings.SetStyleSettings(aStyle);
    1077           4 :         OutputDevice::SetSettings(aSettings);
    1078             :     }
    1079        3199 : }
    1080             : 
    1081           3 : void MenuBarWindow::DataChanged( const DataChangedEvent& rDCEvt )
    1082             : {
    1083           3 :     Window::DataChanged( rDCEvt );
    1084             : 
    1085          12 :     if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
    1086           9 :          (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
    1087           9 :          ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
    1088          12 :           (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
    1089             :     {
    1090           0 :         ApplySettings(*this);
    1091           0 :         ImplInitStyleSettings();
    1092           0 :         LayoutChanged();
    1093             :     }
    1094           3 : }
    1095             : 
    1096           8 : void MenuBarWindow::LoseFocus()
    1097             : {
    1098           8 :     if ( !HasChildPathFocus( true ) )
    1099           8 :         ChangeHighlightItem( ITEMPOS_INVALID, false, false );
    1100           8 : }
    1101             : 
    1102           8 : void MenuBarWindow::GetFocus()
    1103             : {
    1104           8 :     if ( nHighlightedItem == ITEMPOS_INVALID )
    1105             :     {
    1106           2 :         mbAutoPopup = false;    // do not open menu when activated by focus handling like taskpane cycling
    1107           2 :         ChangeHighlightItem( 0, false );
    1108             :     }
    1109           8 : }
    1110             : 
    1111          10 : css::uno::Reference<css::accessibility::XAccessible> MenuBarWindow::CreateAccessible()
    1112             : {
    1113          10 :     css::uno::Reference<css::accessibility::XAccessible> xAcc;
    1114             : 
    1115          10 :     if (pMenu)
    1116          10 :         xAcc = pMenu->GetAccessible();
    1117             : 
    1118          10 :     return xAcc;
    1119             : }
    1120             : 
    1121           0 : sal_uInt16 MenuBarWindow::AddMenuBarButton( const Image& i_rImage, const Link<>& i_rLink, const OUString& i_rToolTip, sal_uInt16 i_nPos )
    1122             : {
    1123             :     // find first free button id
    1124           0 :     sal_uInt16 nId = IID_DOCUMENTCLOSE;
    1125           0 :     std::map< sal_uInt16, AddButtonEntry >::const_iterator it;
    1126           0 :     if( i_nPos > m_aAddButtons.size() )
    1127           0 :         i_nPos = static_cast<sal_uInt16>(m_aAddButtons.size());
    1128           0 :     do
    1129             :     {
    1130           0 :         nId++;
    1131           0 :         it = m_aAddButtons.find( nId );
    1132           0 :     } while( it != m_aAddButtons.end() && nId < 128 );
    1133             :     DBG_ASSERT( nId < 128, "too many addbuttons in menubar" );
    1134           0 :     AddButtonEntry& rNewEntry = m_aAddButtons[nId];
    1135           0 :     rNewEntry.m_nId = nId;
    1136           0 :     rNewEntry.m_aSelectLink = i_rLink;
    1137           0 :     aCloseBtn->InsertItem(nId, i_rImage, ToolBoxItemBits::NONE, 0);
    1138           0 :     aCloseBtn->calcMinSize();
    1139           0 :     ShowButtons(aCloseBtn->IsItemVisible(IID_DOCUMENTCLOSE), aFloatBtn->IsVisible(), aHideBtn->IsVisible());
    1140           0 :     LayoutChanged();
    1141             : 
    1142           0 :     if( pMenu->mpSalMenu )
    1143           0 :         pMenu->mpSalMenu->AddMenuBarButton( SalMenuButtonItem( nId, i_rImage, i_rToolTip ) );
    1144             : 
    1145           0 :     return nId;
    1146             : }
    1147             : 
    1148           0 : void MenuBarWindow::SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link<>& rLink )
    1149             : {
    1150           0 :     std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( nId );
    1151           0 :     if( it != m_aAddButtons.end() )
    1152           0 :         it->second.m_aHighlightLink = rLink;
    1153           0 : }
    1154             : 
    1155           0 : Rectangle MenuBarWindow::GetMenuBarButtonRectPixel( sal_uInt16 nId )
    1156             : {
    1157           0 :     Rectangle aRect;
    1158           0 :     if( m_aAddButtons.find( nId ) != m_aAddButtons.end() )
    1159             :     {
    1160           0 :         if( pMenu->mpSalMenu )
    1161             :         {
    1162           0 :             aRect = pMenu->mpSalMenu->GetMenuBarButtonRectPixel( nId, ImplGetWindowImpl()->mpFrame );
    1163           0 :             if( aRect == Rectangle( Point( -1, -1 ), Size( 1, 1 ) ) )
    1164             :             {
    1165             :                 // system menu button is somewhere but location cannot be determined
    1166           0 :                 return Rectangle();
    1167             :             }
    1168             :         }
    1169             : 
    1170           0 :         if( aRect.IsEmpty() )
    1171             :         {
    1172           0 :             aRect = aCloseBtn->GetItemRect(nId);
    1173           0 :             Point aOffset = aCloseBtn->OutputToScreenPixel(Point());
    1174           0 :             aRect.Move( aOffset.X(), aOffset.Y() );
    1175             :         }
    1176             :     }
    1177           0 :     return aRect;
    1178             : }
    1179             : 
    1180           0 : void MenuBarWindow::RemoveMenuBarButton( sal_uInt16 nId )
    1181             : {
    1182           0 :     sal_uInt16 nPos = aCloseBtn->GetItemPos(nId);
    1183           0 :     aCloseBtn->RemoveItem(nPos);
    1184           0 :     m_aAddButtons.erase( nId );
    1185           0 :     aCloseBtn->calcMinSize();
    1186           0 :     LayoutChanged();
    1187             : 
    1188           0 :     if( pMenu->mpSalMenu )
    1189           0 :         pMenu->mpSalMenu->RemoveMenuBarButton( nId );
    1190           0 : }
    1191             : 
    1192           0 : bool MenuBarWindow::HandleMenuButtonEvent( sal_uInt16 i_nButtonId )
    1193             : {
    1194           0 :     std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( i_nButtonId );
    1195           0 :     if( it != m_aAddButtons.end() )
    1196             :     {
    1197             :         MenuBar::MenuBarButtonCallbackArg aArg;
    1198           0 :         aArg.nId = it->first;
    1199           0 :         aArg.bHighlight = true;
    1200           0 :         aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
    1201           0 :         return it->second.m_aSelectLink.Call( &aArg );
    1202             :     }
    1203           0 :     return false;
    1204             : }
    1205             : 
    1206             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11