LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/window - menu.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 551 3114 17.7 %
Date: 2012-12-27 Functions: 73 274 26.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             : 
      21             : #include "tools/debug.hxx"
      22             : #include "tools/diagnose_ex.h"
      23             : #include "tools/rc.h"
      24             : #include "tools/stream.hxx"
      25             : 
      26             : #include "vcl/svapp.hxx"
      27             : #include "vcl/mnemonic.hxx"
      28             : #include "vcl/image.hxx"
      29             : #include "vcl/event.hxx"
      30             : #include "vcl/help.hxx"
      31             : #include "vcl/floatwin.hxx"
      32             : #include "vcl/wrkwin.hxx"
      33             : #include "vcl/timer.hxx"
      34             : #include "vcl/decoview.hxx"
      35             : #include "vcl/bitmap.hxx"
      36             : #include "vcl/menu.hxx"
      37             : #include "vcl/button.hxx"
      38             : #include "vcl/gradient.hxx"
      39             : #include "vcl/i18nhelp.hxx"
      40             : #include "vcl/taskpanelist.hxx"
      41             : #include "vcl/controllayout.hxx"
      42             : #include "vcl/toolbox.hxx"
      43             : #include "vcl/dockingarea.hxx"
      44             : 
      45             : #include "salinst.hxx"
      46             : #include "svdata.hxx"
      47             : #include "svids.hrc"
      48             : #include "window.h"
      49             : #include "salmenu.hxx"
      50             : #include "salframe.hxx"
      51             : 
      52             : 
      53             : #include <com/sun/star/uno/Reference.h>
      54             : #include <com/sun/star/i18n/XCharacterClassification.hpp>
      55             : #include <com/sun/star/lang/XComponent.hpp>
      56             : #include <com/sun/star/accessibility/XAccessible.hpp>
      57             : #include <com/sun/star/accessibility/AccessibleRole.hpp>
      58             : #include <vcl/unowrap.hxx>
      59             : 
      60             : #include <vcl/unohelp.hxx>
      61             : #include <vcl/configsettings.hxx>
      62             : 
      63             : #include "vcl/lazydelete.hxx"
      64             : 
      65             : #include <map>
      66             : #include <vector>
      67             : 
      68             : namespace vcl
      69             : {
      70             : 
      71           0 : struct MenuLayoutData : public ControlLayoutData
      72             : {
      73             :     std::vector< sal_uInt16 >               m_aLineItemIds;
      74             :     std::vector< sal_uInt16 >               m_aLineItemPositions;
      75             :     std::map< sal_uInt16, Rectangle >       m_aVisibleItemBoundRects;
      76             : };
      77             : 
      78             : }
      79             : 
      80             : using namespace ::com::sun::star;
      81             : using namespace vcl;
      82             : 
      83             : DBG_NAME( Menu )
      84             : 
      85             : #define ITEMPOS_INVALID     0xFFFF
      86             : 
      87             : #define EXTRASPACEY         2
      88             : #define EXTRAITEMHEIGHT     4
      89             : #define GUTTERBORDER        8
      90             : 
      91             : // document closer
      92             : #define IID_DOCUMENTCLOSE 1
      93             : 
      94           0 : static sal_Bool ImplAccelDisabled()
      95             : {
      96             :     // display of accelerator strings may be suppressed via configuration
      97             :     static int nAccelDisabled = -1;
      98             : 
      99           0 :     if( nAccelDisabled == -1 )
     100             :     {
     101             :         rtl::OUString aStr =
     102             :             vcl::SettingsConfigItem::get()->
     103             :             getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Menu" ) ),
     104           0 :                         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuppressAccelerators" ) ) );
     105           0 :         nAccelDisabled = aStr.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("true")) ? 1 : 0;
     106             :     }
     107           0 :     return (nAccelDisabled == 1) ? sal_True : sal_False;
     108             : }
     109             : 
     110             : struct MenuItemData
     111             : {
     112             :     sal_uInt16          nId;                    // SV Id
     113             :     MenuItemType    eType;                  // MenuItem-Type
     114             :     MenuItemBits    nBits;                  // MenuItem-Bits
     115             :     Menu*           pSubMenu;               // Pointer to SubMenu
     116             :     Menu*           pAutoSubMenu;           // Pointer to SubMenu from Resource
     117             :     XubString       aText;                  // Menu-Text
     118             :     XubString       aHelpText;              // Help-String
     119             :     XubString       aTipHelpText;           // TipHelp-String (eg, expanded filenames)
     120             :     XubString       aCommandStr;            // CommandString
     121             :     XubString       aHelpCommandStr;        // Help command string (to reference external help)
     122             :     rtl::OString    aHelpId;                // Help-Id
     123             :     sal_uLong           nUserValue;             // User value
     124             :     Image           aImage;                 // Image
     125             :     KeyCode         aAccelKey;              // Accelerator-Key
     126             :     sal_Bool            bChecked;               // Checked
     127             :     sal_Bool            bEnabled;               // Enabled
     128             :     sal_Bool            bVisible;               // Visible (note: this flag will not override MENU_FLAG_HIDEDISABLEDENTRIES when true)
     129             :     sal_Bool            bIsTemporary;           // Temporary inserted ('No selection possible')
     130             :     sal_Bool            bMirrorMode;
     131             :     long            nItemImageAngle;
     132             :     Size            aSz;                    // only temporarily valid
     133             :     XubString       aAccessibleName;        // accessible name
     134             :     XubString       aAccessibleDescription; // accessible description
     135             : 
     136             :     SalMenuItem*    pSalMenuItem;           // access to native menu
     137             : 
     138           6 :                     MenuItemData() :
     139           6 :                         pSalMenuItem ( NULL )
     140           6 :                     {}
     141          50 :                     MenuItemData( const XubString& rStr, const Image& rImage ) :
     142             :                         aText( rStr ),
     143             :                         aImage( rImage ),
     144          50 :                         pSalMenuItem ( NULL )
     145          50 :                     {}
     146             :                     ~MenuItemData();
     147           0 :         bool HasCheck() const
     148             :         {
     149           0 :             return bChecked || ( nBits & ( MIB_RADIOCHECK | MIB_CHECKABLE | MIB_AUTOCHECK ) );
     150             :         }
     151             : };
     152             : 
     153          34 : MenuItemData::~MenuItemData()
     154             : {
     155          17 :     if( pAutoSubMenu )
     156             :     {
     157           0 :         ((PopupMenu*)pAutoSubMenu)->pRefAutoSubMenu = NULL;
     158           0 :         delete pAutoSubMenu;
     159           0 :         pAutoSubMenu = NULL;
     160             :     }
     161          17 :     if( pSalMenuItem )
     162           0 :         ImplGetSVData()->mpDefInst->DestroyMenuItem( pSalMenuItem );
     163          17 : }
     164             : 
     165             : class MenuItemList
     166             : {
     167             : private:
     168             :     typedef ::std::vector< MenuItemData* > MenuItemDataList_impl;
     169             :     MenuItemDataList_impl maItemList;
     170             : 
     171             :     uno::Reference< i18n::XCharacterClassification > xCharClass;
     172             : 
     173             : public:
     174        1458 :                     MenuItemList() {}
     175             :                     ~MenuItemList();
     176             : 
     177             :     MenuItemData*   Insert(
     178             :                         sal_uInt16 nId,
     179             :                         MenuItemType eType,
     180             :                         MenuItemBits nBits,
     181             :                         const XubString& rStr,
     182             :                         const Image& rImage,
     183             :                         Menu* pMenu,
     184             :                         size_t nPos
     185             :                     );
     186             :     void            InsertSeparator( size_t nPos );
     187             :     void            Remove( size_t nPos );
     188             : 
     189             : 
     190             :     MenuItemData*   GetData( sal_uInt16 nSVId, size_t& rPos ) const;
     191         526 :     MenuItemData*   GetData( sal_uInt16 nSVId ) const
     192             :                     {
     193             :                         size_t nTemp;
     194         526 :                         return GetData( nSVId, nTemp );
     195             :                     }
     196           6 :     MenuItemData*   GetDataFromPos( size_t nPos ) const
     197             :                     {
     198           6 :                         return ( nPos < maItemList.size() ) ? maItemList[ nPos ] : NULL;
     199             :                     }
     200             : 
     201             :     MenuItemData*   SearchItem(
     202             :                         sal_Unicode cSelectChar,
     203             :                         KeyCode aKeyCode,
     204             :                         sal_uInt16& rPos,
     205             :                         sal_uInt16& nDuplicates,
     206             :                         sal_uInt16 nCurrentPos
     207             :                     ) const;
     208             :     size_t          GetItemCount( sal_Unicode cSelectChar ) const;
     209             :     size_t          GetItemCount( KeyCode aKeyCode ) const;
     210        1609 :     size_t          size()
     211             :                     {
     212        1609 :                         return maItemList.size();
     213             :                     }
     214             : };
     215             : 
     216             : 
     217             : 
     218        1112 : MenuItemList::~MenuItemList()
     219             : {
     220         573 :     for( size_t i = 0, n = maItemList.size(); i < n; ++i )
     221          17 :         delete maItemList[ i ];
     222         556 : }
     223             : 
     224          50 : MenuItemData* MenuItemList::Insert(
     225             :     sal_uInt16 nId,
     226             :     MenuItemType eType,
     227             :     MenuItemBits nBits,
     228             :     const XubString& rStr,
     229             :     const Image& rImage,
     230             :     Menu* pMenu,
     231             :     size_t nPos
     232             : )
     233             : {
     234          50 :     MenuItemData* pData     = new MenuItemData( rStr, rImage );
     235          50 :     pData->nId              = nId;
     236          50 :     pData->eType            = eType;
     237          50 :     pData->nBits            = nBits;
     238          50 :     pData->pSubMenu         = NULL;
     239          50 :     pData->pAutoSubMenu     = NULL;
     240          50 :     pData->nUserValue       = 0;
     241          50 :     pData->bChecked         = sal_False;
     242          50 :     pData->bEnabled         = sal_True;
     243          50 :     pData->bVisible         = sal_True;
     244          50 :     pData->bIsTemporary     = sal_False;
     245          50 :     pData->bMirrorMode      = sal_False;
     246          50 :     pData->nItemImageAngle  = 0;
     247             : 
     248          50 :     SalItemParams aSalMIData;
     249          50 :     aSalMIData.nId = nId;
     250          50 :     aSalMIData.eType = eType;
     251          50 :     aSalMIData.nBits = nBits;
     252          50 :     aSalMIData.pMenu = pMenu;
     253          50 :     aSalMIData.aText = rStr;
     254          50 :     aSalMIData.aImage = rImage;
     255             : 
     256             :     // Native-support: returns NULL if not supported
     257          50 :     pData->pSalMenuItem = ImplGetSVData()->mpDefInst->CreateMenuItem( &aSalMIData );
     258             : 
     259          50 :     if( nPos < maItemList.size() ) {
     260           0 :         maItemList.insert( maItemList.begin() + nPos, pData );
     261             :     } else {
     262          50 :         maItemList.push_back( pData );
     263             :     }
     264          50 :     return pData;
     265             : }
     266             : 
     267           6 : void MenuItemList::InsertSeparator( size_t nPos )
     268             : {
     269           6 :     MenuItemData* pData     = new MenuItemData;
     270           6 :     pData->nId              = 0;
     271           6 :     pData->eType            = MENUITEM_SEPARATOR;
     272           6 :     pData->nBits            = 0;
     273           6 :     pData->pSubMenu         = NULL;
     274           6 :     pData->pAutoSubMenu     = NULL;
     275           6 :     pData->nUserValue       = 0;
     276           6 :     pData->bChecked         = sal_False;
     277           6 :     pData->bEnabled         = sal_True;
     278           6 :     pData->bVisible         = sal_True;
     279           6 :     pData->bIsTemporary     = sal_False;
     280           6 :     pData->bMirrorMode      = sal_False;
     281           6 :     pData->nItemImageAngle  = 0;
     282             : 
     283           6 :     SalItemParams aSalMIData;
     284           6 :     aSalMIData.nId = 0;
     285           6 :     aSalMIData.eType = MENUITEM_SEPARATOR;
     286           6 :     aSalMIData.nBits = 0;
     287           6 :     aSalMIData.pMenu = NULL;
     288           6 :     aSalMIData.aText = XubString();
     289           6 :     aSalMIData.aImage = Image();
     290             : 
     291             :     // Native-support: returns NULL if not supported
     292           6 :     pData->pSalMenuItem = ImplGetSVData()->mpDefInst->CreateMenuItem( &aSalMIData );
     293             : 
     294           6 :     if( nPos < maItemList.size() ) {
     295           0 :         maItemList.insert( maItemList.begin() + nPos, pData );
     296             :     } else {
     297           6 :         maItemList.push_back( pData );
     298           6 :     }
     299           6 : }
     300             : 
     301           0 : void MenuItemList::Remove( size_t nPos )
     302             : {
     303           0 :     if( nPos < maItemList.size() )
     304             :     {
     305           0 :         delete maItemList[ nPos ];
     306           0 :         maItemList.erase( maItemList.begin() + nPos );
     307             :     }
     308           0 : }
     309             : 
     310         538 : MenuItemData* MenuItemList::GetData( sal_uInt16 nSVId, size_t& rPos ) const
     311             : {
     312         708 :     for( size_t i = 0, n = maItemList.size(); i < n; ++i )
     313             :     {
     314         282 :         if ( maItemList[ i ]->nId == nSVId )
     315             :         {
     316         112 :             rPos = i;
     317         112 :             return maItemList[ i ];
     318             :         }
     319             :     }
     320         426 :     return NULL;
     321             : }
     322             : 
     323           0 : MenuItemData* MenuItemList::SearchItem(
     324             :     sal_Unicode cSelectChar,
     325             :     KeyCode aKeyCode,
     326             :     sal_uInt16& rPos,
     327             :     sal_uInt16& nDuplicates,
     328             :     sal_uInt16 nCurrentPos
     329             : ) const
     330             : {
     331           0 :     const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
     332             : 
     333           0 :     size_t nListCount = maItemList.size();
     334             : 
     335             :     // try character code first
     336           0 :     nDuplicates = GetItemCount( cSelectChar );  // return number of duplicates
     337           0 :     if( nDuplicates )
     338             :     {
     339           0 :         for ( rPos = 0; rPos < nListCount; rPos++)
     340             :         {
     341           0 :             MenuItemData* pData = maItemList[ rPos ];
     342           0 :             if ( pData->bEnabled && rI18nHelper.MatchMnemonic( pData->aText, cSelectChar ) )
     343             :             {
     344           0 :                 if( nDuplicates > 1 && rPos == nCurrentPos )
     345           0 :                     continue;   // select next entry with the same mnemonic
     346             :                 else
     347           0 :                     return pData;
     348             :             }
     349             :         }
     350             :     }
     351             : 
     352             :     // nothing found, try keycode instead
     353           0 :     nDuplicates = GetItemCount( aKeyCode ); // return number of duplicates
     354             : 
     355           0 :     if( nDuplicates )
     356             :     {
     357           0 :         char ascii = 0;
     358           0 :         if( aKeyCode.GetCode() >= KEY_A && aKeyCode.GetCode() <= KEY_Z )
     359           0 :             ascii = sal::static_int_cast<char>('A' + (aKeyCode.GetCode() - KEY_A));
     360             : 
     361           0 :         for ( rPos = 0; rPos < nListCount; rPos++)
     362             :         {
     363           0 :             MenuItemData* pData = maItemList[ rPos ];
     364           0 :             if ( pData->bEnabled )
     365             :             {
     366           0 :                 sal_uInt16 n = pData->aText.Search( '~' );
     367           0 :                 if ( n != STRING_NOTFOUND )
     368             :                 {
     369           0 :                     KeyCode mnKeyCode;
     370           0 :                     sal_Unicode mnUnicode = pData->aText.GetChar(n+1);
     371           0 :                     Window* pDefWindow = ImplGetDefaultWindow();
     372           0 :                     if(  (  pDefWindow
     373           0 :                          && pDefWindow->ImplGetFrame()->MapUnicodeToKeyCode( mnUnicode,
     374           0 :                              Application::GetSettings().GetUILanguageTag().getLanguageType(), mnKeyCode )
     375           0 :                          && aKeyCode.GetCode() == mnKeyCode.GetCode()
     376             :                          )
     377             :                       || (  ascii
     378           0 :                          && rI18nHelper.MatchMnemonic( pData->aText, ascii )
     379             :                          )
     380             :                       )
     381             :                     {
     382           0 :                         if( nDuplicates > 1 && rPos == nCurrentPos )
     383           0 :                             continue;   // select next entry with the same mnemonic
     384             :                         else
     385           0 :                             return pData;
     386             :                     }
     387             :                 }
     388             :             }
     389             :         }
     390             :     }
     391             : 
     392           0 :     return NULL;
     393             : }
     394             : 
     395           0 : size_t MenuItemList::GetItemCount( sal_Unicode cSelectChar ) const
     396             : {
     397             :     // returns number of entries with same mnemonic
     398           0 :     const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
     399             : 
     400           0 :     size_t nItems = 0;
     401           0 :     for ( size_t nPos = maItemList.size(); nPos; )
     402             :     {
     403           0 :         MenuItemData* pData = maItemList[ --nPos ];
     404           0 :         if ( pData->bEnabled && rI18nHelper.MatchMnemonic( pData->aText, cSelectChar ) )
     405           0 :             nItems++;
     406             :     }
     407             : 
     408           0 :     return nItems;
     409             : }
     410             : 
     411           0 : size_t MenuItemList::GetItemCount( KeyCode aKeyCode ) const
     412             : {
     413             :     // returns number of entries with same mnemonic
     414             :     // uses key codes instead of character codes
     415           0 :     const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
     416           0 :     char ascii = 0;
     417           0 :     if( aKeyCode.GetCode() >= KEY_A && aKeyCode.GetCode() <= KEY_Z )
     418           0 :         ascii = sal::static_int_cast<char>('A' + (aKeyCode.GetCode() - KEY_A));
     419             : 
     420           0 :     size_t nItems = 0;
     421           0 :     for ( size_t nPos = maItemList.size(); nPos; )
     422             :     {
     423           0 :         MenuItemData* pData = maItemList[ --nPos ];
     424           0 :         if ( pData->bEnabled )
     425             :         {
     426           0 :             sal_uInt16 n = pData->aText.Search( '~' );
     427           0 :             if ( n != STRING_NOTFOUND )
     428             :             {
     429           0 :                 KeyCode mnKeyCode;
     430             :                 // if MapUnicodeToKeyCode fails or is unsupported we try the pure ascii mapping of the keycodes
     431             :                 // so we have working shortcuts when ascii mnemonics are used
     432           0 :                 Window* pDefWindow = ImplGetDefaultWindow();
     433           0 :                 if(  (  pDefWindow
     434           0 :                      && pDefWindow->ImplGetFrame()->MapUnicodeToKeyCode( pData->aText.GetChar(n+1),
     435           0 :                          Application::GetSettings().GetUILanguageTag().getLanguageType(), mnKeyCode )
     436           0 :                      && aKeyCode.GetCode() == mnKeyCode.GetCode()
     437             :                      )
     438             :                   || (  ascii
     439           0 :                      && rI18nHelper.MatchMnemonic( pData->aText, ascii )
     440             :                      )
     441             :                   )
     442           0 :                     nItems++;
     443             :             }
     444             :         }
     445             :     }
     446             : 
     447           0 :     return nItems;
     448             : }
     449             : 
     450             : 
     451             : // ----------------------
     452             : // - MenuFloatingWindow -
     453             : // ----------------------
     454             : 
     455             : class MenuFloatingWindow : public FloatingWindow
     456             : {
     457             :     friend void Menu::ImplFillLayoutData() const;
     458             :     friend Menu::~Menu();
     459             : 
     460             : private:
     461             :     Menu*           pMenu;
     462             :     PopupMenu*      pActivePopup;
     463             :     Timer           aHighlightChangedTimer;
     464             :     Timer           aSubmenuCloseTimer;
     465             :     Timer           aScrollTimer;
     466             :     sal_uLong           nSaveFocusId;
     467             :     sal_uInt16          nHighlightedItem;       // highlighted/selected Item
     468             :     sal_uInt16          nMBDownPos;
     469             :     sal_uInt16          nScrollerHeight;
     470             :     sal_uInt16          nFirstEntry;
     471             :     sal_uInt16          nBorder;
     472             :     sal_uInt16          nPosInParent;
     473             :     sal_Bool            bInExecute;
     474             : 
     475             :     sal_Bool            bScrollMenu;
     476             :     sal_Bool            bScrollUp;
     477             :     sal_Bool            bScrollDown;
     478             :     sal_Bool            bIgnoreFirstMove;
     479             :     sal_Bool            bKeyInput;
     480             : 
     481             :                     DECL_LINK(PopupEnd, void *);
     482             :                     DECL_LINK( HighlightChanged, Timer* );
     483             :                     DECL_LINK(SubmenuClose, void *);
     484             :                     DECL_LINK(AutoScroll, void *);
     485             :                     DECL_LINK( ShowHideListener, VclWindowEvent* );
     486             : 
     487             :     void            StateChanged( StateChangedType nType );
     488             :     void            DataChanged( const DataChangedEvent& rDCEvt );
     489             : protected:
     490             :     Region          ImplCalcClipRegion( sal_Bool bIncludeLogo = sal_True ) const;
     491             :     void            ImplInitClipRegion();
     492             :     void            ImplDrawScroller( sal_Bool bUp );
     493             :     using Window::ImplScroll;
     494             :     void            ImplScroll( const Point& rMousePos );
     495             :     void            ImplScroll( sal_Bool bUp );
     496             :     void            ImplCursorUpDown( sal_Bool bUp, sal_Bool bHomeEnd = sal_False );
     497             :     void            ImplHighlightItem( const MouseEvent& rMEvt, sal_Bool bMBDown );
     498             :     long            ImplGetStartY() const;
     499             :     Rectangle       ImplGetItemRect( sal_uInt16 nPos );
     500             : 
     501             : public:
     502             :                     MenuFloatingWindow( Menu* pMenu, Window* pParent, WinBits nStyle );
     503             :                     ~MenuFloatingWindow();
     504             : 
     505             :             void    doShutdown();
     506             : 
     507             :     virtual void    MouseMove( const MouseEvent& rMEvt );
     508             :     virtual void    MouseButtonDown( const MouseEvent& rMEvt );
     509             :     virtual void    MouseButtonUp( const MouseEvent& rMEvt );
     510             :     virtual void    KeyInput( const KeyEvent& rKEvent );
     511             :     virtual void    Command( const CommandEvent& rCEvt );
     512             :     virtual void    Paint( const Rectangle& rRect );
     513             :     virtual void    RequestHelp( const HelpEvent& rHEvt );
     514             :     virtual void    Resize();
     515             : 
     516           0 :     void            SetFocusId( sal_uLong nId ) { nSaveFocusId = nId; }
     517           0 :     sal_uLong           GetFocusId() const      { return nSaveFocusId; }
     518             : 
     519             :     void            EnableScrollMenu( sal_Bool b );
     520           0 :     sal_Bool            IsScrollMenu() const        { return bScrollMenu; }
     521           0 :     sal_uInt16          GetScrollerHeight() const   { return nScrollerHeight; }
     522             : 
     523             :     void            Execute();
     524             :     void            StopExecute( sal_uLong nFocusId = 0 );
     525             :     void            EndExecute();
     526             :     void            EndExecute( sal_uInt16 nSelectId );
     527             : 
     528           0 :     PopupMenu*      GetActivePopup() const  { return pActivePopup; }
     529             :     void            KillActivePopup( PopupMenu* pThisOnly = NULL );
     530             : 
     531             :     void            HighlightItem( sal_uInt16 nPos, sal_Bool bHighlight );
     532             :     void            ChangeHighlightItem( sal_uInt16 n, sal_Bool bStartPopupTimer );
     533           0 :     sal_uInt16          GetHighlightedItem() const { return nHighlightedItem; }
     534             : 
     535           0 :     void            SetPosInParent( sal_uInt16 nPos ) { nPosInParent = nPos; }
     536             :     sal_uInt16          GetPosInParent() const { return nPosInParent; }
     537             : 
     538             :     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
     539             : };
     540             : 
     541             : // To get the transparent mouse-over look, the closer is actually a toolbox
     542             : // overload DataChange to handle style changes correctly
     543          63 : class DecoToolBox : public ToolBox
     544             : {
     545             :     long lastSize;
     546             :     Size maMinSize;
     547             : 
     548             :     using Window::ImplInit;
     549             : public:
     550             :             DecoToolBox( Window* pParent, WinBits nStyle = 0 );
     551             :     void    ImplInit();
     552             : 
     553             :     void    DataChanged( const DataChangedEvent& rDCEvt );
     554             : 
     555             :     void    SetImages( long nMaxHeight = 0, bool bForce = false );
     556             : 
     557             :     void    calcMinSize();
     558             :     Size    getMinSize();
     559             : 
     560             :     Image   maImage;
     561             : };
     562             : 
     563         236 : DecoToolBox::DecoToolBox( Window* pParent, WinBits nStyle ) :
     564         236 :     ToolBox( pParent, nStyle )
     565             : {
     566         236 :     ImplInit();
     567         236 : }
     568             : 
     569         236 : void DecoToolBox::ImplInit()
     570             : {
     571         236 :     lastSize = -1;
     572         236 :     calcMinSize();
     573         236 : }
     574             : 
     575          92 : void DecoToolBox::DataChanged( const DataChangedEvent& rDCEvt )
     576             : {
     577          92 :     Window::DataChanged( rDCEvt );
     578             : 
     579          92 :     if ( rDCEvt.GetFlags() & SETTINGS_STYLE )
     580             :     {
     581           0 :         calcMinSize();
     582           0 :         SetBackground();
     583           0 :         SetImages( 0, true);
     584             :     }
     585          92 : }
     586             : 
     587         236 : void DecoToolBox::calcMinSize()
     588             : {
     589         236 :     ToolBox aTbx( GetParent() );
     590         236 :     if( GetItemCount() == 0 )
     591             :     {
     592         236 :         ResMgr* pResMgr = ImplGetResMgr();
     593             : 
     594         236 :         Bitmap aBitmap;
     595         236 :         if( pResMgr )
     596         236 :             aBitmap = Bitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) );
     597         236 :         aTbx.InsertItem( IID_DOCUMENTCLOSE, Image( aBitmap ) );
     598             :     }
     599             :     else
     600             :     {
     601           0 :         sal_uInt16 nItems = GetItemCount();
     602           0 :         for( sal_uInt16 i = 0; i < nItems; i++ )
     603             :         {
     604           0 :             sal_uInt16 nId = GetItemId( i );
     605           0 :             aTbx.InsertItem( nId, GetItemImage( nId ) );
     606             :         }
     607             :     }
     608         236 :     aTbx.SetOutStyle( TOOLBOX_STYLE_FLAT );
     609         236 :     maMinSize = aTbx.CalcWindowSizePixel();
     610         236 : }
     611             : 
     612         287 : Size DecoToolBox::getMinSize()
     613             : {
     614         287 :     return maMinSize;
     615             : }
     616             : 
     617          17 : void DecoToolBox::SetImages( long nMaxHeight, bool bForce )
     618             : {
     619          17 :     long border = getMinSize().Height() - maImage.GetSizePixel().Height();
     620             : 
     621          17 :     if( !nMaxHeight && lastSize != -1 )
     622           0 :         nMaxHeight = lastSize + border; // don't change anything if called with 0
     623             : 
     624          17 :     if( nMaxHeight < getMinSize().Height() )
     625          17 :         nMaxHeight = getMinSize().Height();
     626             : 
     627          17 :     if( (lastSize != nMaxHeight - border) || bForce )
     628             :     {
     629          11 :         lastSize = nMaxHeight - border;
     630             : 
     631          11 :         Color       aEraseColor( 255, 255, 255, 255 );
     632          11 :         BitmapEx    aBmpExDst( maImage.GetBitmapEx() );
     633          11 :         BitmapEx    aBmpExSrc( aBmpExDst );
     634             : 
     635          11 :         aEraseColor.SetTransparency( 255 );
     636          11 :         aBmpExDst.Erase( aEraseColor );
     637          11 :         aBmpExDst.SetSizePixel( Size( lastSize, lastSize ) );
     638             : 
     639          11 :         Rectangle aSrcRect( Point(0,0), maImage.GetSizePixel() );
     640          22 :         Rectangle aDestRect( Point((lastSize - maImage.GetSizePixel().Width())/2,
     641          22 :                                 (lastSize - maImage.GetSizePixel().Height())/2 ),
     642          44 :                             maImage.GetSizePixel() );
     643             : 
     644             : 
     645          11 :         aBmpExDst.CopyPixel( aDestRect, aSrcRect, &aBmpExSrc );
     646          11 :         SetItemImage( IID_DOCUMENTCLOSE, Image( aBmpExDst ) );
     647             :     }
     648          17 : }
     649             : 
     650             : 
     651             : // a basic class for both (due to pActivePopup, Timer,...) would be nice,
     652             : // but a container class should have been created then, as they
     653             : // would be derived from different windows
     654             : // In most functions we would have to create exceptions for
     655             : // menubar, popupmenu, hence we made two classes
     656             : 
     657             : class MenuBarWindow : public Window
     658             : {
     659             :     friend class MenuBar;
     660             :     friend class Menu;
     661             : 
     662             : private:
     663             :     struct AddButtonEntry
     664             :     {
     665             :         sal_uInt16      m_nId;
     666             :         Link        m_aSelectLink;
     667             :         Link        m_aHighlightLink;
     668             : 
     669           0 :         AddButtonEntry() : m_nId( 0 ) {}
     670             :     };
     671             : 
     672             :     Menu*           pMenu;
     673             :     PopupMenu*      pActivePopup;
     674             :     sal_uInt16          nHighlightedItem;
     675             :     sal_uLong           nSaveFocusId;
     676             :     sal_Bool            mbAutoPopup;
     677             :     sal_Bool            bIgnoreFirstMove;
     678             :     sal_Bool            bStayActive;
     679             : 
     680             :     DecoToolBox     aCloser;
     681             :     PushButton      aFloatBtn;
     682             :     PushButton      aHideBtn;
     683             : 
     684             :     std::map< sal_uInt16, AddButtonEntry > m_aAddButtons;
     685             : 
     686             :     void            HighlightItem( sal_uInt16 nPos, sal_Bool bHighlight );
     687             :     void            ChangeHighlightItem( sal_uInt16 n, sal_Bool bSelectPopupEntry, sal_Bool bAllowRestoreFocus = sal_True, sal_Bool bDefaultToDocument = sal_True );
     688             : 
     689             :     sal_uInt16          ImplFindEntry( const Point& rMousePos ) const;
     690             :     void            ImplCreatePopup( sal_Bool bPreSelectFirst );
     691             :     sal_Bool            ImplHandleKeyEvent( const KeyEvent& rKEvent, sal_Bool bFromMenu = sal_True );
     692             :     Rectangle       ImplGetItemRect( sal_uInt16 nPos );
     693             : 
     694             :     void            ImplInitStyleSettings();
     695             : 
     696             :                     DECL_LINK(CloserHdl, void *);
     697             :                     DECL_LINK(FloatHdl, void *);
     698             :                     DECL_LINK(HideHdl, void *);
     699             :                     DECL_LINK( ToolboxEventHdl, VclWindowEvent* );
     700             :                     DECL_LINK( ShowHideListener, VclWindowEvent* );
     701             : 
     702             :     void            StateChanged( StateChangedType nType );
     703             :     void            DataChanged( const DataChangedEvent& rDCEvt );
     704             :     void            LoseFocus();
     705             :     void            GetFocus();
     706             : 
     707             : public:
     708             :                     MenuBarWindow( Window* pParent );
     709             :                     ~MenuBarWindow();
     710             : 
     711             :     void            ShowButtons( sal_Bool bClose, sal_Bool bFloat, sal_Bool bHide );
     712             : 
     713             :     virtual void    MouseMove( const MouseEvent& rMEvt );
     714             :     virtual void    MouseButtonDown( const MouseEvent& rMEvt );
     715             :     virtual void    MouseButtonUp( const MouseEvent& rMEvt );
     716             :     virtual void    KeyInput( const KeyEvent& rKEvent );
     717             :     virtual void    Paint( const Rectangle& rRect );
     718             :     virtual void    Resize();
     719             :     virtual void    RequestHelp( const HelpEvent& rHEvt );
     720             : 
     721           0 :     void            SetFocusId( sal_uLong nId ) { nSaveFocusId = nId; }
     722           0 :     sal_uLong           GetFocusId() const { return nSaveFocusId; }
     723             : 
     724             :     void            SetMenu( MenuBar* pMenu );
     725             :     void            KillActivePopup();
     726             :     PopupMenu*      GetActivePopup() const  { return pActivePopup; }
     727             :     void            PopupClosed( Menu* pMenu );
     728           0 :     sal_uInt16          GetHighlightedItem() const { return nHighlightedItem; }
     729             :     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
     730             : 
     731           0 :     void SetAutoPopup( sal_Bool bAuto ) { mbAutoPopup = bAuto; }
     732             :     void            ImplLayoutChanged();
     733             :     Size            MinCloseButtonSize();
     734             : 
     735             :     // add an arbitrary button to the menubar (will appear next to closer)
     736             :     sal_uInt16              AddMenuBarButton( const Image&, const Link&, const String&, sal_uInt16 nPos );
     737             :     void                SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link& );
     738             :     Rectangle           GetMenuBarButtonRectPixel( sal_uInt16 nId );
     739             :     void                RemoveMenuBarButton( sal_uInt16 nId );
     740             :     bool                HandleMenuButtonEvent( sal_uInt16 i_nButtonId );
     741             : };
     742             : 
     743           0 : static void ImplAddNWFSeparator( Window *pThis, const MenubarValue& rMenubarValue )
     744             : {
     745             :     // add a separator if
     746             :     // - we have an adjacent docking area
     747             :     // - and if toolbars would draw them as well (mbDockingAreaSeparateTB must not be set, see dockingarea.cxx)
     748           0 :     if( rMenubarValue.maTopDockingAreaHeight && !ImplGetSVData()->maNWFData.mbDockingAreaSeparateTB && !ImplGetSVData()->maNWFData.mbDockingAreaAvoidTBFrames )
     749             :     {
     750             :         // note: the menubar only provides the upper (dark) half of it, the rest (bright part) is drawn by the docking area
     751             : 
     752           0 :         pThis->SetLineColor( pThis->GetSettings().GetStyleSettings().GetSeparatorColor() );
     753           0 :         Point aPt;
     754           0 :         Rectangle aRect( aPt, pThis->GetOutputSizePixel() );
     755           0 :         pThis->DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
     756             :     }
     757           0 : }
     758             : 
     759           6 : static void ImplSetMenuItemData( MenuItemData* pData )
     760             : {
     761             :     // convert data
     762           6 :     if ( !pData->aImage )
     763           6 :         pData->eType = MENUITEM_STRING;
     764           0 :     else if ( !pData->aText.Len() )
     765           0 :         pData->eType = MENUITEM_IMAGE;
     766             :     else
     767           0 :         pData->eType = MENUITEM_STRINGIMAGE;
     768           6 : }
     769             : 
     770           0 : static sal_uLong ImplChangeTipTimeout( sal_uLong nTimeout, Window *pWindow )
     771             : {
     772           0 :        AllSettings aAllSettings( pWindow->GetSettings() );
     773           0 :        HelpSettings aHelpSettings( aAllSettings.GetHelpSettings() );
     774           0 :        sal_uLong nRet = aHelpSettings.GetTipTimeout();
     775           0 :        aHelpSettings.SetTipTimeout( nTimeout );
     776           0 :        aAllSettings.SetHelpSettings( aHelpSettings );
     777           0 :        pWindow->SetSettings( aAllSettings );
     778           0 :        return nRet;
     779             : }
     780             : 
     781           0 : static sal_Bool ImplHandleHelpEvent( Window* pMenuWindow, Menu* pMenu, sal_uInt16 nHighlightedItem, const HelpEvent& rHEvt, const Rectangle &rHighlightRect )
     782             : {
     783           0 :     if( ! pMenu )
     784           0 :         return sal_False;
     785             : 
     786           0 :     sal_Bool bDone = sal_False;
     787           0 :     sal_uInt16 nId = 0;
     788             : 
     789           0 :     if ( nHighlightedItem != ITEMPOS_INVALID )
     790             :     {
     791           0 :         MenuItemData* pItemData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
     792           0 :         if ( pItemData )
     793           0 :             nId = pItemData->nId;
     794             :     }
     795             : 
     796           0 :     if ( ( rHEvt.GetMode() & HELPMODE_BALLOON ) && pMenuWindow )
     797             :     {
     798           0 :         Point aPos;
     799           0 :         if( rHEvt.KeyboardActivated() )
     800           0 :             aPos = rHighlightRect.Center();
     801             :         else
     802           0 :             aPos = rHEvt.GetMousePosPixel();
     803             : 
     804           0 :         Rectangle aRect( aPos, Size() );
     805           0 :         if( pMenu->GetHelpText( nId ).Len() )
     806           0 :             Help::ShowBalloon( pMenuWindow, aPos, pMenu->GetHelpText( nId ) );
     807             :         else
     808             :         {
     809             :             // give user a chance to read the full filename
     810           0 :             sal_uLong oldTimeout=ImplChangeTipTimeout( 60000, pMenuWindow );
     811             :             // call always, even when strlen==0 to correctly remove tip
     812           0 :             Help::ShowQuickHelp( pMenuWindow, aRect, pMenu->GetTipHelpText( nId ) );
     813           0 :             ImplChangeTipTimeout( oldTimeout, pMenuWindow );
     814             :         }
     815           0 :         bDone = sal_True;
     816             :     }
     817           0 :     else if ( ( rHEvt.GetMode() & HELPMODE_QUICK ) && pMenuWindow )
     818             :     {
     819           0 :         Point aPos = rHEvt.GetMousePosPixel();
     820           0 :         Rectangle aRect( aPos, Size() );
     821             :         // give user a chance to read the full filename
     822           0 :         sal_uLong oldTimeout=ImplChangeTipTimeout( 60000, pMenuWindow );
     823             :         // call always, even when strlen==0 to correctly remove tip
     824           0 :         Help::ShowQuickHelp( pMenuWindow, aRect, pMenu->GetTipHelpText( nId ) );
     825           0 :         ImplChangeTipTimeout( oldTimeout, pMenuWindow );
     826           0 :         bDone = sal_True;
     827             :     }
     828           0 :     else if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) )
     829             :     {
     830             :         // is help in the application selected
     831           0 :         Help* pHelp = Application::GetHelp();
     832           0 :         if ( pHelp )
     833             :         {
     834             :             // is an id available, then call help with the id, otherwise
     835             :             // use help-index
     836           0 :             String aCommand = pMenu->GetItemCommand( nId );
     837           0 :             rtl::OString aHelpId(  pMenu->GetHelpId( nId ) );
     838           0 :             if( aHelpId.isEmpty() )
     839           0 :                 aHelpId = OOO_HELP_INDEX;
     840             : 
     841           0 :             if ( aCommand.Len() )
     842           0 :                 pHelp->Start( aCommand, NULL );
     843             :             else
     844           0 :                 pHelp->Start( rtl::OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), NULL );
     845             :         }
     846           0 :         bDone = sal_True;
     847             :     }
     848           0 :     return bDone;
     849             : }
     850             : 
     851           0 : static int ImplGetTopDockingAreaHeight( Window *pWindow )
     852             : {
     853             :     // find docking area that is top aligned and return its height
     854             :     // note: dockingareas are direct children of the SystemWindow
     855           0 :     if( pWindow->ImplGetFrameWindow() )
     856             :     {
     857           0 :         Window *pWin = pWindow->ImplGetFrameWindow()->GetWindow( WINDOW_FIRSTCHILD ); //mpWindowImpl->mpFirstChild;
     858           0 :         while( pWin )
     859             :         {
     860           0 :             if( pWin->IsSystemWindow() )
     861             :             {
     862           0 :                 Window *pChildWin = pWin->GetWindow( WINDOW_FIRSTCHILD ); //mpWindowImpl->mpFirstChild;
     863           0 :                 while( pChildWin )
     864             :                 {
     865           0 :                     DockingAreaWindow *pDockingArea = NULL;
     866           0 :                     if ( pChildWin->GetType() == WINDOW_DOCKINGAREA )
     867           0 :                         pDockingArea = static_cast< DockingAreaWindow* >( pChildWin );
     868             : 
     869           0 :                     if( pDockingArea && pDockingArea->GetAlign() == WINDOWALIGN_TOP &&
     870           0 :                         pDockingArea->IsVisible() && pDockingArea->GetOutputSizePixel().Height() != 0 )
     871             :                     {
     872           0 :                         return pDockingArea->GetOutputSizePixel().Height();
     873             :                     }
     874             : 
     875           0 :                     pChildWin = pChildWin->GetWindow( WINDOW_NEXT ); //mpWindowImpl->mpNext;
     876             :                 }
     877             : 
     878             :             }
     879             : 
     880           0 :             pWin = pWin->GetWindow( WINDOW_NEXT ); //mpWindowImpl->mpNext;
     881             :         }
     882             :     }
     883           0 :     return 0;
     884             : }
     885             : 
     886        1222 : Menu::Menu()
     887             : {
     888             :     DBG_CTOR( Menu, NULL );
     889        1222 :     bIsMenuBar = sal_False;
     890        1222 :     ImplInit();
     891        1222 : }
     892             : 
     893             : // this constructor makes sure we're creating the native menu
     894             : // with the correct type (ie, MenuBar vs. PopupMenu)
     895         236 : Menu::Menu( sal_Bool bMenubar )
     896             : {
     897             :     DBG_CTOR( Menu, NULL );
     898         236 :     bIsMenuBar = bMenubar;
     899         236 :     ImplInit();
     900         236 : }
     901             : 
     902        1112 : Menu::~Menu()
     903             : {
     904             :     DBG_DTOR( Menu, NULL );
     905             : 
     906         556 :     vcl::LazyDeletor<Menu>::Undelete( this );
     907             : 
     908         556 :     ImplCallEventListeners( VCLEVENT_OBJECT_DYING, ITEMPOS_INVALID );
     909             : 
     910             :     // at the window free the reference to the accessible component
     911             :     // and make sure the MenuFloatingWindow knows about our destruction
     912         556 :     if ( pWindow )
     913             :     {
     914           0 :         MenuFloatingWindow* pFloat = (MenuFloatingWindow*)pWindow;
     915           0 :         if( pFloat->pMenu == this )
     916           0 :             pFloat->pMenu = NULL;
     917           0 :         pWindow->SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >() );
     918             :     }
     919             : 
     920             :     // dispose accessible components
     921         556 :     if ( mxAccessible.is() )
     922             :     {
     923           0 :         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xComponent( mxAccessible, ::com::sun::star::uno::UNO_QUERY );
     924           0 :         if ( xComponent.is() )
     925           0 :             xComponent->dispose();
     926             :     }
     927             : 
     928         556 :     if ( nEventId )
     929           0 :         Application::RemoveUserEvent( nEventId );
     930             : 
     931             :     // Notify deletion of this menu
     932         556 :     ImplMenuDelData* pDelData = mpFirstDel;
     933        1112 :     while ( pDelData )
     934             :     {
     935           0 :         pDelData->mpMenu = NULL;
     936           0 :         pDelData = pDelData->mpNext;
     937             :     }
     938             : 
     939         556 :     bKilled = sal_True;
     940             : 
     941         556 :     delete pItemList;
     942         556 :     delete pLogo;
     943         556 :     delete mpLayoutData;
     944             : 
     945             :     // Native-support: destroy SalMenu
     946         556 :     ImplSetSalMenu( NULL );
     947         556 : }
     948             : 
     949        1458 : void Menu::ImplInit()
     950             : {
     951        1458 :     mnHighlightedItemPos = ITEMPOS_INVALID;
     952        1458 :     mpSalMenu       = NULL;
     953        1458 :     nMenuFlags      = 0;
     954        1458 :     nDefaultItem    = 0;
     955             :     //bIsMenuBar      = sal_False;  // this is now set in the ctor, must not be changed here!!!
     956        1458 :     nSelectedId     = 0;
     957        1458 :     pItemList       = new MenuItemList;
     958        1458 :     pLogo           = NULL;
     959        1458 :     pStartedFrom    = NULL;
     960        1458 :     pWindow         = NULL;
     961        1458 :     nEventId        = 0;
     962        1458 :     bCanceled       = sal_False;
     963        1458 :     bInCallback     = sal_False;
     964        1458 :     bKilled         = sal_False;
     965        1458 :     mpLayoutData    = NULL;
     966        1458 :     mpFirstDel      = NULL;         // Dtor notification list
     967             :     // Native-support: returns NULL if not supported
     968        1458 :     mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu( bIsMenuBar, this );
     969        1458 : }
     970             : 
     971          19 : void Menu::ImplLoadRes( const ResId& rResId )
     972             : {
     973          19 :     ResMgr* pMgr = rResId.GetResMgr();
     974          19 :     if( ! pMgr )
     975          19 :         return;
     976             : 
     977          19 :     rResId.SetRT( RSC_MENU );
     978          19 :     GetRes( rResId );
     979             : 
     980          19 :     sal_uLong nObjMask = ReadLongRes();
     981             : 
     982          19 :     if( nObjMask & RSC_MENU_ITEMS )
     983             :     {
     984          19 :         sal_uLong nObjFollows = ReadLongRes();
     985             :         // insert menu items
     986          75 :         for( sal_uLong i = 0; i < nObjFollows; i++ )
     987             :         {
     988          56 :             InsertItem( ResId( (RSHEADER_TYPE*)GetClassRes(), *pMgr ) );
     989          56 :             IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
     990             :         }
     991             :     }
     992             : 
     993          19 :     if( nObjMask & RSC_MENU_TEXT )
     994             :     {
     995           0 :         if( bIsMenuBar ) // no title in menubar
     996           0 :             ReadStringRes();
     997             :         else
     998           0 :             aTitleText = ReadStringRes();
     999             :     }
    1000          19 :     if( nObjMask & RSC_MENU_DEFAULTITEMID )
    1001           0 :         SetDefaultItem( sal::static_int_cast<sal_uInt16>(ReadLongRes()) );
    1002             : }
    1003             : 
    1004           0 : void Menu::CreateAutoMnemonics()
    1005             : {
    1006           0 :     MnemonicGenerator aMnemonicGenerator;
    1007             :     size_t n;
    1008           0 :     for ( n = 0; n < pItemList->size(); n++ )
    1009             :     {
    1010           0 :         MenuItemData* pData = pItemList->GetDataFromPos( n );
    1011           0 :         if ( ! (pData->nBits & MIB_NOSELECT ) )
    1012           0 :             aMnemonicGenerator.RegisterMnemonic( pData->aText );
    1013             :     }
    1014           0 :     for ( n = 0; n < pItemList->size(); n++ )
    1015             :     {
    1016           0 :         MenuItemData* pData = pItemList->GetDataFromPos( n );
    1017           0 :         if ( ! (pData->nBits & MIB_NOSELECT ) )
    1018           0 :             aMnemonicGenerator.CreateMnemonic( pData->aText );
    1019           0 :     }
    1020           0 : }
    1021             : 
    1022           0 : void Menu::Activate()
    1023             : {
    1024           0 :     bInCallback = sal_True;
    1025             : 
    1026           0 :     ImplMenuDelData aDelData( this );
    1027             : 
    1028           0 :     ImplCallEventListeners( VCLEVENT_MENU_ACTIVATE, ITEMPOS_INVALID );
    1029             : 
    1030           0 :     if( !aDelData.isDeleted() )
    1031             :     {
    1032           0 :         if ( !aActivateHdl.Call( this ) )
    1033             :         {
    1034           0 :             if( !aDelData.isDeleted() )
    1035             :             {
    1036           0 :                 Menu* pStartMenu = ImplGetStartMenu();
    1037           0 :                 if ( pStartMenu && ( pStartMenu != this ) )
    1038             :                 {
    1039           0 :                     pStartMenu->bInCallback = sal_True;
    1040             :                     // MT 11/01: Call EventListener here? I don't know...
    1041           0 :                     pStartMenu->aActivateHdl.Call( this );
    1042           0 :                     pStartMenu->bInCallback = sal_False;
    1043             :                 }
    1044             :             }
    1045             :         }
    1046           0 :         bInCallback = sal_False;
    1047           0 :     }
    1048           0 : }
    1049             : 
    1050           0 : void Menu::Deactivate()
    1051             : {
    1052           0 :     for ( size_t n = pItemList->size(); n; )
    1053             :     {
    1054           0 :         MenuItemData* pData = pItemList->GetDataFromPos( --n );
    1055           0 :         if ( pData->bIsTemporary )
    1056           0 :             pItemList->Remove( n );
    1057             :     }
    1058             : 
    1059           0 :     bInCallback = sal_True;
    1060             : 
    1061           0 :     ImplMenuDelData aDelData( this );
    1062             : 
    1063           0 :     Menu* pStartMenu = ImplGetStartMenu();
    1064           0 :     ImplCallEventListeners( VCLEVENT_MENU_DEACTIVATE, ITEMPOS_INVALID );
    1065             : 
    1066           0 :     if( !aDelData.isDeleted() )
    1067             :     {
    1068           0 :         if ( !aDeactivateHdl.Call( this ) )
    1069             :         {
    1070           0 :             if( !aDelData.isDeleted() )
    1071             :             {
    1072           0 :                 if ( pStartMenu && ( pStartMenu != this ) )
    1073             :                 {
    1074           0 :                     pStartMenu->bInCallback = sal_True;
    1075           0 :                     pStartMenu->aDeactivateHdl.Call( this );
    1076           0 :                     pStartMenu->bInCallback = sal_False;
    1077             :                 }
    1078             :             }
    1079             :         }
    1080             :     }
    1081             : 
    1082           0 :     if( !aDelData.isDeleted() )
    1083             :     {
    1084           0 :         bInCallback = sal_False;
    1085           0 :     }
    1086           0 : }
    1087             : 
    1088           0 : void Menu::Highlight()
    1089             : {
    1090           0 :     ImplMenuDelData aDelData( this );
    1091             : 
    1092           0 :     Menu* pStartMenu = ImplGetStartMenu();
    1093           0 :     if ( !aHighlightHdl.Call( this ) && !aDelData.isDeleted() )
    1094             :     {
    1095           0 :         if ( pStartMenu && ( pStartMenu != this ) )
    1096           0 :             pStartMenu->aHighlightHdl.Call( this );
    1097           0 :     }
    1098           0 : }
    1099             : 
    1100           0 : void Menu::ImplSelect()
    1101             : {
    1102           0 :     MenuItemData* pData = GetItemList()->GetData( nSelectedId );
    1103           0 :     if ( pData && (pData->nBits & MIB_AUTOCHECK) )
    1104             :     {
    1105           0 :         sal_Bool bChecked = IsItemChecked( nSelectedId );
    1106           0 :         if ( pData->nBits & MIB_RADIOCHECK )
    1107             :         {
    1108           0 :             if ( !bChecked )
    1109           0 :                 CheckItem( nSelectedId, sal_True );
    1110             :         }
    1111             :         else
    1112           0 :             CheckItem( nSelectedId, !bChecked );
    1113             :     }
    1114             : 
    1115             :     // call select
    1116           0 :     ImplSVData* pSVData = ImplGetSVData();
    1117           0 :     pSVData->maAppData.mpActivePopupMenu = NULL;        // if new execute in select()
    1118           0 :     Application::PostUserEvent( nEventId, LINK( this, Menu, ImplCallSelect ) );
    1119           0 : }
    1120             : 
    1121           0 : void Menu::Select()
    1122             : {
    1123           0 :     ImplMenuDelData aDelData( this );
    1124             : 
    1125           0 :     ImplCallEventListeners( VCLEVENT_MENU_SELECT, GetItemPos( GetCurItemId() ) );
    1126           0 :     if ( !aDelData.isDeleted() && !aSelectHdl.Call( this ) )
    1127             :     {
    1128           0 :         if( !aDelData.isDeleted() )
    1129             :         {
    1130           0 :             Menu* pStartMenu = ImplGetStartMenu();
    1131           0 :             if ( pStartMenu && ( pStartMenu != this ) )
    1132             :             {
    1133           0 :                 pStartMenu->nSelectedId = nSelectedId;
    1134           0 :                 pStartMenu->aSelectHdl.Call( this );
    1135             :             }
    1136             :         }
    1137           0 :     }
    1138           0 : }
    1139             : 
    1140             : #if defined(QUARTZ)
    1141             : void Menu::ImplSelectWithStart( Menu* pSMenu )
    1142             : {
    1143             :     Menu* pOldStartedFrom = pStartedFrom;
    1144             :     pStartedFrom = pSMenu;
    1145             :     Menu* pOldStartedStarted = pOldStartedFrom ? pOldStartedFrom->pStartedFrom : NULL;
    1146             :     Select();
    1147             :     if( pOldStartedFrom )
    1148             :         pOldStartedFrom->pStartedFrom = pOldStartedStarted;
    1149             :     pStartedFrom = pOldStartedFrom;
    1150             : }
    1151             : #endif
    1152             : 
    1153           0 : void Menu::RequestHelp( const HelpEvent& )
    1154             : {
    1155           0 : }
    1156             : 
    1157         948 : void Menu::ImplCallEventListeners( sal_uLong nEvent, sal_uInt16 nPos )
    1158             : {
    1159         948 :     ImplMenuDelData aDelData( this );
    1160             : 
    1161         948 :     VclMenuEvent aEvent( this, nEvent, nPos );
    1162             : 
    1163             :     // This is needed by atk accessibility bridge
    1164         948 :     if ( nEvent == VCLEVENT_MENU_HIGHLIGHT )
    1165             :     {
    1166           0 :         ImplGetSVData()->mpApp->ImplCallEventListeners( &aEvent );
    1167             :     }
    1168             : 
    1169         948 :     if ( !aDelData.isDeleted() )
    1170         948 :         maEventListeners.Call( &aEvent );
    1171             : 
    1172         948 :     if( !aDelData.isDeleted() )
    1173             :     {
    1174         948 :         Menu* pMenu = this;
    1175        2844 :         while ( pMenu )
    1176             :         {
    1177         948 :             maChildEventListeners.Call( &aEvent );
    1178             : 
    1179         948 :             if( aDelData.isDeleted() )
    1180           0 :                 break;
    1181             : 
    1182         948 :             pMenu = ( pMenu->pStartedFrom != pMenu ) ? pMenu->pStartedFrom : NULL;
    1183             :         }
    1184         948 :     }
    1185         948 : }
    1186             : 
    1187           0 : void Menu::AddEventListener( const Link& rEventListener )
    1188             : {
    1189           0 :     maEventListeners.addListener( rEventListener );
    1190           0 : }
    1191             : 
    1192          63 : void Menu::RemoveEventListener( const Link& rEventListener )
    1193             : {
    1194          63 :     maEventListeners.removeListener( rEventListener );
    1195          63 : }
    1196             : 
    1197          50 : void Menu::InsertItem( sal_uInt16 nItemId, const XubString& rStr, MenuItemBits nItemBits, sal_uInt16 nPos )
    1198             : {
    1199             :     DBG_ASSERT( nItemId, "Menu::InsertItem(): ItemId == 0" );
    1200             :     DBG_ASSERT( GetItemPos( nItemId ) == MENU_ITEM_NOTFOUND,
    1201             :                 "Menu::InsertItem(): ItemId already exists" );
    1202             : 
    1203             :     // if Position > ItemCount, append
    1204          50 :     if ( nPos >= pItemList->size() )
    1205          50 :         nPos = MENU_APPEND;
    1206             : 
    1207             :     // put Item in MenuItemList
    1208             :     MenuItemData* pData = pItemList->Insert( nItemId, MENUITEM_STRING,
    1209          50 :                              nItemBits, rStr, Image(), this, nPos );
    1210             : 
    1211             :     // update native menu
    1212          50 :     if( ImplGetSalMenu() && pData->pSalMenuItem )
    1213           0 :         ImplGetSalMenu()->InsertItem( pData->pSalMenuItem, nPos );
    1214             : 
    1215          50 :     Window* pWin = ImplGetWindow();
    1216          50 :     delete mpLayoutData, mpLayoutData = NULL;
    1217          50 :     if ( pWin )
    1218             :     {
    1219           0 :         ImplCalcSize( pWin );
    1220           0 :         if ( pWin->IsVisible() )
    1221           0 :             pWin->Invalidate();
    1222             :     }
    1223          50 :     ImplCallEventListeners( VCLEVENT_MENU_INSERTITEM, nPos );
    1224          50 : }
    1225             : 
    1226           0 : void Menu::InsertItem( sal_uInt16 nItemId, const Image& rImage,
    1227             :                        MenuItemBits nItemBits, sal_uInt16 nPos )
    1228             : {
    1229           0 :     InsertItem( nItemId, ImplGetSVEmptyStr(), nItemBits, nPos );
    1230           0 :     SetItemImage( nItemId, rImage );
    1231           0 : }
    1232             : 
    1233           0 : void Menu::InsertItem( sal_uInt16 nItemId,
    1234             :                        const XubString& rStr, const Image& rImage,
    1235             :                        MenuItemBits nItemBits, sal_uInt16 nPos )
    1236             : {
    1237           0 :     InsertItem( nItemId, rStr, nItemBits, nPos );
    1238           0 :     SetItemImage( nItemId, rImage );
    1239           0 : }
    1240             : 
    1241          56 : void Menu::InsertItem( const ResId& rResId, sal_uInt16 nPos )
    1242             : {
    1243          56 :     ResMgr* pMgr = rResId.GetResMgr();
    1244          56 :     if( ! pMgr )
    1245          56 :         return;
    1246             : 
    1247             :     sal_uLong              nObjMask;
    1248             : 
    1249          56 :     GetRes( rResId.SetRT( RSC_MENUITEM ) );
    1250          56 :     nObjMask    = ReadLongRes();
    1251             : 
    1252          56 :     sal_Bool bSep = sal_False;
    1253          56 :     if ( nObjMask & RSC_MENUITEM_SEPARATOR )
    1254           6 :         bSep = (sal_Bool)ReadShortRes();
    1255             : 
    1256          56 :     sal_uInt16 nItemId = 1;
    1257          56 :     if ( nObjMask & RSC_MENUITEM_ID )
    1258          50 :         nItemId = sal::static_int_cast<sal_uInt16>(ReadLongRes());
    1259             : 
    1260          56 :     MenuItemBits nStatus = 0;
    1261          56 :     if ( nObjMask & RSC_MENUITEM_STATUS )
    1262           0 :         nStatus = sal::static_int_cast<MenuItemBits>(ReadLongRes());
    1263             : 
    1264          56 :     String aText;
    1265          56 :     if ( nObjMask & RSC_MENUITEM_TEXT )
    1266          50 :         aText = ReadStringRes();
    1267             : 
    1268             :     // create item
    1269          56 :     if ( nObjMask & RSC_MENUITEM_BITMAP )
    1270             :     {
    1271           0 :         if ( !bSep )
    1272             :         {
    1273           0 :             Bitmap aBmp( ResId( (RSHEADER_TYPE*)GetClassRes(), *pMgr ) );
    1274           0 :             if ( aText.Len() )
    1275           0 :                 InsertItem( nItemId, aText, aBmp, nStatus, nPos );
    1276             :             else
    1277           0 :                 InsertItem( nItemId, aBmp, nStatus, nPos );
    1278             :         }
    1279           0 :         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
    1280             :     }
    1281          56 :     else if ( !bSep )
    1282          50 :         InsertItem( nItemId, aText, nStatus, nPos );
    1283          56 :     if ( bSep )
    1284           6 :         InsertSeparator( nPos );
    1285             : 
    1286          56 :     String aHelpText;
    1287          56 :     if ( nObjMask & RSC_MENUITEM_HELPTEXT )
    1288             :     {
    1289           0 :         aHelpText = ReadStringRes();
    1290           0 :         if( !bSep )
    1291           0 :             SetHelpText( nItemId, aHelpText );
    1292             :     }
    1293             : 
    1294          56 :     if ( nObjMask & RSC_MENUITEM_HELPID )
    1295             :     {
    1296          50 :         rtl::OString aHelpId( ReadByteStringRes() );
    1297          50 :         if ( !bSep )
    1298          50 :             SetHelpId( nItemId, aHelpId );
    1299             :     }
    1300             : 
    1301          56 :     if( !bSep )
    1302          50 :         SetHelpText( nItemId, aHelpText );
    1303             : 
    1304          56 :     if ( nObjMask & RSC_MENUITEM_KEYCODE )
    1305             :     {
    1306           0 :         if ( !bSep )
    1307           0 :             SetAccelKey( nItemId, KeyCode( ResId( (RSHEADER_TYPE*)GetClassRes(), *pMgr ) ) );
    1308           0 :         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
    1309             :     }
    1310          56 :     if( nObjMask & RSC_MENUITEM_CHECKED )
    1311             :     {
    1312           0 :         if ( !bSep )
    1313           0 :             CheckItem( nItemId, (sal_Bool)ReadShortRes() );
    1314             :     }
    1315          56 :     if ( nObjMask & RSC_MENUITEM_DISABLE )
    1316             :     {
    1317           0 :         if ( !bSep )
    1318           0 :             EnableItem( nItemId, !(sal_Bool)ReadShortRes() );
    1319             :     }
    1320          56 :     if ( nObjMask & RSC_MENUITEM_COMMAND )
    1321             :     {
    1322           0 :         String aCommandStr = ReadStringRes();
    1323           0 :         if ( !bSep )
    1324           0 :             SetItemCommand( nItemId, aCommandStr );
    1325             :     }
    1326          56 :     if ( nObjMask & RSC_MENUITEM_MENU )
    1327             :     {
    1328           0 :         if ( !bSep )
    1329             :         {
    1330           0 :             MenuItemData* pData = GetItemList()->GetData( nItemId );
    1331           0 :             if ( pData )
    1332             :             {
    1333           0 :                 PopupMenu* pSubMenu = new PopupMenu( ResId( (RSHEADER_TYPE*)GetClassRes(), *pMgr ) );
    1334           0 :                 pData->pAutoSubMenu = pSubMenu;
    1335             :                 // #111060# keep track of this pointer, may be it will be deleted from outside
    1336           0 :                 pSubMenu->pRefAutoSubMenu = &pData->pAutoSubMenu;
    1337           0 :                 SetPopupMenu( nItemId, pSubMenu );
    1338             :             }
    1339             :         }
    1340           0 :         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
    1341             :     }
    1342          56 :     delete mpLayoutData, mpLayoutData = NULL;
    1343             : }
    1344             : 
    1345           6 : void Menu::InsertSeparator( sal_uInt16 nPos )
    1346             : {
    1347             :     // do nothing if its a menu bar
    1348           6 :     if ( bIsMenuBar )
    1349           6 :         return;
    1350             : 
    1351             :     // if position > ItemCount, append
    1352           6 :     if ( nPos >= pItemList->size() )
    1353           6 :         nPos = MENU_APPEND;
    1354             : 
    1355             :     // put separator in item list
    1356           6 :     pItemList->InsertSeparator( nPos );
    1357             : 
    1358             :     // update native menu
    1359           6 :     size_t itemPos = ( nPos != MENU_APPEND ) ? nPos : pItemList->size() - 1;
    1360           6 :     MenuItemData *pData = pItemList->GetDataFromPos( itemPos );
    1361           6 :     if( ImplGetSalMenu() && pData && pData->pSalMenuItem )
    1362           0 :         ImplGetSalMenu()->InsertItem( pData->pSalMenuItem, nPos );
    1363             : 
    1364           6 :     delete mpLayoutData, mpLayoutData = NULL;
    1365             : 
    1366           6 :     ImplCallEventListeners( VCLEVENT_MENU_INSERTITEM, nPos );
    1367             : }
    1368             : 
    1369           0 : void Menu::RemoveItem( sal_uInt16 nPos )
    1370             : {
    1371           0 :     sal_Bool bRemove = sal_False;
    1372             : 
    1373           0 :     if ( nPos < GetItemCount() )
    1374             :     {
    1375             :         // update native menu
    1376           0 :         if( ImplGetSalMenu() )
    1377           0 :             ImplGetSalMenu()->RemoveItem( nPos );
    1378             : 
    1379           0 :         pItemList->Remove( nPos );
    1380           0 :         bRemove = sal_True;
    1381             :     }
    1382             : 
    1383           0 :     Window* pWin = ImplGetWindow();
    1384           0 :     if ( pWin )
    1385             :     {
    1386           0 :         ImplCalcSize( pWin );
    1387           0 :         if ( pWin->IsVisible() )
    1388           0 :             pWin->Invalidate();
    1389             :     }
    1390           0 :     delete mpLayoutData, mpLayoutData = NULL;
    1391             : 
    1392           0 :     if ( bRemove )
    1393           0 :         ImplCallEventListeners( VCLEVENT_MENU_REMOVEITEM, nPos );
    1394           0 : }
    1395             : 
    1396           0 : void ImplCopyItem( Menu* pThis, const Menu& rMenu, sal_uInt16 nPos, sal_uInt16 nNewPos,
    1397             :                   sal_uInt16 nMode = 0 )
    1398             : {
    1399           0 :     MenuItemType eType = rMenu.GetItemType( nPos );
    1400             : 
    1401           0 :     if ( eType == MENUITEM_DONTKNOW )
    1402           0 :         return;
    1403             : 
    1404           0 :     if ( eType == MENUITEM_SEPARATOR )
    1405           0 :         pThis->InsertSeparator( nNewPos );
    1406             :     else
    1407             :     {
    1408           0 :         sal_uInt16 nId = rMenu.GetItemId( nPos );
    1409             : 
    1410             :         DBG_ASSERT( pThis->GetItemPos( nId ) == MENU_ITEM_NOTFOUND,
    1411             :                     "Menu::CopyItem(): ItemId already exists" );
    1412             : 
    1413           0 :         MenuItemData* pData = rMenu.GetItemList()->GetData( nId );
    1414             : 
    1415           0 :         if ( eType == MENUITEM_STRINGIMAGE )
    1416           0 :             pThis->InsertItem( nId, pData->aText, pData->aImage, pData->nBits, nNewPos );
    1417           0 :         else if ( eType == MENUITEM_STRING )
    1418           0 :             pThis->InsertItem( nId, pData->aText, pData->nBits, nNewPos );
    1419             :         else
    1420           0 :             pThis->InsertItem( nId, pData->aImage, pData->nBits, nNewPos );
    1421             : 
    1422           0 :         if ( rMenu.IsItemChecked( nId ) )
    1423           0 :             pThis->CheckItem( nId, sal_True );
    1424           0 :         if ( !rMenu.IsItemEnabled( nId ) )
    1425           0 :             pThis->EnableItem( nId, sal_False );
    1426           0 :         pThis->SetHelpId( nId, pData->aHelpId );
    1427           0 :         pThis->SetHelpText( nId, pData->aHelpText );
    1428           0 :         pThis->SetAccelKey( nId, pData->aAccelKey );
    1429           0 :         pThis->SetItemCommand( nId, pData->aCommandStr );
    1430           0 :         pThis->SetHelpCommand( nId, pData->aHelpCommandStr );
    1431             : 
    1432           0 :         PopupMenu* pSubMenu = rMenu.GetPopupMenu( nId );
    1433           0 :         if ( pSubMenu )
    1434             :         {
    1435             :             // create auto-copy
    1436           0 :             if ( nMode == 1 )
    1437             :             {
    1438           0 :                 PopupMenu* pNewMenu = new PopupMenu( *pSubMenu );
    1439           0 :                 pThis->SetPopupMenu( nId, pNewMenu );
    1440             :             }
    1441             :             else
    1442           0 :                 pThis->SetPopupMenu( nId, pSubMenu );
    1443             :         }
    1444             :     }
    1445             : }
    1446             : 
    1447           0 : void Menu::CopyItem( const Menu& rMenu, sal_uInt16 nPos, sal_uInt16 nNewPos )
    1448             : {
    1449           0 :     ImplCopyItem( this, rMenu, nPos, nNewPos );
    1450           0 : }
    1451             : 
    1452           0 : void Menu::Clear()
    1453             : {
    1454           0 :     for ( sal_uInt16 i = GetItemCount(); i; i-- )
    1455           0 :         RemoveItem( 0 );
    1456           0 : }
    1457             : 
    1458         898 : sal_uInt16 Menu::GetItemCount() const
    1459             : {
    1460         898 :     return (sal_uInt16)pItemList->size();
    1461             : }
    1462             : 
    1463           0 : sal_uInt16 Menu::ImplGetVisibleItemCount() const
    1464             : {
    1465           0 :     sal_uInt16 nItems = 0;
    1466           0 :     for ( size_t n = pItemList->size(); n; )
    1467             :     {
    1468           0 :         if ( ImplIsVisible( --n ) )
    1469           0 :             nItems++;
    1470             :     }
    1471           0 :     return nItems;
    1472             : }
    1473             : 
    1474           0 : sal_uInt16 Menu::ImplGetFirstVisible() const
    1475             : {
    1476           0 :     for ( size_t n = 0; n < pItemList->size(); n++ )
    1477             :     {
    1478           0 :         if ( ImplIsVisible( n ) )
    1479           0 :             return n;
    1480             :     }
    1481           0 :     return ITEMPOS_INVALID;
    1482             : }
    1483             : 
    1484           0 : sal_uInt16 Menu::ImplGetPrevVisible( sal_uInt16 nPos ) const
    1485             : {
    1486           0 :     for ( size_t n = nPos; n; )
    1487             :     {
    1488           0 :         if ( n && ImplIsVisible( --n ) )
    1489           0 :             return n;
    1490             :     }
    1491           0 :     return ITEMPOS_INVALID;
    1492             : }
    1493             : 
    1494           0 : sal_uInt16 Menu::ImplGetNextVisible( sal_uInt16 nPos ) const
    1495             : {
    1496           0 :     for ( size_t n = nPos+1; n < pItemList->size(); n++ )
    1497             :     {
    1498           0 :         if ( ImplIsVisible( n ) )
    1499           0 :             return n;
    1500             :     }
    1501           0 :     return ITEMPOS_INVALID;
    1502             : }
    1503             : 
    1504           0 : sal_uInt16 Menu::GetItemId( sal_uInt16 nPos ) const
    1505             : {
    1506           0 :     MenuItemData* pData = pItemList->GetDataFromPos( nPos );
    1507             : 
    1508           0 :     if ( pData )
    1509           0 :         return pData->nId;
    1510             :     else
    1511           0 :         return 0;
    1512             : }
    1513             : 
    1514           0 : sal_uInt16 Menu::GetItemPos( sal_uInt16 nItemId ) const
    1515             : {
    1516             :     size_t          nPos;
    1517           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1518             : 
    1519           0 :     if ( pData )
    1520           0 :         return (sal_uInt16)nPos;
    1521             :     else
    1522           0 :         return MENU_ITEM_NOTFOUND;
    1523             : }
    1524             : 
    1525           0 : MenuItemType Menu::GetItemType( sal_uInt16 nPos ) const
    1526             : {
    1527           0 :     MenuItemData* pData = pItemList->GetDataFromPos( nPos );
    1528             : 
    1529           0 :     if ( pData )
    1530           0 :         return pData->eType;
    1531             :     else
    1532           0 :         return MENUITEM_DONTKNOW;
    1533             : }
    1534             : 
    1535           0 : sal_uInt16 Menu::GetCurItemId() const
    1536             : {
    1537           0 :     return nSelectedId;
    1538             : }
    1539             : 
    1540           0 : void Menu::SetItemBits( sal_uInt16 nItemId, MenuItemBits nBits )
    1541             : {
    1542           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1543           0 :     if ( pData )
    1544           0 :         pData->nBits = nBits;
    1545           0 : }
    1546             : 
    1547           0 : MenuItemBits Menu::GetItemBits( sal_uInt16 nItemId ) const
    1548             : {
    1549           0 :     MenuItemBits nBits = 0;
    1550           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1551           0 :     if ( pData )
    1552           0 :         nBits = pData->nBits;
    1553           0 :     return nBits;
    1554             : }
    1555             : 
    1556           0 : void Menu::SetUserValue( sal_uInt16 nItemId, sal_uLong nValue )
    1557             : {
    1558           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1559           0 :     if ( pData )
    1560           0 :         pData->nUserValue = nValue;
    1561           0 : }
    1562             : 
    1563           0 : sal_uLong Menu::GetUserValue( sal_uInt16 nItemId ) const
    1564             : {
    1565           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1566           0 :     return pData ? pData->nUserValue : 0;
    1567             : }
    1568             : 
    1569           0 : void Menu::SetPopupMenu( sal_uInt16 nItemId, PopupMenu* pMenu )
    1570             : {
    1571             :     size_t          nPos;
    1572           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1573             : 
    1574             :     // Item does not exist -> return NULL
    1575           0 :     if ( !pData )
    1576             :         return;
    1577             : 
    1578             :     // same menu, nothing to do
    1579           0 :     if ( (PopupMenu*)pData->pSubMenu == pMenu )
    1580             :         return;
    1581             : 
    1582             :     // data exchange
    1583           0 :     pData->pSubMenu = pMenu;
    1584             : 
    1585             :     // #112023# Make sure pStartedFrom does not point to invalid (old) data
    1586           0 :     if ( pData->pSubMenu )
    1587           0 :         pData->pSubMenu->pStartedFrom = 0;
    1588             : 
    1589             :     // set native submenu
    1590           0 :     if( ImplGetSalMenu() && pData->pSalMenuItem )
    1591             :     {
    1592           0 :         if( pMenu )
    1593           0 :             ImplGetSalMenu()->SetSubMenu( pData->pSalMenuItem, pMenu->ImplGetSalMenu(), nPos );
    1594             :         else
    1595           0 :             ImplGetSalMenu()->SetSubMenu( pData->pSalMenuItem, NULL, nPos );
    1596             :     }
    1597             : 
    1598           0 :     ImplCallEventListeners( VCLEVENT_MENU_SUBMENUCHANGED, nPos );
    1599             : }
    1600             : 
    1601         426 : PopupMenu* Menu::GetPopupMenu( sal_uInt16 nItemId ) const
    1602             : {
    1603         426 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1604             : 
    1605         426 :     if ( pData )
    1606           0 :         return (PopupMenu*)(pData->pSubMenu);
    1607             :     else
    1608         426 :         return NULL;
    1609             : }
    1610             : 
    1611           0 : void Menu::SetAccelKey( sal_uInt16 nItemId, const KeyCode& rKeyCode )
    1612             : {
    1613             :     size_t          nPos;
    1614           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1615             : 
    1616           0 :     if ( !pData )
    1617             :         return;
    1618             : 
    1619           0 :     if ( pData->aAccelKey == rKeyCode )
    1620             :         return;
    1621             : 
    1622           0 :     pData->aAccelKey = rKeyCode;
    1623             : 
    1624             :     // update native menu
    1625           0 :     if( ImplGetSalMenu() && pData->pSalMenuItem )
    1626           0 :         ImplGetSalMenu()->SetAccelerator( nPos, pData->pSalMenuItem, rKeyCode, rKeyCode.GetName() );
    1627             : }
    1628             : 
    1629           0 : KeyCode Menu::GetAccelKey( sal_uInt16 nItemId ) const
    1630             : {
    1631           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1632             : 
    1633           0 :     if ( pData )
    1634           0 :         return pData->aAccelKey;
    1635             :     else
    1636           0 :         return KeyCode();
    1637             : }
    1638             : 
    1639           0 : KeyEvent Menu::GetActivationKey( sal_uInt16 nItemId ) const
    1640             : {
    1641           0 :     KeyEvent aRet;
    1642           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1643           0 :     if( pData )
    1644             :     {
    1645           0 :         sal_uInt16 nPos = pData->aText.Search( '~' );
    1646           0 :         if( nPos != STRING_NOTFOUND && nPos < pData->aText.Len()-1 )
    1647             :         {
    1648           0 :             sal_uInt16 nCode = 0;
    1649           0 :             sal_Unicode cAccel = pData->aText.GetChar( nPos+1 );
    1650           0 :             if( cAccel >= 'a' && cAccel <= 'z' )
    1651           0 :                 nCode = KEY_A + (cAccel-'a');
    1652           0 :             else if( cAccel >= 'A' && cAccel <= 'Z' )
    1653           0 :                 nCode = KEY_A + (cAccel-'A');
    1654           0 :             else if( cAccel >= '0' && cAccel <= '9' )
    1655           0 :                 nCode = KEY_0 + (cAccel-'0');
    1656           0 :             if(nCode )
    1657           0 :                 aRet = KeyEvent( cAccel, KeyCode( nCode, KEY_MOD2 ) );
    1658             :         }
    1659             : 
    1660             :     }
    1661           0 :     return aRet;
    1662             : }
    1663             : 
    1664           0 : void Menu::CheckItem( sal_uInt16 nItemId, sal_Bool bCheck )
    1665             : {
    1666             :     size_t          nPos;
    1667           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1668             : 
    1669           0 :     if ( !pData || pData->bChecked == bCheck )
    1670           0 :         return;
    1671             : 
    1672             :     // if radio-check, then uncheck previous
    1673           0 :     if ( bCheck && (pData->nBits & MIB_AUTOCHECK) &&
    1674             :          (pData->nBits & MIB_RADIOCHECK) )
    1675             :     {
    1676             :         MenuItemData*   pGroupData;
    1677             :         sal_uInt16          nGroupPos;
    1678           0 :         sal_uInt16          nItemCount = GetItemCount();
    1679           0 :         sal_Bool            bFound = sal_False;
    1680             : 
    1681           0 :         nGroupPos = nPos;
    1682           0 :         while ( nGroupPos )
    1683             :         {
    1684           0 :             pGroupData = pItemList->GetDataFromPos( nGroupPos-1 );
    1685           0 :             if ( pGroupData->nBits & MIB_RADIOCHECK )
    1686             :             {
    1687           0 :                 if ( IsItemChecked( pGroupData->nId ) )
    1688             :                 {
    1689           0 :                     CheckItem( pGroupData->nId, sal_False );
    1690           0 :                     bFound = sal_True;
    1691           0 :                     break;
    1692             :                 }
    1693             :             }
    1694             :             else
    1695           0 :                 break;
    1696           0 :             nGroupPos--;
    1697             :         }
    1698             : 
    1699           0 :         if ( !bFound )
    1700             :         {
    1701           0 :             nGroupPos = nPos+1;
    1702           0 :             while ( nGroupPos < nItemCount )
    1703             :             {
    1704           0 :                 pGroupData = pItemList->GetDataFromPos( nGroupPos );
    1705           0 :                 if ( pGroupData->nBits & MIB_RADIOCHECK )
    1706             :                 {
    1707           0 :                     if ( IsItemChecked( pGroupData->nId ) )
    1708             :                     {
    1709           0 :                         CheckItem( pGroupData->nId, sal_False );
    1710           0 :                         break;
    1711             :                     }
    1712             :                 }
    1713             :                 else
    1714           0 :                     break;
    1715           0 :                 nGroupPos++;
    1716             :             }
    1717             :         }
    1718             :     }
    1719             : 
    1720           0 :     pData->bChecked = bCheck;
    1721             : 
    1722             :     // update native menu
    1723           0 :     if( ImplGetSalMenu() )
    1724           0 :         ImplGetSalMenu()->CheckItem( nPos, bCheck );
    1725             : 
    1726           0 :     ImplCallEventListeners( bCheck ? VCLEVENT_MENU_ITEMCHECKED : VCLEVENT_MENU_ITEMUNCHECKED, nPos );
    1727             : }
    1728             : 
    1729           0 : sal_Bool Menu::IsItemChecked( sal_uInt16 nItemId ) const
    1730             : {
    1731             :     size_t          nPos;
    1732           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1733             : 
    1734           0 :     if ( !pData )
    1735           0 :         return sal_False;
    1736             : 
    1737           0 :     return pData->bChecked;
    1738             : }
    1739             : 
    1740           0 : void Menu::EnableItem( sal_uInt16 nItemId, sal_Bool bEnable )
    1741             : {
    1742             :     size_t          nPos;
    1743           0 :     MenuItemData*   pItemData = pItemList->GetData( nItemId, nPos );
    1744             : 
    1745           0 :     if ( pItemData && ( pItemData->bEnabled != bEnable ) )
    1746             :     {
    1747           0 :         pItemData->bEnabled = bEnable;
    1748             : 
    1749           0 :         Window* pWin = ImplGetWindow();
    1750           0 :         if ( pWin && pWin->IsVisible() )
    1751             :         {
    1752             :             DBG_ASSERT( bIsMenuBar, "Menu::EnableItem - Popup visible!" );
    1753           0 :             long nX = 0;
    1754           0 :             size_t nCount = pItemList->size();
    1755           0 :             for ( size_t n = 0; n < nCount; n++ )
    1756             :             {
    1757           0 :                 MenuItemData* pData = pItemList->GetDataFromPos( n );
    1758           0 :                 if ( n == nPos )
    1759             :                 {
    1760           0 :                     pWin->Invalidate( Rectangle( Point( nX, 0 ), Size( pData->aSz.Width(), pData->aSz.Height() ) ) );
    1761           0 :                     break;
    1762             :                 }
    1763           0 :                 nX += pData->aSz.Width();
    1764             :             }
    1765             :         }
    1766             :         // update native menu
    1767           0 :         if( ImplGetSalMenu() )
    1768           0 :             ImplGetSalMenu()->EnableItem( nPos, bEnable );
    1769             : 
    1770           0 :         ImplCallEventListeners( bEnable ? VCLEVENT_MENU_ENABLE : VCLEVENT_MENU_DISABLE, nPos );
    1771             :     }
    1772           0 : }
    1773             : 
    1774           0 : sal_Bool Menu::IsItemEnabled( sal_uInt16 nItemId ) const
    1775             : {
    1776             :     size_t          nPos;
    1777           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1778             : 
    1779           0 :     if ( !pData )
    1780           0 :         return sal_False;
    1781             : 
    1782           0 :     return pData->bEnabled;
    1783             : }
    1784             : 
    1785           0 : void Menu::ShowItem( sal_uInt16 nItemId, sal_Bool bVisible )
    1786             : {
    1787             :     size_t          nPos;
    1788           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1789             : 
    1790             :     DBG_ASSERT( !bIsMenuBar, "Menu::ShowItem - ignored for menu bar entries!" );
    1791           0 :     if ( !bIsMenuBar && pData && ( pData->bVisible != bVisible ) )
    1792             :     {
    1793           0 :         Window* pWin = ImplGetWindow();
    1794           0 :         if ( pWin && pWin->IsVisible() )
    1795             :         {
    1796             :             DBG_ASSERT( 0, "Menu::ShowItem - ignored for visible popups!" );
    1797           0 :             return;
    1798             :         }
    1799           0 :         pData->bVisible = bVisible;
    1800             : 
    1801             :         // update native menu
    1802           0 :         if( ImplGetSalMenu() )
    1803           0 :             ImplGetSalMenu()->ShowItem( nPos, bVisible );
    1804             :     }
    1805             : }
    1806             : 
    1807           6 : void Menu::SetItemText( sal_uInt16 nItemId, const XubString& rStr )
    1808             : {
    1809             :     size_t          nPos;
    1810           6 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1811             : 
    1812           6 :     if ( !pData )
    1813           6 :         return;
    1814             : 
    1815           6 :     if ( !rStr.Equals( pData->aText ) )
    1816             :     {
    1817           6 :         pData->aText = rStr;
    1818           6 :         ImplSetMenuItemData( pData );
    1819             :         // update native menu
    1820           6 :         if( ImplGetSalMenu() && pData->pSalMenuItem )
    1821           0 :             ImplGetSalMenu()->SetItemText( nPos, pData->pSalMenuItem, rStr );
    1822             : 
    1823           6 :         Window* pWin = ImplGetWindow();
    1824           6 :         delete mpLayoutData, mpLayoutData = NULL;
    1825           6 :         if ( pWin && IsMenuBar() )
    1826             :         {
    1827           0 :             ImplCalcSize( pWin );
    1828           0 :             if ( pWin->IsVisible() )
    1829           0 :                 pWin->Invalidate();
    1830             :         }
    1831             : 
    1832           6 :         ImplCallEventListeners( VCLEVENT_MENU_ITEMTEXTCHANGED, nPos );
    1833             :     }
    1834             : }
    1835             : 
    1836           6 : XubString Menu::GetItemText( sal_uInt16 nItemId ) const
    1837             : {
    1838             :     size_t          nPos;
    1839           6 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1840             : 
    1841           6 :     if ( pData )
    1842           6 :         return pData->aText;
    1843             :     else
    1844           0 :         return ImplGetSVEmptyStr();
    1845             : }
    1846             : 
    1847           0 : void Menu::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
    1848             : {
    1849             :     size_t          nPos;
    1850           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1851             : 
    1852           0 :     if ( !pData )
    1853           0 :         return;
    1854             : 
    1855           0 :     pData->aImage = rImage;
    1856           0 :     ImplSetMenuItemData( pData );
    1857             : 
    1858             :     // update native menu
    1859           0 :     if( ImplGetSalMenu() && pData->pSalMenuItem )
    1860           0 :         ImplGetSalMenu()->SetItemImage( nPos, pData->pSalMenuItem, rImage );
    1861             : }
    1862             : 
    1863           0 : static inline Image ImplRotImage( const Image& rImage, long nAngle10 )
    1864             : {
    1865           0 :     Image       aRet;
    1866           0 :     BitmapEx    aBmpEx( rImage.GetBitmapEx() );
    1867             : 
    1868           0 :     aBmpEx.Rotate( nAngle10, COL_WHITE );
    1869             : 
    1870           0 :     return Image( aBmpEx );
    1871             : }
    1872             : 
    1873           0 : void Menu::SetItemImageAngle( sal_uInt16 nItemId, long nAngle10 )
    1874             : {
    1875             :     size_t          nPos;
    1876           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1877             : 
    1878           0 :     if ( pData )
    1879             :     {
    1880           0 :         long nDeltaAngle = (nAngle10 - pData->nItemImageAngle) % 3600;
    1881           0 :         while( nDeltaAngle < 0 )
    1882           0 :             nDeltaAngle += 3600;
    1883             : 
    1884           0 :         pData->nItemImageAngle = nAngle10;
    1885           0 :         if( nDeltaAngle && !!pData->aImage )
    1886           0 :             pData->aImage = ImplRotImage( pData->aImage, nDeltaAngle );
    1887             :     }
    1888           0 : }
    1889             : 
    1890           0 : static inline Image ImplMirrorImage( const Image& rImage )
    1891             : {
    1892           0 :     Image       aRet;
    1893           0 :     BitmapEx    aBmpEx( rImage.GetBitmapEx() );
    1894             : 
    1895           0 :     aBmpEx.Mirror( BMP_MIRROR_HORZ );
    1896             : 
    1897           0 :     return Image( aBmpEx );
    1898             : }
    1899             : 
    1900           0 : void Menu::SetItemImageMirrorMode( sal_uInt16 nItemId, sal_Bool bMirror )
    1901             : {
    1902             :     size_t          nPos;
    1903           0 :     MenuItemData*   pData = pItemList->GetData( nItemId, nPos );
    1904             : 
    1905           0 :     if ( pData )
    1906             :     {
    1907           0 :         if( ( pData->bMirrorMode && ! bMirror ) ||
    1908           0 :             ( ! pData->bMirrorMode && bMirror )
    1909             :             )
    1910             :         {
    1911           0 :             pData->bMirrorMode = bMirror ? true : false;
    1912           0 :             if( !!pData->aImage )
    1913           0 :                 pData->aImage = ImplMirrorImage( pData->aImage );
    1914             :         }
    1915             :     }
    1916           0 : }
    1917             : 
    1918           0 : Image Menu::GetItemImage( sal_uInt16 nItemId ) const
    1919             : {
    1920           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1921             : 
    1922           0 :     if ( pData )
    1923           0 :         return pData->aImage;
    1924             :     else
    1925           0 :         return Image();
    1926             : }
    1927             : 
    1928           0 : long Menu::GetItemImageAngle( sal_uInt16 nItemId ) const
    1929             : {
    1930           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1931             : 
    1932           0 :     if ( pData )
    1933           0 :         return pData->nItemImageAngle;
    1934             :     else
    1935           0 :         return 0;
    1936             : }
    1937             : 
    1938           0 : sal_Bool Menu::GetItemImageMirrorMode( sal_uInt16 nItemId ) const
    1939             : {
    1940           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1941             : 
    1942           0 :     if ( pData )
    1943           0 :         return pData->bMirrorMode;
    1944             :     else
    1945           0 :         return sal_False;
    1946             : }
    1947             : 
    1948           0 : void Menu::SetItemCommand( sal_uInt16 nItemId, const String& rCommand )
    1949             : {
    1950             :     size_t        nPos;
    1951           0 :     MenuItemData* pData = pItemList->GetData( nItemId, nPos );
    1952             : 
    1953           0 :     if ( pData )
    1954           0 :         pData->aCommandStr = rCommand;
    1955           0 : }
    1956             : 
    1957           0 : const XubString& Menu::GetItemCommand( sal_uInt16 nItemId ) const
    1958             : {
    1959           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1960             : 
    1961           0 :     if ( pData )
    1962           0 :         return pData->aCommandStr;
    1963             :     else
    1964           0 :         return ImplGetSVEmptyStr();
    1965             : }
    1966             : 
    1967           0 : void Menu::SetHelpCommand( sal_uInt16 nItemId, const XubString& rStr )
    1968             : {
    1969           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1970             : 
    1971           0 :     if ( pData )
    1972           0 :         pData->aHelpCommandStr = rStr;
    1973           0 : }
    1974             : 
    1975           0 : const XubString& Menu::GetHelpCommand( sal_uInt16 nItemId ) const
    1976             : {
    1977           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1978             : 
    1979           0 :     if ( pData )
    1980           0 :         return pData->aHelpCommandStr;
    1981             :     else
    1982           0 :         return ImplGetSVEmptyStr();
    1983             : }
    1984             : 
    1985          50 : void Menu::SetHelpText( sal_uInt16 nItemId, const XubString& rStr )
    1986             : {
    1987          50 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1988             : 
    1989          50 :     if ( pData )
    1990          50 :         pData->aHelpText = rStr;
    1991          50 : }
    1992             : 
    1993           0 : const XubString& Menu::ImplGetHelpText( sal_uInt16 nItemId ) const
    1994             : {
    1995           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    1996             : 
    1997           0 :     if ( pData )
    1998             :     {
    1999           0 :         if ( !pData->aHelpText.Len() &&
    2000           0 :              (( !pData->aHelpId.isEmpty()  ) || ( pData->aCommandStr.Len() )))
    2001             :         {
    2002           0 :             Help* pHelp = Application::GetHelp();
    2003           0 :             if ( pHelp )
    2004             :             {
    2005           0 :                 if ( pData->aCommandStr.Len() )
    2006           0 :                     pData->aHelpText = pHelp->GetHelpText( pData->aCommandStr, NULL );
    2007             : 
    2008           0 :                 if( !pData->aHelpText.Len() && !pData->aHelpId.isEmpty() )
    2009           0 :                     pData->aHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pData->aHelpId, RTL_TEXTENCODING_UTF8 ), NULL );
    2010             :             }
    2011             :         }
    2012             : 
    2013           0 :         return pData->aHelpText;
    2014             :     }
    2015             :     else
    2016           0 :         return ImplGetSVEmptyStr();
    2017             : }
    2018             : 
    2019           0 : const XubString& Menu::GetHelpText( sal_uInt16 nItemId ) const
    2020             : {
    2021           0 :     return ImplGetHelpText( nItemId );
    2022             : }
    2023             : 
    2024           0 : void Menu::SetTipHelpText( sal_uInt16 nItemId, const XubString& rStr )
    2025             : {
    2026           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    2027             : 
    2028           0 :     if ( pData )
    2029           0 :         pData->aTipHelpText = rStr;
    2030           0 : }
    2031             : 
    2032           0 : const XubString& Menu::GetTipHelpText( sal_uInt16 nItemId ) const
    2033             : {
    2034           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    2035             : 
    2036           0 :     if ( pData )
    2037           0 :         return pData->aTipHelpText;
    2038             :     else
    2039           0 :         return ImplGetSVEmptyStr();
    2040             : }
    2041             : 
    2042          50 : void Menu::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId )
    2043             : {
    2044          50 :     MenuItemData* pData = pItemList->GetData( nItemId );
    2045             : 
    2046          50 :     if ( pData )
    2047          50 :         pData->aHelpId = rHelpId;
    2048          50 : }
    2049             : 
    2050           0 : rtl::OString Menu::GetHelpId( sal_uInt16 nItemId ) const
    2051             : {
    2052           0 :     rtl::OString aRet;
    2053             : 
    2054           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    2055             : 
    2056           0 :     if ( pData )
    2057             :     {
    2058           0 :         if ( !pData->aHelpId.isEmpty() )
    2059           0 :             aRet = pData->aHelpId;
    2060             :         else
    2061           0 :             aRet = ::rtl::OUStringToOString( pData->aCommandStr, RTL_TEXTENCODING_UTF8 );
    2062             :     }
    2063             : 
    2064           0 :     return aRet;
    2065             : }
    2066             : 
    2067           0 : Menu& Menu::operator=( const Menu& rMenu )
    2068             : {
    2069             :     // clean up
    2070           0 :     Clear();
    2071             : 
    2072             :     // copy items
    2073           0 :     sal_uInt16 nCount = rMenu.GetItemCount();
    2074           0 :     for ( sal_uInt16 i = 0; i < nCount; i++ )
    2075           0 :         ImplCopyItem( this, rMenu, i, MENU_APPEND, 1 );
    2076             : 
    2077           0 :     nDefaultItem = rMenu.nDefaultItem;
    2078           0 :     aActivateHdl = rMenu.aActivateHdl;
    2079           0 :     aDeactivateHdl = rMenu.aDeactivateHdl;
    2080           0 :     aHighlightHdl = rMenu.aHighlightHdl;
    2081           0 :     aSelectHdl = rMenu.aSelectHdl;
    2082           0 :     aTitleText = rMenu.aTitleText;
    2083           0 :     bIsMenuBar = rMenu.bIsMenuBar;
    2084             : 
    2085           0 :     return *this;
    2086             : }
    2087             : 
    2088           0 : sal_Bool Menu::ImplIsVisible( sal_uInt16 nPos ) const
    2089             : {
    2090           0 :     sal_Bool bVisible = sal_True;
    2091             : 
    2092           0 :     MenuItemData* pData = pItemList->GetDataFromPos( nPos );
    2093             :     // check general visibility first
    2094           0 :     if( pData && !pData->bVisible )
    2095           0 :         bVisible = sal_False;
    2096             : 
    2097           0 :     if ( bVisible && pData && pData->eType == MENUITEM_SEPARATOR )
    2098             :     {
    2099           0 :         if( nPos == 0 ) // no separator should be shown at the very beginning
    2100           0 :             bVisible = sal_False;
    2101             :         else
    2102             :         {
    2103             :             // always avoid adjacent separators
    2104           0 :             size_t nCount = pItemList->size();
    2105             :             size_t n;
    2106           0 :             MenuItemData* pNextData = NULL;
    2107             :             // search next visible item
    2108           0 :             for( n = nPos + 1; n < nCount; n++ )
    2109             :             {
    2110           0 :                 pNextData = pItemList->GetDataFromPos( n );
    2111           0 :                 if( pNextData && pNextData->bVisible )
    2112             :                 {
    2113           0 :                     if( pNextData->eType == MENUITEM_SEPARATOR || ImplIsVisible(n) )
    2114           0 :                         break;
    2115             :                 }
    2116             :             }
    2117           0 :             if( n == nCount ) // no next visible item
    2118           0 :                 bVisible = sal_False;
    2119             :             // check for separator
    2120           0 :             if( pNextData && pNextData->bVisible && pNextData->eType == MENUITEM_SEPARATOR )
    2121           0 :                 bVisible = sal_False;
    2122             : 
    2123           0 :             if( bVisible )
    2124             :             {
    2125           0 :                 for( n = nPos; n > 0; n-- )
    2126             :                 {
    2127           0 :                     pNextData = pItemList->GetDataFromPos( n-1 );
    2128           0 :                     if( pNextData && pNextData->bVisible )
    2129             :                     {
    2130           0 :                         if( pNextData->eType != MENUITEM_SEPARATOR && ImplIsVisible(n-1) )
    2131           0 :                             break;
    2132             :                     }
    2133             :                 }
    2134           0 :                 if( n == 0 ) // no previous visible item
    2135           0 :                     bVisible = sal_False;
    2136             :             }
    2137             :         }
    2138             :     }
    2139             : 
    2140             :     // not allowed for menubar, as I do not know
    2141             :     // whether a menu-entry will disappear or will appear
    2142           0 :     if ( bVisible && !bIsMenuBar && ( nMenuFlags & MENU_FLAG_HIDEDISABLEDENTRIES ) &&
    2143           0 :         !( nMenuFlags & MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES ) )
    2144             :     {
    2145           0 :         if( !pData ) // e.g. nPos == ITEMPOS_INVALID
    2146           0 :             bVisible = sal_False;
    2147           0 :         else if ( pData->eType != MENUITEM_SEPARATOR ) // separators handled above
    2148             :         {
    2149             :             // bVisible = pData->bEnabled && ( !pData->pSubMenu || pData->pSubMenu->HasValidEntries( sal_True ) );
    2150           0 :             bVisible = pData->bEnabled; // do not check submenus as they might be filled at Activate().
    2151             :         }
    2152             :     }
    2153             : 
    2154           0 :     return bVisible;
    2155             : }
    2156             : 
    2157           0 : sal_Bool Menu::IsItemPosVisible( sal_uInt16 nItemPos ) const
    2158             : {
    2159           0 :     return IsMenuVisible() && ImplIsVisible( nItemPos );
    2160             : }
    2161             : 
    2162           0 : sal_Bool Menu::IsMenuVisible() const
    2163             : {
    2164           0 :     return pWindow && pWindow->IsReallyVisible();
    2165             : }
    2166             : 
    2167           0 : sal_Bool Menu::ImplIsSelectable( sal_uInt16 nPos ) const
    2168             : {
    2169           0 :     sal_Bool bSelectable = sal_True;
    2170             : 
    2171           0 :     MenuItemData* pData = pItemList->GetDataFromPos( nPos );
    2172             :     // check general visibility first
    2173           0 :     if ( pData && ( pData->nBits & MIB_NOSELECT ) )
    2174           0 :         bSelectable = sal_False;
    2175             : 
    2176           0 :     return bSelectable;
    2177             : }
    2178             : 
    2179           0 : void Menu::SelectItem( sal_uInt16 nItemId )
    2180             : {
    2181           0 :     if( bIsMenuBar )
    2182           0 :         static_cast<MenuBar*>(this)->SelectEntry( nItemId );
    2183             :     else
    2184           0 :         static_cast<PopupMenu*>(this)->SelectEntry( nItemId );
    2185           0 : }
    2186             : 
    2187           0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Menu::GetAccessible()
    2188             : {
    2189             :     // Since PopupMenu are sometimes shared by different instances of MenuBar, the mxAccessible member gets
    2190             :     // overwritten and may contain a disposed object when the initial menubar gets set again. So use the
    2191             :     // mxAccessible member only for sub menus.
    2192           0 :     if ( pStartedFrom )
    2193             :     {
    2194           0 :         for ( sal_uInt16 i = 0, nCount = pStartedFrom->GetItemCount(); i < nCount; ++i )
    2195             :         {
    2196           0 :             sal_uInt16 nItemId = pStartedFrom->GetItemId( i );
    2197           0 :             if ( static_cast< Menu* >( pStartedFrom->GetPopupMenu( nItemId ) ) == this )
    2198             :             {
    2199           0 :                 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xParent = pStartedFrom->GetAccessible();
    2200           0 :                 if ( xParent.is() )
    2201             :                 {
    2202           0 :                     ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
    2203           0 :                     if ( xParentContext.is() )
    2204           0 :                         return xParentContext->getAccessibleChild( i );
    2205           0 :                 }
    2206             :             }
    2207             :         }
    2208             :     }
    2209           0 :     else if ( !mxAccessible.is() )
    2210             :     {
    2211           0 :         UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
    2212           0 :         if ( pWrapper )
    2213           0 :             mxAccessible = pWrapper->CreateAccessible( this, bIsMenuBar );
    2214             :     }
    2215             : 
    2216           0 :     return mxAccessible;
    2217             : }
    2218             : 
    2219           0 : void Menu::SetAccessible( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rxAccessible )
    2220             : {
    2221           0 :     mxAccessible = rxAccessible;
    2222           0 : }
    2223             : 
    2224         413 : Size Menu::ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, long& rRadioHeight ) const
    2225             : {
    2226         413 :     long nCheckWidth = 0, nRadioWidth = 0;
    2227         413 :     rCheckHeight = rRadioHeight = 0;
    2228             : 
    2229         413 :     if( ! bIsMenuBar )
    2230             :     {
    2231           0 :         ImplControlValue aVal;
    2232           0 :         Rectangle aNativeBounds;
    2233           0 :         Rectangle aNativeContent;
    2234           0 :         Point tmp( 0, 0 );
    2235           0 :         Rectangle aCtrlRegion( Rectangle( tmp, Size( 100, 15 ) ) );
    2236           0 :         if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_CHECK_MARK ) )
    2237             :         {
    2238           0 :             if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
    2239             :                                               ControlPart(PART_MENU_ITEM_CHECK_MARK),
    2240             :                                               aCtrlRegion,
    2241             :                                               ControlState(CTRL_STATE_ENABLED),
    2242             :                                               aVal,
    2243             :                                               OUString(),
    2244             :                                               aNativeBounds,
    2245           0 :                                               aNativeContent )
    2246             :             )
    2247             :             {
    2248           0 :                 rCheckHeight = aNativeBounds.GetHeight();
    2249           0 :                 nCheckWidth = aNativeContent.GetWidth();
    2250             :             }
    2251             :         }
    2252           0 :         if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_RADIO_MARK ) )
    2253             :         {
    2254           0 :             if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
    2255             :                                               ControlPart(PART_MENU_ITEM_RADIO_MARK),
    2256             :                                               aCtrlRegion,
    2257             :                                               ControlState(CTRL_STATE_ENABLED),
    2258             :                                               aVal,
    2259             :                                               OUString(),
    2260             :                                               aNativeBounds,
    2261           0 :                                               aNativeContent )
    2262             :             )
    2263             :             {
    2264           0 :                 rRadioHeight = aNativeBounds.GetHeight();
    2265           0 :                 nRadioWidth = aNativeContent.GetWidth();
    2266             :             }
    2267           0 :         }
    2268             :     }
    2269         413 :     return Size(Max(nCheckWidth, nRadioWidth), Max(rCheckHeight, rRadioHeight));
    2270             : }
    2271             : 
    2272           0 : sal_Bool Menu::ImplGetNativeSubmenuArrowSize( Window* pWin, Size& rArrowSize, long& rArrowSpacing ) const
    2273             : {
    2274           0 :     ImplControlValue aVal;
    2275           0 :     Rectangle aNativeBounds;
    2276           0 :     Rectangle aNativeContent;
    2277           0 :     Point tmp( 0, 0 );
    2278           0 :     Rectangle aCtrlRegion( Rectangle( tmp, Size( 100, 15 ) ) );
    2279           0 :     if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP,
    2280           0 :                                         PART_MENU_SUBMENU_ARROW ) )
    2281             :         {
    2282           0 :             if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
    2283             :                                               ControlPart(PART_MENU_SUBMENU_ARROW),
    2284             :                                               aCtrlRegion,
    2285             :                                               ControlState(CTRL_STATE_ENABLED),
    2286             :                                               aVal,
    2287             :                                               OUString(),
    2288             :                                               aNativeBounds,
    2289           0 :                                               aNativeContent )
    2290             :             )
    2291             :             {
    2292             :                 Size aSize( Size ( aNativeContent.GetWidth(),
    2293           0 :                                    aNativeContent.GetHeight() ) );
    2294           0 :                 rArrowSize = aSize;
    2295           0 :                 rArrowSpacing = aNativeBounds.GetWidth() - aNativeContent.GetWidth();
    2296             : 
    2297           0 :                 return sal_True;
    2298             :             }
    2299             :         }
    2300           0 :     return sal_False;
    2301             : }
    2302             : 
    2303             : // -----------------------------------------------------------------------
    2304             : 
    2305         948 : void Menu::ImplAddDel( ImplMenuDelData& rDel )
    2306             : {
    2307             :     DBG_ASSERT( !rDel.mpMenu, "Menu::ImplAddDel(): cannot add ImplMenuDelData twice !" );
    2308         948 :     if( !rDel.mpMenu )
    2309             :     {
    2310         948 :         rDel.mpMenu = this;
    2311         948 :         rDel.mpNext = mpFirstDel;
    2312         948 :         mpFirstDel = &rDel;
    2313             :     }
    2314         948 : }
    2315             : 
    2316             : // -----------------------------------------------------------------------
    2317             : 
    2318         948 : void Menu::ImplRemoveDel( ImplMenuDelData& rDel )
    2319             : {
    2320         948 :     rDel.mpMenu = NULL;
    2321         948 :     if ( mpFirstDel == &rDel )
    2322             :     {
    2323         948 :         mpFirstDel = rDel.mpNext;
    2324             :     }
    2325             :     else
    2326             :     {
    2327           0 :         ImplMenuDelData* pData = mpFirstDel;
    2328           0 :         while ( pData && (pData->mpNext != &rDel) )
    2329           0 :             pData = pData->mpNext;
    2330             : 
    2331             :         DBG_ASSERT( pData, "Menu::ImplRemoveDel(): ImplMenuDelData not registered !" );
    2332           0 :         if( pData )
    2333           0 :             pData->mpNext = rDel.mpNext;
    2334             :     }
    2335         948 : }
    2336             : 
    2337             : // -----------------------------------------------------------------------
    2338             : 
    2339         236 : Size Menu::ImplCalcSize( Window* pWin )
    2340             : {
    2341             :     // | Check/Radio/Image| Text| Accel/Popup|
    2342             : 
    2343             :     // for symbols: nFontHeight x nFontHeight
    2344         236 :     long nFontHeight = pWin->GetTextHeight();
    2345         236 :     long nExtra = nFontHeight/4;
    2346             : 
    2347         236 :     long nMinMenuItemHeight = nFontHeight;
    2348         236 :     long nCheckHeight = 0, nRadioHeight = 0;
    2349         236 :     Size aMaxSize = ImplGetNativeCheckAndRadioSize(pWin, nCheckHeight, nRadioHeight);
    2350         236 :     if( aMaxSize.Height() > nMinMenuItemHeight )
    2351           0 :         nMinMenuItemHeight = aMaxSize.Height();
    2352             : 
    2353         236 :     Size aMaxImgSz;
    2354             : 
    2355         236 :     const StyleSettings& rSettings = pWin->GetSettings().GetStyleSettings();
    2356         236 :     if ( rSettings.GetUseImagesInMenus() )
    2357             :     {
    2358         236 :         nMinMenuItemHeight = 16;
    2359         472 :         for ( size_t i = pItemList->size(); i; )
    2360             :         {
    2361           0 :             MenuItemData* pData = pItemList->GetDataFromPos( --i );
    2362           0 :             if ( ImplIsVisible( i )
    2363             :                && (  ( pData->eType == MENUITEM_IMAGE )
    2364             :                   || ( pData->eType == MENUITEM_STRINGIMAGE )
    2365             :                   )
    2366             :                )
    2367             :             {
    2368           0 :                 Size aImgSz = pData->aImage.GetSizePixel();
    2369           0 :                 if ( aImgSz.Height() > aMaxImgSz.Height() )
    2370           0 :                     aMaxImgSz.Height() = aImgSz.Height();
    2371           0 :                 if ( aImgSz.Height() > nMinMenuItemHeight )
    2372           0 :                     nMinMenuItemHeight = aImgSz.Height();
    2373             :                 break;
    2374             :             }
    2375             :         }
    2376             :     }
    2377             : 
    2378         236 :     Size aSz;
    2379         236 :     long nCheckWidth = 0;
    2380         236 :     long nMaxWidth = 0;
    2381             : 
    2382         472 :     for ( size_t n = pItemList->size(); n; )
    2383             :     {
    2384           0 :         MenuItemData* pData = pItemList->GetDataFromPos( --n );
    2385             : 
    2386           0 :         pData->aSz.Height() = 0;
    2387           0 :         pData->aSz.Width() = 0;
    2388             : 
    2389           0 :         if ( ImplIsVisible( n ) )
    2390             :         {
    2391           0 :             long nWidth = 0;
    2392             : 
    2393             :             // Separator
    2394           0 :             if ( !bIsMenuBar && ( pData->eType == MENUITEM_SEPARATOR ) )
    2395             :             {
    2396             :                 DBG_ASSERT( !bIsMenuBar, "Separator in MenuBar ?! " );
    2397           0 :                 pData->aSz.Height() = 4;
    2398             :             }
    2399             : 
    2400             :             // Image:
    2401           0 :             if ( !bIsMenuBar && ( ( pData->eType == MENUITEM_IMAGE ) || ( pData->eType == MENUITEM_STRINGIMAGE ) ) )
    2402             :             {
    2403           0 :                 Size aImgSz = pData->aImage.GetSizePixel();
    2404           0 :                 aImgSz.Height() += 4; // add a border for native marks
    2405           0 :                 aImgSz.Width() += 4; // add a border for native marks
    2406           0 :                 if ( aImgSz.Width() > aMaxImgSz.Width() )
    2407           0 :                     aMaxImgSz.Width() = aImgSz.Width();
    2408           0 :                 if ( aImgSz.Height() > aMaxImgSz.Height() )
    2409           0 :                     aMaxImgSz.Height() = aImgSz.Height();
    2410           0 :                 if ( aImgSz.Height() > pData->aSz.Height() )
    2411           0 :                     pData->aSz.Height() = aImgSz.Height();
    2412             :             }
    2413             : 
    2414             :             // Check Buttons:
    2415           0 :             if ( !bIsMenuBar && pData->HasCheck() )
    2416             :             {
    2417           0 :                 nCheckWidth = aMaxSize.Width();
    2418             :                 // checks / images take the same place
    2419           0 :                 if( ! ( ( pData->eType == MENUITEM_IMAGE ) || ( pData->eType == MENUITEM_STRINGIMAGE ) ) )
    2420           0 :                     nWidth += nCheckWidth + nExtra * 2;
    2421             :             }
    2422             : 
    2423             :             // Text:
    2424           0 :             if ( (pData->eType == MENUITEM_STRING) || (pData->eType == MENUITEM_STRINGIMAGE) )
    2425             :             {
    2426           0 :                 long nTextWidth = pWin->GetCtrlTextWidth( pData->aText );
    2427           0 :                 long nTextHeight = pWin->GetTextHeight();
    2428             : 
    2429           0 :                 if ( bIsMenuBar )
    2430             :                 {
    2431           0 :                     if ( nTextHeight > pData->aSz.Height() )
    2432           0 :                         pData->aSz.Height() = nTextHeight;
    2433             : 
    2434           0 :                     pData->aSz.Width() = nTextWidth + 4*nExtra;
    2435           0 :                     aSz.Width() += pData->aSz.Width();
    2436             :                 }
    2437             :                 else
    2438           0 :                     pData->aSz.Height() = Max( Max( nTextHeight, pData->aSz.Height() ), nMinMenuItemHeight );
    2439             : 
    2440           0 :                 nWidth += nTextWidth;
    2441             :             }
    2442             : 
    2443             :             // Accel
    2444           0 :             if ( !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() )
    2445             :             {
    2446           0 :                 String aName = pData->aAccelKey.GetName();
    2447           0 :                 long nAccWidth = pWin->GetTextWidth( aName );
    2448           0 :                 nAccWidth += nExtra;
    2449           0 :                 nWidth += nAccWidth;
    2450             :             }
    2451             : 
    2452             :             // SubMenu?
    2453           0 :             if ( !bIsMenuBar && pData->pSubMenu )
    2454             :             {
    2455           0 :                     if ( nFontHeight > nWidth )
    2456           0 :                         nWidth += nFontHeight;
    2457             : 
    2458           0 :                 pData->aSz.Height() = Max( Max( nFontHeight, pData->aSz.Height() ), nMinMenuItemHeight );
    2459             :             }
    2460             : 
    2461           0 :             pData->aSz.Height() += EXTRAITEMHEIGHT; // little bit more distance
    2462             : 
    2463           0 :             if ( !bIsMenuBar )
    2464           0 :                 aSz.Height() += (long)pData->aSz.Height();
    2465             : 
    2466           0 :             if ( nWidth > nMaxWidth )
    2467           0 :                 nMaxWidth = nWidth;
    2468             : 
    2469             :         }
    2470             :     }
    2471             : 
    2472         236 :     if ( !bIsMenuBar )
    2473             :     {
    2474             :         // popup menus should not be wider than half the screen
    2475             :         // except on rather small screens
    2476             :         // TODO: move GetScreenNumber from SystemWindow to Window ?
    2477             :         // currently we rely on internal privileges
    2478           0 :         unsigned int nDisplayScreen = pWin->ImplGetWindowImpl()->mpFrame->maGeometry.nDisplayScreenNumber;
    2479           0 :         Rectangle aDispRect( Application::GetScreenPosSizePixel( nDisplayScreen ) );
    2480           0 :         long nScreenWidth = aDispRect.GetWidth() >= 800 ? aDispRect.GetWidth() : 800;
    2481           0 :         if( nMaxWidth > nScreenWidth/2 )
    2482           0 :             nMaxWidth = nScreenWidth/2;
    2483             : 
    2484           0 :         sal_uInt16 gfxExtra = (sal_uInt16) Max( nExtra, 7L ); // #107710# increase space between checkmarks/images/text
    2485           0 :         nImgOrChkPos = (sal_uInt16)nExtra;
    2486           0 :         long nImgOrChkWidth = 0;
    2487           0 :         if( aMaxSize.Height() > 0 ) // NWF case
    2488           0 :             nImgOrChkWidth = aMaxSize.Height() + nExtra;
    2489             :         else // non NWF case
    2490           0 :             nImgOrChkWidth = nFontHeight/2 + gfxExtra;
    2491           0 :         nImgOrChkWidth = Max( nImgOrChkWidth, aMaxImgSz.Width() + gfxExtra );
    2492           0 :         nTextPos = (sal_uInt16)(nImgOrChkPos + nImgOrChkWidth);
    2493           0 :         nTextPos = nTextPos + gfxExtra;
    2494             : 
    2495           0 :         aSz.Width() = nTextPos + nMaxWidth + nExtra;
    2496           0 :         aSz.Width() += 4*nExtra;   // a _little_ more ...
    2497             : 
    2498           0 :         aSz.Width() += 2*ImplGetSVData()->maNWFData.mnMenuFormatBorderX;
    2499           0 :         aSz.Height() += 2*ImplGetSVData()->maNWFData.mnMenuFormatBorderY;
    2500             :     }
    2501             :     else
    2502             :     {
    2503         236 :         nTextPos = (sal_uInt16)(2*nExtra);
    2504         236 :         aSz.Height() = nFontHeight+6;
    2505             : 
    2506             :         // get menubar height from native methods if supported
    2507         236 :         if( pWindow->IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) )
    2508             :         {
    2509           0 :             ImplControlValue aVal;
    2510           0 :             Rectangle aNativeBounds;
    2511           0 :             Rectangle aNativeContent;
    2512           0 :             Point tmp( 0, 0 );
    2513           0 :             Rectangle aCtrlRegion( tmp, Size( 100, 15 ) );
    2514           0 :             if( pWindow->GetNativeControlRegion( ControlType(CTRL_MENUBAR),
    2515             :                                                  ControlPart(PART_ENTIRE_CONTROL),
    2516             :                                                  aCtrlRegion,
    2517             :                                                  ControlState(CTRL_STATE_ENABLED),
    2518             :                                                  aVal,
    2519             :                                                  OUString(),
    2520             :                                                  aNativeBounds,
    2521           0 :                                                  aNativeContent )
    2522             :             )
    2523             :             {
    2524           0 :                 int nNativeHeight = aNativeBounds.GetHeight();
    2525           0 :                 if( nNativeHeight > aSz.Height() )
    2526           0 :                     aSz.Height() = nNativeHeight;
    2527           0 :             }
    2528             :         }
    2529             : 
    2530             :         // account for the size of the close button, which actually is a toolbox
    2531             :         // due to NWF this is variable
    2532         236 :         long nCloserHeight = ((MenuBarWindow*) pWindow)->MinCloseButtonSize().Height();
    2533         236 :         if( aSz.Height() < nCloserHeight )
    2534         236 :             aSz.Height() = nCloserHeight;
    2535             :     }
    2536             : 
    2537         236 :     if ( pLogo )
    2538           0 :         aSz.Width() += pLogo->aBitmap.GetSizePixel().Width();
    2539             : 
    2540         236 :     return aSz;
    2541             : }
    2542             : 
    2543           0 : static void ImplPaintCheckBackground( Window* i_pWindow, const Rectangle& i_rRect, bool i_bHighlight )
    2544             : {
    2545           0 :     sal_Bool bNativeOk = sal_False;
    2546           0 :     if( i_pWindow->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
    2547             :     {
    2548           0 :         ImplControlValue    aControlValue;
    2549           0 :         Rectangle           aCtrlRegion( i_rRect );
    2550           0 :         ControlState        nState = CTRL_STATE_PRESSED | CTRL_STATE_ENABLED;
    2551             : 
    2552           0 :         aControlValue.setTristateVal( BUTTONVALUE_ON );
    2553             : 
    2554             :         bNativeOk = i_pWindow->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON,
    2555             :                                                   aCtrlRegion, nState, aControlValue,
    2556           0 :                                                   rtl::OUString() );
    2557             :     }
    2558             : 
    2559           0 :     if( ! bNativeOk )
    2560             :     {
    2561           0 :         const StyleSettings& rSettings = i_pWindow->GetSettings().GetStyleSettings();
    2562           0 :         Color aColor( i_bHighlight ? rSettings.GetMenuHighlightTextColor() : rSettings.GetHighlightColor() );
    2563           0 :         i_pWindow->DrawSelectionBackground( i_rRect, 0, i_bHighlight, sal_True, sal_False, 2, NULL, &aColor );
    2564             :     }
    2565           0 : }
    2566             : 
    2567           0 : static String getShortenedString( const String& i_rLong, Window* i_pWin, long i_nMaxWidth )
    2568             : {
    2569           0 :     xub_StrLen nPos = STRING_NOTFOUND;
    2570           0 :     String aNonMnem( OutputDevice::GetNonMnemonicString( i_rLong, nPos ) );
    2571           0 :     aNonMnem = i_pWin->GetEllipsisString( aNonMnem, i_nMaxWidth, TEXT_DRAW_CENTERELLIPSIS );
    2572             :     // re-insert mnemonic
    2573           0 :     if( nPos != STRING_NOTFOUND )
    2574             :     {
    2575           0 :         if( nPos < aNonMnem.Len() && i_rLong.GetChar(nPos+1) == aNonMnem.GetChar(nPos) )
    2576             :         {
    2577           0 :             rtl::OUStringBuffer aBuf( i_rLong.Len() );
    2578           0 :             aBuf.append( aNonMnem.GetBuffer(), nPos );
    2579           0 :             aBuf.append( sal_Unicode('~') );
    2580           0 :             aBuf.append( aNonMnem.GetBuffer()+nPos );
    2581           0 :             aNonMnem = aBuf.makeStringAndClear();
    2582             :         }
    2583             :     }
    2584           0 :     return aNonMnem;
    2585             : }
    2586             : 
    2587         177 : void Menu::ImplPaint( Window* pWin, sal_uInt16 nBorder, long nStartY, MenuItemData* pThisItemOnly, sal_Bool bHighlighted, bool bLayout ) const
    2588             : {
    2589             :     // for symbols: nFontHeight x nFontHeight
    2590         177 :     long nFontHeight = pWin->GetTextHeight();
    2591         177 :     long nExtra = nFontHeight/4;
    2592             : 
    2593         177 :     long nCheckHeight = 0, nRadioHeight = 0;
    2594         177 :     ImplGetNativeCheckAndRadioSize( pWin, nCheckHeight, nRadioHeight );
    2595             : 
    2596         177 :     DecorationView aDecoView( pWin );
    2597         177 :     const StyleSettings& rSettings = pWin->GetSettings().GetStyleSettings();
    2598             : 
    2599         177 :     Point aTopLeft, aTmpPos;
    2600             : 
    2601         177 :     if ( pLogo )
    2602           0 :         aTopLeft.X() = pLogo->aBitmap.GetSizePixel().Width();
    2603             : 
    2604         177 :     int nOuterSpaceX = 0;
    2605         177 :     if( !bIsMenuBar )
    2606             :     {
    2607           0 :         nOuterSpaceX = ImplGetSVData()->maNWFData.mnMenuFormatBorderX;
    2608           0 :         aTopLeft.X() += nOuterSpaceX;
    2609           0 :         aTopLeft.Y() += ImplGetSVData()->maNWFData.mnMenuFormatBorderY;
    2610             :     }
    2611             : 
    2612         177 :     Size aOutSz = pWin->GetOutputSizePixel();
    2613         177 :     size_t nCount = pItemList->size();
    2614         177 :     if( bLayout )
    2615           0 :         mpLayoutData->m_aVisibleItemBoundRects.clear();
    2616             : 
    2617         177 :     for ( size_t n = 0; n < nCount; n++ )
    2618             :     {
    2619           0 :         MenuItemData* pData = pItemList->GetDataFromPos( n );
    2620           0 :         if ( ImplIsVisible( n ) && ( !pThisItemOnly || ( pData == pThisItemOnly ) ) )
    2621             :         {
    2622           0 :             if ( pThisItemOnly && bHighlighted )
    2623           0 :                 pWin->SetTextColor( rSettings.GetMenuHighlightTextColor() );
    2624             : 
    2625           0 :             Point aPos( aTopLeft );
    2626           0 :             aPos.Y() += nBorder;
    2627           0 :             aPos.Y() += nStartY;
    2628             : 
    2629           0 :             if ( aPos.Y() >= 0 )
    2630             :             {
    2631           0 :                 long    nTextOffsetY = ((pData->aSz.Height()-nFontHeight)/2);
    2632           0 :                 if( bIsMenuBar )
    2633           0 :                     nTextOffsetY += (aOutSz.Height()-pData->aSz.Height()) / 2;
    2634           0 :                 sal_uInt16  nTextStyle   = 0;
    2635           0 :                 sal_uInt16  nSymbolStyle = 0;
    2636           0 :                 sal_uInt16  nImageStyle  = 0;
    2637             : 
    2638             :                 // submenus without items are not disabled when no items are
    2639             :                 // contained. The application itself should check for this!
    2640             :                 // Otherwise it could happen entries are disabled due to
    2641             :                 // asynchronous loading
    2642           0 :                 if ( !pData->bEnabled )
    2643             :                 {
    2644           0 :                     nTextStyle   |= TEXT_DRAW_DISABLE;
    2645           0 :                     nSymbolStyle |= SYMBOL_DRAW_DISABLE;
    2646           0 :                     nImageStyle  |= IMAGE_DRAW_DISABLE;
    2647             :                 }
    2648             : 
    2649             :                 // Separator
    2650           0 :                 if ( !bLayout && !bIsMenuBar && ( pData->eType == MENUITEM_SEPARATOR ) )
    2651             :                 {
    2652           0 :                     bool bNativeOk = false;
    2653           0 :                     if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP,
    2654           0 :                                                         PART_MENU_SEPARATOR ) )
    2655             :                     {
    2656           0 :                         ControlState nState = 0;
    2657           0 :                         if ( pData->bEnabled )
    2658           0 :                             nState |= CTRL_STATE_ENABLED;
    2659           0 :                         if ( bHighlighted )
    2660           0 :                             nState |= CTRL_STATE_SELECTED;
    2661           0 :                         Size aSz( pData->aSz );
    2662           0 :                         aSz.Width() = aOutSz.Width() - 2*nOuterSpaceX;
    2663           0 :                         Rectangle aItemRect( aPos, aSz );
    2664           0 :                         MenupopupValue aVal( nTextPos-GUTTERBORDER, aItemRect );
    2665             :                         bNativeOk = pWin->DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_SEPARATOR,
    2666             :                                                              aItemRect,
    2667             :                                                              nState,
    2668             :                                                              aVal,
    2669           0 :                                                              OUString() );
    2670             :                     }
    2671           0 :                     if( ! bNativeOk )
    2672             :                     {
    2673           0 :                         aTmpPos.Y() = aPos.Y() + ((pData->aSz.Height()-2)/2);
    2674           0 :                         aTmpPos.X() = aPos.X() + 2 + nOuterSpaceX;
    2675           0 :                         pWin->SetLineColor( rSettings.GetShadowColor() );
    2676           0 :                         pWin->DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpaceX, aTmpPos.Y() ) );
    2677           0 :                         aTmpPos.Y()++;
    2678           0 :                         pWin->SetLineColor( rSettings.GetLightColor() );
    2679           0 :                         pWin->DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpaceX, aTmpPos.Y() ) );
    2680           0 :                         pWin->SetLineColor();
    2681             :                     }
    2682             :                 }
    2683             : 
    2684           0 :                 Rectangle aOuterCheckRect( Point( aPos.X()+nImgOrChkPos, aPos.Y() ), Size( pData->aSz.Height(), pData->aSz.Height() ) );
    2685           0 :                 aOuterCheckRect.Left()      += 1;
    2686           0 :                 aOuterCheckRect.Right()     -= 1;
    2687           0 :                 aOuterCheckRect.Top()       += 1;
    2688           0 :                 aOuterCheckRect.Bottom()    -= 1;
    2689             : 
    2690             :                 // CheckMark
    2691           0 :                 if ( !bLayout && !bIsMenuBar && pData->HasCheck() )
    2692             :                 {
    2693             :                     // draw selection transparent marker if checked
    2694             :                     // onto that either a checkmark or the item image
    2695             :                     // will be painted
    2696             :                     // however do not do this if native checks will be painted since
    2697             :                     // the selection color too often does not fit the theme's check and/or radio
    2698             : 
    2699           0 :                     if( ! ( ( pData->eType == MENUITEM_IMAGE ) || ( pData->eType == MENUITEM_STRINGIMAGE ) ) )
    2700             :                     {
    2701           0 :                         if ( pWin->IsNativeControlSupported( CTRL_MENU_POPUP,
    2702             :                                                              (pData->nBits & MIB_RADIOCHECK)
    2703             :                                                              ? PART_MENU_ITEM_CHECK_MARK
    2704           0 :                                                              : PART_MENU_ITEM_RADIO_MARK ) )
    2705             :                         {
    2706             :                             ControlPart nPart = ((pData->nBits & MIB_RADIOCHECK)
    2707             :                                                  ? PART_MENU_ITEM_RADIO_MARK
    2708           0 :                                                  : PART_MENU_ITEM_CHECK_MARK);
    2709             : 
    2710           0 :                             ControlState nState = 0;
    2711             : 
    2712           0 :                             if ( pData->bChecked )
    2713           0 :                                 nState |= CTRL_STATE_PRESSED;
    2714             : 
    2715           0 :                             if ( pData->bEnabled )
    2716           0 :                                 nState |= CTRL_STATE_ENABLED;
    2717             : 
    2718           0 :                             if ( bHighlighted )
    2719           0 :                                 nState |= CTRL_STATE_SELECTED;
    2720             : 
    2721           0 :                             long nCtrlHeight = (pData->nBits & MIB_RADIOCHECK) ? nCheckHeight : nRadioHeight;
    2722           0 :                             aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - nCtrlHeight)/2;
    2723           0 :                             aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight)/2;
    2724             : 
    2725           0 :                             Rectangle aCheckRect( aTmpPos, Size( nCtrlHeight, nCtrlHeight ) );
    2726           0 :                             Size aSz( pData->aSz );
    2727           0 :                             aSz.Width() = aOutSz.Width() - 2*nOuterSpaceX;
    2728           0 :                             Rectangle aItemRect( aPos, aSz );
    2729           0 :                             MenupopupValue aVal( nTextPos-GUTTERBORDER, aItemRect );
    2730             :                             pWin->DrawNativeControl( CTRL_MENU_POPUP, nPart,
    2731             :                                                      aCheckRect,
    2732             :                                                      nState,
    2733             :                                                      aVal,
    2734           0 :                                                      OUString() );
    2735             :                         }
    2736           0 :                         else if ( pData->bChecked ) // by default do nothing for unchecked items
    2737             :                         {
    2738           0 :                             ImplPaintCheckBackground( pWin, aOuterCheckRect, pThisItemOnly && bHighlighted );
    2739             : 
    2740             :                             SymbolType eSymbol;
    2741           0 :                             Size aSymbolSize;
    2742           0 :                             if ( pData->nBits & MIB_RADIOCHECK )
    2743             :                             {
    2744           0 :                                 eSymbol = SYMBOL_RADIOCHECKMARK;
    2745           0 :                                 aSymbolSize = Size( nFontHeight/2, nFontHeight/2 );
    2746             :                             }
    2747             :                             else
    2748             :                             {
    2749           0 :                                 eSymbol = SYMBOL_CHECKMARK;
    2750           0 :                                 aSymbolSize = Size( (nFontHeight*25)/40, nFontHeight/2 );
    2751             :                             }
    2752           0 :                             aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - aSymbolSize.Width())/2;
    2753           0 :                             aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - aSymbolSize.Height())/2;
    2754           0 :                             Rectangle aRect( aTmpPos, aSymbolSize );
    2755           0 :                             aDecoView.DrawSymbol( aRect, eSymbol, pWin->GetTextColor(), nSymbolStyle );
    2756             :                         }
    2757             :                     }
    2758             :                 }
    2759             : 
    2760             :                 // Image:
    2761           0 :                 if ( !bLayout && !bIsMenuBar && ( ( pData->eType == MENUITEM_IMAGE ) || ( pData->eType == MENUITEM_STRINGIMAGE ) ) )
    2762             :                 {
    2763             :                     // Don't render an image for a check thing
    2764           0 :                     if( pData->bChecked )
    2765           0 :                         ImplPaintCheckBackground( pWin, aOuterCheckRect, pThisItemOnly && bHighlighted );
    2766           0 :                     aTmpPos = aOuterCheckRect.TopLeft();
    2767           0 :                     aTmpPos.X() += (aOuterCheckRect.GetWidth()-pData->aImage.GetSizePixel().Width())/2;
    2768           0 :                     aTmpPos.Y() += (aOuterCheckRect.GetHeight()-pData->aImage.GetSizePixel().Height())/2;
    2769           0 :                     pWin->DrawImage( aTmpPos, pData->aImage, nImageStyle );
    2770             :                 }
    2771             : 
    2772             :                 // Text:
    2773           0 :                 if ( ( pData->eType == MENUITEM_STRING ) || ( pData->eType == MENUITEM_STRINGIMAGE ) )
    2774             :                 {
    2775           0 :                     aTmpPos.X() = aPos.X() + nTextPos;
    2776           0 :                     aTmpPos.Y() = aPos.Y();
    2777           0 :                     aTmpPos.Y() += nTextOffsetY;
    2778           0 :                     sal_uInt16 nStyle = nTextStyle|TEXT_DRAW_MNEMONIC;
    2779           0 :                     if ( pData->bIsTemporary )
    2780           0 :                         nStyle |= TEXT_DRAW_DISABLE;
    2781           0 :                     MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
    2782           0 :                     String* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
    2783           0 :                     if( bLayout )
    2784             :                     {
    2785           0 :                         mpLayoutData->m_aLineIndices.push_back( mpLayoutData->m_aDisplayText.Len() );
    2786           0 :                         mpLayoutData->m_aLineItemIds.push_back( pData->nId );
    2787           0 :                         mpLayoutData->m_aLineItemPositions.push_back( n );
    2788             :                     }
    2789             :                     // #i47946# with NWF painted menus the background is transparent
    2790             :                     // since DrawCtrlText can depend on the background (e.g. for
    2791             :                     // TEXT_DRAW_DISABLE), temporarily set a background which
    2792             :                     // hopefully matches the NWF background since it is read
    2793             :                     // from the system style settings
    2794           0 :                     bool bSetTmpBackground = !pWin->IsBackground() && pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL );
    2795           0 :                     if( bSetTmpBackground )
    2796             :                     {
    2797             :                         Color aBg = bIsMenuBar ?
    2798           0 :                             pWin->GetSettings().GetStyleSettings().GetMenuBarColor() :
    2799           0 :                             pWin->GetSettings().GetStyleSettings().GetMenuColor();
    2800           0 :                         pWin->SetBackground( Wallpaper( aBg ) );
    2801             :                     }
    2802             :                     // how much space is there for the text ?
    2803           0 :                     long nMaxItemTextWidth = aOutSz.Width() - aTmpPos.X() - nExtra - nOuterSpaceX;
    2804           0 :                     if( !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() )
    2805             :                     {
    2806           0 :                         XubString aAccText = pData->aAccelKey.GetName();
    2807           0 :                         nMaxItemTextWidth -= pWin->GetTextWidth( aAccText ) + 3*nExtra;
    2808             :                     }
    2809           0 :                     if( !bIsMenuBar && pData->pSubMenu )
    2810             :                     {
    2811           0 :                         nMaxItemTextWidth -= nFontHeight - nExtra;
    2812             :                     }
    2813           0 :                     String aItemText( getShortenedString( pData->aText, pWin, nMaxItemTextWidth ) );
    2814           0 :                     pWin->DrawCtrlText( aTmpPos, aItemText, 0, aItemText.Len(), nStyle, pVector, pDisplayText );
    2815           0 :                     if( bSetTmpBackground )
    2816           0 :                         pWin->SetBackground();
    2817             :                 }
    2818             : 
    2819             :                 // Accel
    2820           0 :                 if ( !bLayout && !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() )
    2821             :                 {
    2822           0 :                     XubString aAccText = pData->aAccelKey.GetName();
    2823           0 :                     aTmpPos.X() = aOutSz.Width() - pWin->GetTextWidth( aAccText );
    2824           0 :                     aTmpPos.X() -= 4*nExtra;
    2825             : 
    2826           0 :                     aTmpPos.X() -= nOuterSpaceX;
    2827           0 :                     aTmpPos.Y() = aPos.Y();
    2828           0 :                     aTmpPos.Y() += nTextOffsetY;
    2829           0 :                     pWin->DrawCtrlText( aTmpPos, aAccText, 0, aAccText.Len(), nTextStyle );
    2830             :                 }
    2831             : 
    2832             :                 // SubMenu?
    2833           0 :                 if ( !bLayout && !bIsMenuBar && pData->pSubMenu )
    2834             :                 {
    2835           0 :                     bool bNativeOk = false;
    2836           0 :                     if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP,
    2837           0 :                                                         PART_MENU_SUBMENU_ARROW ) )
    2838             :                     {
    2839           0 :                         ControlState nState = 0;
    2840           0 :                         Size aTmpSz( 0, 0 );
    2841           0 :                         long aSpacing = 0;
    2842             : 
    2843           0 :                         if( !ImplGetNativeSubmenuArrowSize( pWin,
    2844           0 :                                                             aTmpSz, aSpacing ) )
    2845             :                         {
    2846           0 :                             aTmpSz = Size( nFontHeight, nFontHeight );
    2847           0 :                             aSpacing = nOuterSpaceX;
    2848             :                         }
    2849             : 
    2850           0 :                         if ( pData->bEnabled )
    2851           0 :                             nState |= CTRL_STATE_ENABLED;
    2852           0 :                         if ( bHighlighted )
    2853           0 :                             nState |= CTRL_STATE_SELECTED;
    2854             : 
    2855           0 :                         aTmpPos.X() = aOutSz.Width() - aTmpSz.Width() - aSpacing - nOuterSpaceX;
    2856           0 :                         aTmpPos.Y() = aPos.Y() + ( pData->aSz.Height() - aTmpSz.Height() ) / 2;
    2857           0 :                         aTmpPos.Y() += nExtra/2;
    2858             : 
    2859           0 :                         Rectangle aItemRect( aTmpPos, aTmpSz );
    2860           0 :                         MenupopupValue aVal( nTextPos-GUTTERBORDER, aItemRect );
    2861             :                         bNativeOk = pWin->DrawNativeControl( CTRL_MENU_POPUP,
    2862             :                                                              PART_MENU_SUBMENU_ARROW,
    2863             :                                                              aItemRect,
    2864             :                                                              nState,
    2865             :                                                              aVal,
    2866           0 :                                                              OUString() );
    2867             :                     }
    2868           0 :                     if( ! bNativeOk )
    2869             :                     {
    2870           0 :                         aTmpPos.X() = aOutSz.Width() - nFontHeight + nExtra - nOuterSpaceX;
    2871           0 :                         aTmpPos.Y() = aPos.Y();
    2872           0 :                         aTmpPos.Y() += nExtra/2;
    2873           0 :                         aTmpPos.Y() += ( pData->aSz.Height() / 2 ) - ( nFontHeight/4 );
    2874           0 :                         if ( pData->nBits & MIB_POPUPSELECT )
    2875             :                         {
    2876           0 :                             pWin->SetTextColor( rSettings.GetMenuTextColor() );
    2877           0 :                             Point aTmpPos2( aPos );
    2878           0 :                             aTmpPos2.X() = aOutSz.Width() - nFontHeight - nFontHeight/4;
    2879             :                             aDecoView.DrawFrame(
    2880           0 :                                 Rectangle( aTmpPos2, Size( nFontHeight+nFontHeight/4, pData->aSz.Height() ) ), FRAME_DRAW_GROUP );
    2881             :                         }
    2882             :                         aDecoView.DrawSymbol(
    2883             :                             Rectangle( aTmpPos, Size( nFontHeight/2, nFontHeight/2 ) ),
    2884           0 :                             SYMBOL_SPIN_RIGHT, pWin->GetTextColor(), nSymbolStyle );
    2885             :                     }
    2886             :                 }
    2887             : 
    2888           0 :                 if ( pThisItemOnly && bHighlighted )
    2889             :                 {
    2890             :                     // This restores the normal menu or menu bar text
    2891             :                     // color for when it is no longer highlighted.
    2892           0 :                     if ( bIsMenuBar )
    2893           0 :                         pWin->SetTextColor( rSettings.GetMenuBarTextColor() );
    2894             :                     else
    2895           0 :                         pWin->SetTextColor( rSettings.GetMenuTextColor() );
    2896             :                 }
    2897             :             }
    2898           0 :             if( bLayout )
    2899             :             {
    2900           0 :                 if ( !bIsMenuBar )
    2901           0 :                     mpLayoutData->m_aVisibleItemBoundRects[ n ] = Rectangle( aTopLeft, Size( aOutSz.Width(), pData->aSz.Height() ) );
    2902             :                 else
    2903           0 :                     mpLayoutData->m_aVisibleItemBoundRects[ n ] = Rectangle( aTopLeft, pData->aSz );
    2904             :             }
    2905             :         }
    2906             : 
    2907           0 :         if ( !bIsMenuBar )
    2908             :         {
    2909           0 :             aTopLeft.Y() += pData->aSz.Height();
    2910             :         }
    2911             :         else
    2912             :         {
    2913           0 :             aTopLeft.X() += pData->aSz.Width();
    2914             :         }
    2915             :     }
    2916             : 
    2917         177 :     if ( !bLayout && !pThisItemOnly && pLogo )
    2918             :     {
    2919           0 :         Size aLogoSz = pLogo->aBitmap.GetSizePixel();
    2920             : 
    2921           0 :         Rectangle aRect( Point( 0, 0 ), Point( aLogoSz.Width()-1, aOutSz.Height() ) );
    2922           0 :         if ( pWin->GetColorCount() >= 256 )
    2923             :         {
    2924           0 :             Gradient aGrad( GradientStyle_LINEAR, pLogo->aStartColor, pLogo->aEndColor );
    2925           0 :             aGrad.SetAngle( 1800 );
    2926           0 :             aGrad.SetBorder( 15 );
    2927           0 :             pWin->DrawGradient( aRect, aGrad );
    2928             :         }
    2929             :         else
    2930             :         {
    2931           0 :             pWin->SetFillColor( pLogo->aStartColor );
    2932           0 :             pWin->DrawRect( aRect );
    2933             :         }
    2934             : 
    2935           0 :         Point aLogoPos( 0, aOutSz.Height() - aLogoSz.Height() );
    2936           0 :         pLogo->aBitmap.Draw( pWin, aLogoPos );
    2937             :     }
    2938         177 : }
    2939             : 
    2940           0 : Menu* Menu::ImplGetStartMenu()
    2941             : {
    2942           0 :     Menu* pStart = this;
    2943           0 :     while ( pStart && pStart->pStartedFrom && ( pStart->pStartedFrom != pStart ) )
    2944           0 :         pStart = pStart->pStartedFrom;
    2945           0 :     return pStart;
    2946             : }
    2947             : 
    2948           0 : void Menu::ImplCallHighlight( sal_uInt16 nHighlightedItem )
    2949             : {
    2950           0 :     ImplMenuDelData aDelData( this );
    2951             : 
    2952           0 :     nSelectedId = 0;
    2953           0 :     MenuItemData* pData = pItemList->GetDataFromPos( nHighlightedItem );
    2954           0 :     if ( pData )
    2955           0 :         nSelectedId = pData->nId;
    2956           0 :     ImplCallEventListeners( VCLEVENT_MENU_HIGHLIGHT, GetItemPos( GetCurItemId() ) );
    2957             : 
    2958           0 :     if( !aDelData.isDeleted() )
    2959             :     {
    2960           0 :         Highlight();
    2961           0 :         nSelectedId = 0;
    2962           0 :     }
    2963           0 : }
    2964             : 
    2965           0 : IMPL_LINK_NOARG(Menu, ImplCallSelect)
    2966             : {
    2967           0 :     nEventId = 0;
    2968           0 :     Select();
    2969           0 :     return 0;
    2970             : }
    2971             : 
    2972           0 : Menu* Menu::ImplFindSelectMenu()
    2973             : {
    2974           0 :     Menu* pSelMenu = nEventId ? this : NULL;
    2975             : 
    2976           0 :     for ( size_t n = GetItemList()->size(); n && !pSelMenu; )
    2977             :     {
    2978           0 :         MenuItemData* pData = GetItemList()->GetDataFromPos( --n );
    2979             : 
    2980           0 :         if ( pData->pSubMenu )
    2981           0 :             pSelMenu = pData->pSubMenu->ImplFindSelectMenu();
    2982             :     }
    2983             : 
    2984           0 :     return pSelMenu;
    2985             : }
    2986             : 
    2987           0 : Menu* Menu::ImplFindMenu( sal_uInt16 nItemId )
    2988             : {
    2989           0 :     Menu* pSelMenu = NULL;
    2990             : 
    2991           0 :     for ( size_t n = GetItemList()->size(); n && !pSelMenu; )
    2992             :     {
    2993           0 :         MenuItemData* pData = GetItemList()->GetDataFromPos( --n );
    2994             : 
    2995           0 :         if( pData->nId == nItemId )
    2996           0 :             pSelMenu = this;
    2997           0 :         else if ( pData->pSubMenu )
    2998           0 :             pSelMenu = pData->pSubMenu->ImplFindMenu( nItemId );
    2999             :     }
    3000             : 
    3001           0 :     return pSelMenu;
    3002             : }
    3003             : 
    3004           0 : void Menu::RemoveDisabledEntries( sal_Bool bCheckPopups, sal_Bool bRemoveEmptyPopups )
    3005             : {
    3006           0 :     for ( sal_uInt16 n = 0; n < GetItemCount(); n++ )
    3007             :     {
    3008           0 :         sal_Bool bRemove = sal_False;
    3009           0 :         MenuItemData* pItem = pItemList->GetDataFromPos( n );
    3010           0 :         if ( pItem->eType == MENUITEM_SEPARATOR )
    3011             :         {
    3012           0 :             if ( !n || ( GetItemType( n-1 ) == MENUITEM_SEPARATOR ) )
    3013           0 :                 bRemove = sal_True;
    3014             :         }
    3015             :         else
    3016           0 :             bRemove = !pItem->bEnabled;
    3017             : 
    3018           0 :         if ( bCheckPopups && pItem->pSubMenu )
    3019             :         {
    3020           0 :             pItem->pSubMenu->RemoveDisabledEntries( sal_True );
    3021           0 :             if ( bRemoveEmptyPopups && !pItem->pSubMenu->GetItemCount() )
    3022           0 :                 bRemove = sal_True;
    3023             :         }
    3024             : 
    3025           0 :         if ( bRemove )
    3026           0 :             RemoveItem( n-- );
    3027             :     }
    3028             : 
    3029           0 :     if ( GetItemCount() )
    3030             :     {
    3031           0 :         sal_uInt16 nLast = GetItemCount() - 1;
    3032           0 :         MenuItemData* pItem = pItemList->GetDataFromPos( nLast );
    3033           0 :         if ( pItem->eType == MENUITEM_SEPARATOR )
    3034           0 :             RemoveItem( nLast );
    3035             :     }
    3036           0 :     delete mpLayoutData, mpLayoutData = NULL;
    3037           0 : }
    3038             : 
    3039           0 : sal_Bool Menu::HasValidEntries( sal_Bool bCheckPopups )
    3040             : {
    3041           0 :     sal_Bool bValidEntries = sal_False;
    3042           0 :     sal_uInt16 nCount = GetItemCount();
    3043           0 :     for ( sal_uInt16 n = 0; !bValidEntries && ( n < nCount ); n++ )
    3044             :     {
    3045           0 :         MenuItemData* pItem = pItemList->GetDataFromPos( n );
    3046           0 :         if ( pItem->bEnabled && ( pItem->eType != MENUITEM_SEPARATOR ) )
    3047             :         {
    3048           0 :             if ( bCheckPopups && pItem->pSubMenu )
    3049           0 :                 bValidEntries = pItem->pSubMenu->HasValidEntries( sal_True );
    3050             :             else
    3051           0 :                 bValidEntries = sal_True;
    3052             :         }
    3053             :     }
    3054           0 :     return bValidEntries;
    3055             : }
    3056             : 
    3057           0 : void Menu::SetLogo( const MenuLogo& rLogo )
    3058             : {
    3059           0 :     delete pLogo;
    3060           0 :     pLogo = new MenuLogo( rLogo );
    3061           0 : }
    3062             : 
    3063           0 : void Menu::SetLogo()
    3064             : {
    3065           0 :     delete pLogo;
    3066           0 :     pLogo = NULL;
    3067           0 : }
    3068             : 
    3069           0 : MenuLogo Menu::GetLogo() const
    3070             : {
    3071           0 :     MenuLogo aLogo;
    3072           0 :     if ( pLogo )
    3073           0 :         aLogo = *pLogo;
    3074           0 :     return aLogo;
    3075             : }
    3076             : 
    3077         582 : void Menu::ImplKillLayoutData() const
    3078             : {
    3079         582 :     delete mpLayoutData, mpLayoutData = NULL;
    3080         582 : }
    3081             : 
    3082           0 : void Menu::ImplFillLayoutData() const
    3083             : {
    3084           0 :     if( pWindow && pWindow->IsReallyVisible() )
    3085             :     {
    3086           0 :         mpLayoutData = new MenuLayoutData();
    3087           0 :         if( bIsMenuBar )
    3088             :         {
    3089           0 :             ImplPaint( pWindow, 0, 0, 0, sal_False, true );
    3090             :         }
    3091             :         else
    3092             :         {
    3093           0 :             MenuFloatingWindow* pFloat = (MenuFloatingWindow*)pWindow;
    3094           0 :             ImplPaint( pWindow, pFloat->nScrollerHeight, pFloat->ImplGetStartY(), 0, sal_False, true );
    3095             :         }
    3096             :     }
    3097           0 : }
    3098             : 
    3099           0 : Rectangle Menu::GetCharacterBounds( sal_uInt16 nItemID, long nIndex ) const
    3100             : {
    3101           0 :     long nItemIndex = -1;
    3102           0 :     if( ! mpLayoutData )
    3103           0 :         ImplFillLayoutData();
    3104           0 :     if( mpLayoutData )
    3105             :     {
    3106           0 :         for( size_t i = 0; i < mpLayoutData->m_aLineItemIds.size(); i++ )
    3107             :         {
    3108           0 :             if( mpLayoutData->m_aLineItemIds[i] == nItemID )
    3109             :             {
    3110           0 :                 nItemIndex = mpLayoutData->m_aLineIndices[i];
    3111           0 :                 break;
    3112             :             }
    3113             :         }
    3114             :     }
    3115           0 :     return (mpLayoutData && nItemIndex != -1) ? mpLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : Rectangle();
    3116             : }
    3117             : 
    3118             : 
    3119           0 : long Menu::GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const
    3120             : {
    3121           0 :     long nIndex = -1;
    3122           0 :     rItemID = 0;
    3123           0 :     if( ! mpLayoutData )
    3124           0 :         ImplFillLayoutData();
    3125           0 :     if( mpLayoutData )
    3126             :     {
    3127           0 :         nIndex = mpLayoutData->GetIndexForPoint( rPoint );
    3128           0 :         for( size_t i = 0; i < mpLayoutData->m_aLineIndices.size(); i++ )
    3129             :         {
    3130           0 :             if( mpLayoutData->m_aLineIndices[i] <= nIndex &&
    3131           0 :                 (i == mpLayoutData->m_aLineIndices.size()-1 || mpLayoutData->m_aLineIndices[i+1] > nIndex) )
    3132             :             {
    3133             :                 // make index relative to item
    3134           0 :                 nIndex -= mpLayoutData->m_aLineIndices[i];
    3135           0 :                 rItemID = mpLayoutData->m_aLineItemIds[i];
    3136           0 :                 break;
    3137             :             }
    3138             :         }
    3139             :     }
    3140           0 :     return nIndex;
    3141             : }
    3142             : 
    3143           0 : Rectangle Menu::GetBoundingRectangle( sal_uInt16 nPos ) const
    3144             : {
    3145           0 :     Rectangle aRet;
    3146             : 
    3147           0 :     if( ! mpLayoutData )
    3148           0 :         ImplFillLayoutData();
    3149           0 :     if( mpLayoutData )
    3150             :     {
    3151           0 :         std::map< sal_uInt16, Rectangle >::const_iterator it = mpLayoutData->m_aVisibleItemBoundRects.find( nPos );
    3152           0 :         if( it != mpLayoutData->m_aVisibleItemBoundRects.end() )
    3153           0 :             aRet = it->second;
    3154             :     }
    3155           0 :     return aRet;
    3156             : }
    3157             : 
    3158           0 : void Menu::SetAccessibleName( sal_uInt16 nItemId, const XubString& rStr )
    3159             : {
    3160             :     size_t        nPos;
    3161           0 :     MenuItemData* pData = pItemList->GetData( nItemId, nPos );
    3162             : 
    3163           0 :     if ( pData && !rStr.Equals( pData->aAccessibleName ) )
    3164             :     {
    3165           0 :         pData->aAccessibleName = rStr;
    3166           0 :         ImplCallEventListeners( VCLEVENT_MENU_ACCESSIBLENAMECHANGED, nPos );
    3167             :     }
    3168           0 : }
    3169             : 
    3170           0 : XubString Menu::GetAccessibleName( sal_uInt16 nItemId ) const
    3171             : {
    3172           0 :     MenuItemData* pData = pItemList->GetData( nItemId );
    3173             : 
    3174           0 :     if ( pData )
    3175           0 :         return pData->aAccessibleName;
    3176             :     else
    3177           0 :         return ImplGetSVEmptyStr();
    3178             : }
    3179             : 
    3180         556 : void Menu::ImplSetSalMenu( SalMenu *pSalMenu )
    3181             : {
    3182         556 :     if( mpSalMenu )
    3183           0 :         ImplGetSVData()->mpDefInst->DestroyMenu( mpSalMenu );
    3184         556 :     mpSalMenu = pSalMenu;
    3185         556 : }
    3186             : 
    3187           0 : sal_Bool Menu::GetSystemMenuData( SystemMenuData* pData ) const
    3188             : {
    3189           0 :     Menu* pMenu = (Menu*)this;
    3190           0 :     if( pData && pMenu->ImplGetSalMenu() )
    3191             :     {
    3192           0 :         pMenu->ImplGetSalMenu()->GetSystemMenuData( pData );
    3193           0 :         return sal_True;
    3194             :     }
    3195             :     else
    3196           0 :         return sal_False;
    3197             : }
    3198             : 
    3199           0 : bool Menu::IsHighlighted( sal_uInt16 nItemPos ) const
    3200             : {
    3201           0 :     bool bRet = false;
    3202             : 
    3203           0 :     if( pWindow )
    3204             :     {
    3205           0 :         if( bIsMenuBar )
    3206           0 :             bRet = ( nItemPos == static_cast< MenuBarWindow * > (pWindow)->GetHighlightedItem() );
    3207             :         else
    3208           0 :             bRet = ( nItemPos == static_cast< MenuFloatingWindow * > (pWindow)->GetHighlightedItem() );
    3209             :     }
    3210             : 
    3211           0 :     return bRet;
    3212             : }
    3213             : 
    3214           0 : void Menu::HighlightItem( sal_uInt16 nItemPos )
    3215             : {
    3216           0 :     if ( pWindow )
    3217             :     {
    3218           0 :         if ( bIsMenuBar )
    3219             :         {
    3220           0 :             MenuBarWindow* pMenuWin = static_cast< MenuBarWindow* >( pWindow );
    3221           0 :             pMenuWin->SetAutoPopup( sal_False );
    3222           0 :             pMenuWin->ChangeHighlightItem( nItemPos, sal_False );
    3223             :         }
    3224             :         else
    3225             :         {
    3226           0 :             static_cast< MenuFloatingWindow* >( pWindow )->ChangeHighlightItem( nItemPos, sal_False );
    3227             :         }
    3228             :     }
    3229           0 : }
    3230             : 
    3231             : 
    3232             : // -----------
    3233             : // - MenuBar -
    3234             : // -----------
    3235             : 
    3236         236 : MenuBar::MenuBar() : Menu( sal_True )
    3237             : {
    3238         236 :     mbDisplayable       = sal_True;
    3239         236 :     mbCloserVisible     = sal_False;
    3240         236 :     mbFloatBtnVisible   = sal_False;
    3241         236 :     mbHideBtnVisible    = sal_False;
    3242         236 : }
    3243             : 
    3244           0 : MenuBar::MenuBar( const MenuBar& rMenu ) : Menu( sal_True )
    3245             : {
    3246           0 :     mbDisplayable       = sal_True;
    3247           0 :     mbCloserVisible     = sal_False;
    3248           0 :     mbFloatBtnVisible   = sal_False;
    3249           0 :     mbHideBtnVisible    = sal_False;
    3250           0 :     *this               = rMenu;
    3251           0 :     bIsMenuBar          = sal_True;
    3252           0 : }
    3253             : 
    3254         189 : MenuBar::~MenuBar()
    3255             : {
    3256          63 :     ImplDestroy( this, sal_True );
    3257         126 : }
    3258             : 
    3259         253 : void MenuBar::ShowCloser( sal_Bool bShow )
    3260             : {
    3261         253 :     ShowButtons( bShow, mbFloatBtnVisible, mbHideBtnVisible );
    3262         253 : }
    3263             : 
    3264         253 : void MenuBar::ShowButtons( sal_Bool bClose, sal_Bool bFloat, sal_Bool bHide )
    3265             : {
    3266         253 :     if ( (bClose != mbCloserVisible)    ||
    3267             :          (bFloat != mbFloatBtnVisible)  ||
    3268             :          (bHide  != mbHideBtnVisible) )
    3269             :     {
    3270          25 :         mbCloserVisible     = bClose;
    3271          25 :         mbFloatBtnVisible   = bFloat;
    3272          25 :         mbHideBtnVisible    = bHide;
    3273          25 :         if ( ImplGetWindow() )
    3274          25 :             ((MenuBarWindow*)ImplGetWindow())->ShowButtons( bClose, bFloat, bHide );
    3275             :     }
    3276         253 : }
    3277             : 
    3278         236 : void MenuBar::SetDisplayable( sal_Bool bDisplayable )
    3279             : {
    3280         236 :     if( bDisplayable != mbDisplayable )
    3281             :     {
    3282           0 :         mbDisplayable = bDisplayable;
    3283           0 :         MenuBarWindow* pMenuWin = (MenuBarWindow*) ImplGetWindow();
    3284           0 :         if( pMenuWin )
    3285           0 :             pMenuWin->ImplLayoutChanged();
    3286             :     }
    3287         236 : }
    3288             : 
    3289         236 : Window* MenuBar::ImplCreate( Window* pParent, Window* pWindow, MenuBar* pMenu )
    3290             : {
    3291         236 :     if ( !pWindow )
    3292         236 :         pWindow = new MenuBarWindow( pParent );
    3293             : 
    3294         236 :     pMenu->pStartedFrom = 0;
    3295         236 :     pMenu->pWindow = pWindow;
    3296         236 :     ((MenuBarWindow*)pWindow)->SetMenu( pMenu );
    3297         236 :     long nHeight = pMenu->ImplCalcSize( pWindow ).Height();
    3298             : 
    3299             :     // depending on the native implementation or the displayable flag
    3300             :     // the menubar windows is supressed (ie, height=0)
    3301         472 :     if( !((MenuBar*) pMenu)->IsDisplayable() ||
    3302         236 :         ( pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar() ) )
    3303           0 :         nHeight = 0;
    3304             : 
    3305         236 :     pWindow->setPosSizePixel( 0, 0, 0, nHeight, WINDOW_POSSIZE_HEIGHT );
    3306         236 :     return pWindow;
    3307             : }
    3308             : 
    3309         126 : void MenuBar::ImplDestroy( MenuBar* pMenu, sal_Bool bDelete )
    3310             : {
    3311         126 :     MenuBarWindow* pWindow = (MenuBarWindow*) pMenu->ImplGetWindow();
    3312         126 :     if ( pWindow && bDelete )
    3313             :     {
    3314          63 :         pWindow->KillActivePopup();
    3315          63 :         delete pWindow;
    3316             :     }
    3317         126 :     pMenu->pWindow = NULL;
    3318         126 : }
    3319             : 
    3320           0 : sal_Bool MenuBar::ImplHandleKeyEvent( const KeyEvent& rKEvent, sal_Bool bFromMenu )
    3321             : {
    3322           0 :     sal_Bool bDone = sal_False;
    3323             : 
    3324             :     // No keyboard processing when system handles the menu or our menubar is invisible
    3325           0 :     if( !IsDisplayable() ||
    3326           0 :         ( ImplGetSalMenu() && ImplGetSalMenu()->VisibleMenuBar() ) )
    3327           0 :         return bDone;
    3328             : 
    3329             :     // check for enabled, if this method is called from another window...
    3330           0 :     Window* pWin = ImplGetWindow();
    3331           0 :     if ( pWin && pWin->IsEnabled() && pWin->IsInputEnabled()  && ! pWin->IsInModalMode() )
    3332           0 :         bDone = ((MenuBarWindow*)pWin)->ImplHandleKeyEvent( rKEvent, bFromMenu );
    3333           0 :     return bDone;
    3334             : }
    3335             : 
    3336             : // -----------------------------------------------------------------------
    3337             : 
    3338           0 : void MenuBar::SelectEntry( sal_uInt16 nId )
    3339             : {
    3340           0 :     MenuBarWindow* pMenuWin = (MenuBarWindow*) ImplGetWindow();
    3341             : 
    3342           0 :     if( pMenuWin )
    3343             :     {
    3344           0 :         pMenuWin->GrabFocus();
    3345           0 :         nId = GetItemPos( nId );
    3346             : 
    3347             :         // #99705# popup the selected menu
    3348           0 :         pMenuWin->SetAutoPopup( sal_True );
    3349           0 :         if( ITEMPOS_INVALID != pMenuWin->nHighlightedItem )
    3350             :         {
    3351           0 :             pMenuWin->KillActivePopup();
    3352           0 :             pMenuWin->ChangeHighlightItem( ITEMPOS_INVALID, sal_False );
    3353             :         }
    3354           0 :         if( nId != ITEMPOS_INVALID )
    3355           0 :             pMenuWin->ChangeHighlightItem( nId, sal_False );
    3356             :     }
    3357           0 : }
    3358             : 
    3359             : // -----------------------------------------------------------------------
    3360             : 
    3361             : // handler for native menu selection and command events
    3362             : 
    3363           0 : sal_Bool MenuBar::HandleMenuActivateEvent( Menu *pMenu ) const
    3364             : {
    3365           0 :     if( pMenu )
    3366             :     {
    3367           0 :         ImplMenuDelData aDelData( this );
    3368             : 
    3369           0 :         pMenu->pStartedFrom = (Menu*)this;
    3370           0 :         pMenu->bInCallback = sal_True;
    3371           0 :         pMenu->Activate();
    3372             : 
    3373           0 :         if( !aDelData.isDeleted() )
    3374           0 :             pMenu->bInCallback = sal_False;
    3375             :     }
    3376           0 :     return sal_True;
    3377             : }
    3378             : 
    3379           0 : sal_Bool MenuBar::HandleMenuDeActivateEvent( Menu *pMenu ) const
    3380             : {
    3381           0 :     if( pMenu )
    3382             :     {
    3383           0 :         ImplMenuDelData aDelData( this );
    3384             : 
    3385           0 :         pMenu->pStartedFrom = (Menu*)this;
    3386           0 :         pMenu->bInCallback = sal_True;
    3387           0 :         pMenu->Deactivate();
    3388           0 :         if( !aDelData.isDeleted() )
    3389           0 :             pMenu->bInCallback = sal_False;
    3390             :     }
    3391           0 :     return sal_True;
    3392             : }
    3393             : 
    3394           0 : sal_Bool MenuBar::HandleMenuHighlightEvent( Menu *pMenu, sal_uInt16 nHighlightEventId ) const
    3395             : {
    3396           0 :     if( !pMenu )
    3397           0 :         pMenu = ((Menu*) this)->ImplFindMenu( nHighlightEventId );
    3398           0 :     if( pMenu )
    3399             :     {
    3400           0 :         ImplMenuDelData aDelData( pMenu );
    3401             : 
    3402           0 :         if( mnHighlightedItemPos != ITEMPOS_INVALID )
    3403           0 :             pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, mnHighlightedItemPos );
    3404             : 
    3405           0 :         if( !aDelData.isDeleted() )
    3406             :         {
    3407           0 :             pMenu->mnHighlightedItemPos = pMenu->GetItemPos( nHighlightEventId );
    3408           0 :             pMenu->nSelectedId = nHighlightEventId;
    3409           0 :             pMenu->pStartedFrom = (Menu*)this;
    3410           0 :             pMenu->ImplCallHighlight( pMenu->mnHighlightedItemPos );
    3411             :         }
    3412           0 :         return sal_True;
    3413             :     }
    3414             :     else
    3415           0 :         return sal_False;
    3416             : }
    3417             : 
    3418           0 : sal_Bool MenuBar::HandleMenuCommandEvent( Menu *pMenu, sal_uInt16 nCommandEventId ) const
    3419             : {
    3420           0 :     if( !pMenu )
    3421           0 :         pMenu = ((Menu*) this)->ImplFindMenu( nCommandEventId );
    3422           0 :     if( pMenu )
    3423             :     {
    3424           0 :         pMenu->nSelectedId = nCommandEventId;
    3425           0 :         pMenu->pStartedFrom = (Menu*)this;
    3426           0 :         pMenu->ImplSelect();
    3427           0 :         return sal_True;
    3428             :     }
    3429             :     else
    3430           0 :         return sal_False;
    3431             : }
    3432             : 
    3433           0 : sal_uInt16 MenuBar::AddMenuBarButton( const Image& i_rImage, const Link& i_rLink, const String& i_rToolTip, sal_uInt16 i_nPos )
    3434             : {
    3435           0 :     return pWindow ? static_cast<MenuBarWindow*>(pWindow)->AddMenuBarButton( i_rImage, i_rLink, i_rToolTip, i_nPos ) : 0;
    3436             : }
    3437             : 
    3438           0 : void MenuBar::SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link& rLink )
    3439             : {
    3440           0 :     if( pWindow )
    3441           0 :         static_cast<MenuBarWindow*>(pWindow)->SetMenuBarButtonHighlightHdl( nId, rLink );
    3442           0 : }
    3443             : 
    3444           0 : Rectangle MenuBar::GetMenuBarButtonRectPixel( sal_uInt16 nId )
    3445             : {
    3446           0 :     return pWindow ? static_cast<MenuBarWindow*>(pWindow)->GetMenuBarButtonRectPixel( nId ) : Rectangle();
    3447             : }
    3448             : 
    3449           0 : void MenuBar::RemoveMenuBarButton( sal_uInt16 nId )
    3450             : {
    3451           0 :     if( pWindow )
    3452           0 :         static_cast<MenuBarWindow*>(pWindow)->RemoveMenuBarButton( nId );
    3453           0 : }
    3454             : 
    3455           0 : sal_Bool MenuBar::HandleMenuButtonEvent( Menu *, sal_uInt16 i_nButtonId ) const
    3456             : {
    3457           0 :     return static_cast<MenuBarWindow*>(pWindow)->HandleMenuButtonEvent( i_nButtonId );
    3458             : }
    3459             : 
    3460             : // -----------------------------------------------------------------------
    3461             : 
    3462             : // sal_Bool PopupMenu::bAnyPopupInExecute = sal_False;
    3463             : 
    3464        1203 : PopupMenu::PopupMenu()
    3465             : {
    3466        1203 :     pRefAutoSubMenu = NULL;
    3467        1203 : }
    3468             : 
    3469          19 : PopupMenu::PopupMenu( const ResId& rResId )
    3470             : {
    3471          19 :     pRefAutoSubMenu = NULL;
    3472          19 :     ImplLoadRes( rResId );
    3473          19 : }
    3474             : 
    3475           0 : PopupMenu::PopupMenu( const PopupMenu& rMenu ) : Menu()
    3476             : {
    3477           0 :     pRefAutoSubMenu = NULL;
    3478           0 :     *this = rMenu;
    3479           0 : }
    3480             : 
    3481        1479 : PopupMenu::~PopupMenu()
    3482             : {
    3483         493 :     if( pRefAutoSubMenu && *pRefAutoSubMenu == this )
    3484           0 :         *pRefAutoSubMenu = NULL;    // #111060# avoid second delete in ~MenuItemData
    3485         986 : }
    3486             : 
    3487           0 : sal_Bool PopupMenu::IsInExecute()
    3488             : {
    3489           0 :     return GetActivePopupMenu() ? sal_True : sal_False;
    3490             : }
    3491             : 
    3492           0 : PopupMenu* PopupMenu::GetActivePopupMenu()
    3493             : {
    3494           0 :     ImplSVData* pSVData = ImplGetSVData();
    3495           0 :     return pSVData->maAppData.mpActivePopupMenu;
    3496             : }
    3497             : 
    3498           0 : void PopupMenu::EndExecute( sal_uInt16 nSelectId )
    3499             : {
    3500           0 :     if ( ImplGetWindow() )
    3501           0 :         ImplGetFloatingWindow()->EndExecute( nSelectId );
    3502           0 : }
    3503             : 
    3504           0 : void PopupMenu::SelectEntry( sal_uInt16 nId )
    3505             : {
    3506           0 :     if ( ImplGetWindow() )
    3507             :     {
    3508           0 :         if( nId != ITEMPOS_INVALID )
    3509             :         {
    3510           0 :             size_t nPos = 0;
    3511           0 :             MenuItemData* pData = GetItemList()->GetData( nId, nPos );
    3512           0 :             if ( pData->pSubMenu )
    3513           0 :                 ImplGetFloatingWindow()->ChangeHighlightItem( nPos, sal_True );
    3514             :             else
    3515           0 :                 ImplGetFloatingWindow()->EndExecute( nId );
    3516             :         }
    3517             :         else
    3518             :         {
    3519           0 :             MenuFloatingWindow* pFloat = ImplGetFloatingWindow();
    3520           0 :             pFloat->GrabFocus();
    3521             : 
    3522           0 :             for( size_t nPos = 0; nPos < GetItemList()->size(); nPos++ )
    3523             :             {
    3524           0 :                 MenuItemData* pData = GetItemList()->GetDataFromPos( nPos );
    3525           0 :                 if( pData->pSubMenu )
    3526             :                 {
    3527           0 :                     pFloat->KillActivePopup();
    3528             :                 }
    3529             :             }
    3530           0 :             pFloat->ChangeHighlightItem( ITEMPOS_INVALID, sal_False );
    3531             :         }
    3532             :     }
    3533           0 : }
    3534             : 
    3535           0 : void PopupMenu::SetSelectedEntry( sal_uInt16 nId )
    3536             : {
    3537           0 :     nSelectedId = nId;
    3538           0 : }
    3539             : 
    3540           0 : sal_uInt16 PopupMenu::Execute( Window* pExecWindow, const Point& rPopupPos )
    3541             : {
    3542           0 :     return Execute( pExecWindow, Rectangle( rPopupPos, rPopupPos ), POPUPMENU_EXECUTE_DOWN );
    3543             : }
    3544             : 
    3545           0 : sal_uInt16 PopupMenu::Execute( Window* pExecWindow, const Rectangle& rRect, sal_uInt16 nFlags )
    3546             : {
    3547           0 :     ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL window!", 0 );
    3548             : 
    3549             : 
    3550           0 :     sal_uLong nPopupModeFlags = 0;
    3551           0 :     if ( nFlags & POPUPMENU_EXECUTE_DOWN )
    3552           0 :         nPopupModeFlags = FLOATWIN_POPUPMODE_DOWN;
    3553           0 :     else if ( nFlags & POPUPMENU_EXECUTE_UP )
    3554           0 :         nPopupModeFlags = FLOATWIN_POPUPMODE_UP;
    3555           0 :     else if ( nFlags & POPUPMENU_EXECUTE_LEFT )
    3556           0 :         nPopupModeFlags = FLOATWIN_POPUPMODE_LEFT;
    3557           0 :     else if ( nFlags & POPUPMENU_EXECUTE_RIGHT )
    3558           0 :         nPopupModeFlags = FLOATWIN_POPUPMODE_RIGHT;
    3559             :     else
    3560           0 :         nPopupModeFlags = FLOATWIN_POPUPMODE_DOWN;
    3561             : 
    3562           0 :     if (nFlags & POPUPMENU_NOMOUSEUPCLOSE )                      // allow popup menus to stay open on mouse button up
    3563           0 :         nPopupModeFlags |= FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE;    // useful if the menu was opened on mousebutton down (eg toolbox configuration)
    3564             : 
    3565           0 :     return ImplExecute( pExecWindow, rRect, nPopupModeFlags, 0, sal_False );
    3566             : }
    3567             : 
    3568           0 : sal_uInt16 PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, sal_uLong nPopupModeFlags, Menu* pSFrom, sal_Bool bPreSelectFirst )
    3569             : {
    3570           0 :     if ( !pSFrom && ( PopupMenu::IsInExecute() || !GetItemCount() ) )
    3571           0 :         return 0;
    3572             : 
    3573           0 :     delete mpLayoutData, mpLayoutData = NULL;
    3574             : 
    3575           0 :     ImplSVData* pSVData = ImplGetSVData();
    3576             : 
    3577           0 :     pStartedFrom = pSFrom;
    3578           0 :     nSelectedId = 0;
    3579           0 :     bCanceled = sal_False;
    3580             : 
    3581           0 :     sal_uLong nFocusId = 0;
    3582           0 :     sal_Bool bRealExecute = sal_False;
    3583           0 :     if ( !pStartedFrom )
    3584             :     {
    3585           0 :         pSVData->maWinData.mbNoDeactivate = sal_True;
    3586           0 :         nFocusId = Window::SaveFocus();
    3587           0 :         bRealExecute = sal_True;
    3588             :     }
    3589             :     else
    3590             :     {
    3591             :         // assure that only one menu is open at a time
    3592           0 :         if( pStartedFrom->bIsMenuBar && pSVData->maWinData.mpFirstFloat )
    3593           0 :             pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
    3594             :     }
    3595             : 
    3596             :     DBG_ASSERT( !ImplGetWindow(), "Win?!" );
    3597           0 :     Rectangle aRect( rRect );
    3598           0 :     aRect.SetPos( pW->OutputToScreenPixel( aRect.TopLeft() ) );
    3599             : 
    3600           0 :     WinBits nStyle = WB_BORDER;
    3601           0 :     if ( bRealExecute )
    3602           0 :         nPopupModeFlags |= FLOATWIN_POPUPMODE_NEWLEVEL;
    3603           0 :     if ( !pStartedFrom || !pStartedFrom->bIsMenuBar )
    3604           0 :         nPopupModeFlags |= FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK | FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE;
    3605             : 
    3606           0 :     nPopupModeFlags |= FLOATWIN_POPUPMODE_NOKEYCLOSE;
    3607             : 
    3608             :     // could be usefull during debugging.
    3609             :     // nPopupModeFlags |= FLOATWIN_POPUPMODE_NOFOCUSCLOSE;
    3610             : 
    3611           0 :     ImplDelData aDelData;
    3612           0 :     pW->ImplAddDel( &aDelData );
    3613             : 
    3614           0 :     bInCallback = sal_True; // set it here, if Activate overloaded
    3615           0 :     Activate();
    3616           0 :     bInCallback = sal_False;
    3617             : 
    3618           0 :     if ( aDelData.IsDead() )
    3619           0 :         return 0;   // Error
    3620             : 
    3621           0 :     pW->ImplRemoveDel( &aDelData );
    3622             : 
    3623           0 :     if ( bCanceled || bKilled )
    3624           0 :         return 0;
    3625             : 
    3626           0 :     if ( !GetItemCount() )
    3627           0 :         return 0;
    3628             : 
    3629             :     // The flag MENU_FLAG_HIDEDISABLEDENTRIES is inherited.
    3630           0 :     if ( pSFrom )
    3631             :     {
    3632           0 :         if ( pSFrom->nMenuFlags & MENU_FLAG_HIDEDISABLEDENTRIES )
    3633           0 :             nMenuFlags |= MENU_FLAG_HIDEDISABLEDENTRIES;
    3634             :         else
    3635           0 :             nMenuFlags &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
    3636             :     }
    3637             :     else
    3638             :         // #102790# context menus shall never show disabled entries
    3639           0 :         nMenuFlags |= MENU_FLAG_HIDEDISABLEDENTRIES;
    3640             : 
    3641             : 
    3642           0 :     sal_uInt16 nVisibleEntries = ImplGetVisibleItemCount();
    3643           0 :     if ( !nVisibleEntries )
    3644             :     {
    3645           0 :         ResMgr* pResMgr = ImplGetResMgr();
    3646           0 :         if( pResMgr )
    3647             :         {
    3648           0 :             rtl::OUString aTmpEntryText( ResId( SV_RESID_STRING_NOSELECTIONPOSSIBLE, *pResMgr ) );
    3649             :             MenuItemData* pData = pItemList->Insert(
    3650           0 :                 0xFFFF, MENUITEM_STRING, 0, aTmpEntryText, Image(), NULL, 0xFFFF );
    3651           0 :                 pData->bIsTemporary = sal_True;
    3652             :         }
    3653             :     }
    3654           0 :     else if ( Application::GetSettings().GetStyleSettings().GetAutoMnemonic() && !( nMenuFlags & MENU_FLAG_NOAUTOMNEMONICS ) )
    3655             :     {
    3656           0 :         CreateAutoMnemonics();
    3657             :     }
    3658             : 
    3659           0 :     MenuFloatingWindow* pWin = new MenuFloatingWindow( this, pW, nStyle | WB_SYSTEMWINDOW );
    3660           0 :     if( pSVData->maNWFData.mbFlatMenu )
    3661           0 :         pWin->SetBorderStyle( WINDOW_BORDER_NOBORDER );
    3662             :     else
    3663           0 :         pWin->SetBorderStyle( pWin->GetBorderStyle() | WINDOW_BORDER_MENU );
    3664           0 :     pWindow = pWin;
    3665             : 
    3666           0 :     Size aSz = ImplCalcSize( pWin );
    3667             : 
    3668           0 :     long nMaxHeight = pWin->GetDesktopRectPixel().GetHeight();
    3669           0 :     if( Application::GetScreenCount() > 1 && Application::IsUnifiedDisplay() )
    3670             :     {
    3671           0 :         Window* pDeskW = pWindow->GetWindow( WINDOW_REALPARENT );
    3672           0 :         if( ! pDeskW )
    3673           0 :             pDeskW = pWindow;
    3674           0 :         Point aDesktopTL( pDeskW->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) );
    3675             :         nMaxHeight = Application::GetWorkAreaPosSizePixel(
    3676             :             Application::GetBestScreen( Rectangle( aDesktopTL, aRect.GetSize() ) )
    3677           0 :             ).GetHeight();
    3678             :     }
    3679           0 :     if ( pStartedFrom && pStartedFrom->bIsMenuBar )
    3680           0 :         nMaxHeight -= pW->GetSizePixel().Height();
    3681             :     sal_Int32 nLeft, nTop, nRight, nBottom;
    3682           0 :     pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
    3683           0 :     nMaxHeight -= nTop+nBottom;
    3684           0 :     if ( aSz.Height() > nMaxHeight )
    3685             :     {
    3686           0 :         pWin->EnableScrollMenu( sal_True );
    3687           0 :         sal_uInt16 nStart = ImplGetFirstVisible();
    3688           0 :         sal_uInt16 nEntries = ImplCalcVisEntries( nMaxHeight, nStart );
    3689           0 :         aSz.Height() = ImplCalcHeight( nEntries );
    3690             :     }
    3691             : 
    3692           0 :     pWin->SetFocusId( nFocusId );
    3693           0 :     pWin->SetOutputSizePixel( aSz );
    3694             :     // #102158# menus must never grab the focus, otherwise
    3695             :     // they will be closed immediately
    3696             :     // from now on focus grabbing is only prohibited automatically if
    3697             :     // FLOATWIN_POPUPMODE_GRABFOCUS was set (which is done below), because some
    3698             :     // floaters (like floating toolboxes) may grab the focus
    3699             :     // pWin->GrabFocus();
    3700           0 :     if ( GetItemCount() )
    3701             :     {
    3702           0 :         SalMenu* pMenu = ImplGetSalMenu();
    3703           0 :         if( pMenu && bRealExecute && pMenu->ShowNativePopupMenu( pWin, aRect, nPopupModeFlags | FLOATWIN_POPUPMODE_GRABFOCUS ) )
    3704             :         {
    3705           0 :             pWin->StopExecute(0);
    3706           0 :             pWin->doShutdown();
    3707           0 :             pWindow->doLazyDelete();
    3708           0 :             pWindow = NULL;
    3709           0 :             return nSelectedId;
    3710             :         }
    3711             :         else
    3712             :         {
    3713           0 :             pWin->StartPopupMode( aRect, nPopupModeFlags | FLOATWIN_POPUPMODE_GRABFOCUS );
    3714             :         }
    3715           0 :         if( pSFrom )
    3716             :         {
    3717             :             sal_uInt16 aPos;
    3718           0 :             if( pSFrom->bIsMenuBar )
    3719           0 :                 aPos = ((MenuBarWindow *) pSFrom->pWindow)->GetHighlightedItem();
    3720             :             else
    3721           0 :                 aPos = ((MenuFloatingWindow *) pSFrom->pWindow)->GetHighlightedItem();
    3722             : 
    3723           0 :             pWin->SetPosInParent( aPos );  // store position to be sent in SUBMENUDEACTIVATE
    3724           0 :             pSFrom->ImplCallEventListeners( VCLEVENT_MENU_SUBMENUACTIVATE, aPos );
    3725             :         }
    3726             :     }
    3727           0 :     if ( bPreSelectFirst )
    3728             :     {
    3729           0 :         size_t nCount = pItemList->size();
    3730           0 :         for ( size_t n = 0; n < nCount; n++ )
    3731             :         {
    3732           0 :             MenuItemData* pData = pItemList->GetDataFromPos( n );
    3733           0 :             if (  (  pData->bEnabled
    3734           0 :                   || !Application::GetSettings().GetStyleSettings().GetSkipDisabledInMenus()
    3735             :                   )
    3736             :                && ( pData->eType != MENUITEM_SEPARATOR )
    3737           0 :                && ImplIsVisible( n )
    3738           0 :                && ImplIsSelectable( n )
    3739             :                )
    3740             :             {
    3741           0 :                 pWin->ChangeHighlightItem( n, sal_False );
    3742           0 :                 break;
    3743             :             }
    3744             :         }
    3745             :     }
    3746           0 :     if ( bRealExecute )
    3747             :     {
    3748           0 :         pWin->ImplAddDel( &aDelData );
    3749             : 
    3750           0 :         ImplDelData aModalWinDel;
    3751           0 :         pW->ImplAddDel( &aModalWinDel );
    3752           0 :         pW->ImplIncModalCount();
    3753             : 
    3754           0 :         pWin->Execute();
    3755             : 
    3756             :         DBG_ASSERT( ! aModalWinDel.IsDead(), "window for popup died, modal count incorrect !" );
    3757           0 :         if( ! aModalWinDel.IsDead() )
    3758           0 :             pW->ImplDecModalCount();
    3759             : 
    3760           0 :         if ( !aDelData.IsDead() )
    3761           0 :             pWin->ImplRemoveDel( &aDelData );
    3762             :         else
    3763           0 :             return 0;
    3764             : 
    3765             :         // Restore focus (could already have been
    3766             :         // restored in Select)
    3767           0 :         nFocusId = pWin->GetFocusId();
    3768           0 :         if ( nFocusId )
    3769             :         {
    3770           0 :             pWin->SetFocusId( 0 );
    3771           0 :             pSVData->maWinData.mbNoDeactivate = sal_False;
    3772             :         }
    3773           0 :         pWin->ImplEndPopupMode( 0, nFocusId );
    3774             : 
    3775           0 :         if ( nSelectedId )  // then clean up .. ( otherwise done by TH )
    3776             :         {
    3777           0 :             PopupMenu* pSub = pWin->GetActivePopup();
    3778           0 :             while ( pSub )
    3779             :             {
    3780           0 :                 pSub->ImplGetFloatingWindow()->EndPopupMode();
    3781           0 :                 pSub = pSub->ImplGetFloatingWindow()->GetActivePopup();
    3782             :             }
    3783             :         }
    3784           0 :         pWin->doShutdown();
    3785           0 :         pWindow->doLazyDelete();
    3786           0 :         pWindow = NULL;
    3787             : 
    3788             :         // is there still Select?
    3789           0 :         Menu* pSelect = ImplFindSelectMenu();
    3790           0 :         if ( pSelect )
    3791             :         {
    3792             :             // Select should be called prior to leaving execute in a popup menu!
    3793           0 :             Application::RemoveUserEvent( pSelect->nEventId );
    3794           0 :             pSelect->nEventId = 0;
    3795           0 :             pSelect->Select();
    3796           0 :         }
    3797             :     }
    3798             : 
    3799           0 :     return bRealExecute ? nSelectedId : 0;
    3800             : }
    3801             : 
    3802           0 : sal_uInt16 PopupMenu::ImplCalcVisEntries( long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible ) const
    3803             : {
    3804           0 :     nMaxHeight -= 2 * ImplGetFloatingWindow()->GetScrollerHeight();
    3805             : 
    3806           0 :     long nHeight = 0;
    3807           0 :     size_t nEntries = pItemList->size();
    3808           0 :     sal_uInt16 nVisEntries = 0;
    3809             : 
    3810           0 :     if ( pLastVisible )
    3811           0 :         *pLastVisible = 0;
    3812             : 
    3813           0 :     for ( size_t n = nStartEntry; n < nEntries; n++ )
    3814             :     {
    3815           0 :         if ( ImplIsVisible( n ) )
    3816             :         {
    3817           0 :             MenuItemData* pData = pItemList->GetDataFromPos( n );
    3818           0 :             nHeight += pData->aSz.Height();
    3819           0 :             if ( nHeight > nMaxHeight )
    3820           0 :                 break;
    3821             : 
    3822           0 :             if ( pLastVisible )
    3823           0 :                 *pLastVisible = n;
    3824           0 :             nVisEntries++;
    3825             :         }
    3826             :     }
    3827           0 :     return nVisEntries;
    3828             : }
    3829             : 
    3830           0 : long PopupMenu::ImplCalcHeight( sal_uInt16 nEntries ) const
    3831             : {
    3832           0 :     long nHeight = 0;
    3833             : 
    3834           0 :     sal_uInt16 nFound = 0;
    3835           0 :     for ( size_t n = 0; ( nFound < nEntries ) && ( n < pItemList->size() ); n++ )
    3836             :     {
    3837           0 :         if ( ImplIsVisible( (sal_uInt16) n ) )
    3838             :         {
    3839           0 :             MenuItemData* pData = pItemList->GetDataFromPos( n );
    3840           0 :             nHeight += pData->aSz.Height();
    3841           0 :             nFound++;
    3842             :         }
    3843             :     }
    3844             : 
    3845           0 :     nHeight += 2*ImplGetFloatingWindow()->GetScrollerHeight();
    3846             : 
    3847           0 :     return nHeight;
    3848             : }
    3849             : 
    3850             : 
    3851         236 : static void ImplInitMenuWindow( Window* pWin, sal_Bool bFont, sal_Bool bMenuBar )
    3852             : {
    3853         236 :     const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
    3854             : 
    3855         236 :     if ( bFont )
    3856         236 :         pWin->SetPointFont( rStyleSettings.GetMenuFont() );
    3857         236 :     if( bMenuBar )
    3858             :     {
    3859         236 :         if( pWin->IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) )
    3860             :         {
    3861           0 :             pWin->SetBackground();  // background will be drawn by NWF
    3862             :         }
    3863             :         else
    3864             :         {
    3865         236 :             Wallpaper aWallpaper;
    3866         236 :             aWallpaper.SetStyle( WALLPAPER_APPLICATIONGRADIENT );
    3867         236 :             pWin->SetBackground( aWallpaper );
    3868         236 :             pWin->SetPaintTransparent( sal_False );
    3869         236 :             pWin->SetParentClipMode( 0 );
    3870             :         }
    3871             :     }
    3872             :     else
    3873             :     {
    3874           0 :         if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
    3875             :         {
    3876           0 :             pWin->SetBackground();  // background will be drawn by NWF
    3877             :         }
    3878             :         else
    3879           0 :             pWin->SetBackground( Wallpaper( rStyleSettings.GetMenuColor() ) );
    3880             :     }
    3881             : 
    3882         236 :     if ( bMenuBar )
    3883         236 :         pWin->SetTextColor( rStyleSettings.GetMenuBarTextColor() );
    3884             :     else
    3885           0 :         pWin->SetTextColor( rStyleSettings.GetMenuTextColor() );
    3886         236 :     pWin->SetTextFillColor();
    3887         236 :     pWin->SetLineColor();
    3888         236 : }
    3889             : 
    3890           0 : MenuFloatingWindow::MenuFloatingWindow( Menu* pMen, Window* pParent, WinBits nStyle ) :
    3891           0 :     FloatingWindow( pParent, nStyle )
    3892             : {
    3893           0 :     mpWindowImpl->mbMenuFloatingWindow= sal_True;
    3894           0 :     pMenu               = pMen;
    3895           0 :     pActivePopup        = 0;
    3896           0 :     nSaveFocusId        = 0;
    3897           0 :     bInExecute          = sal_False;
    3898           0 :     bScrollMenu         = sal_False;
    3899           0 :     nHighlightedItem    = ITEMPOS_INVALID;
    3900           0 :     nMBDownPos          = ITEMPOS_INVALID;
    3901           0 :     nPosInParent        = ITEMPOS_INVALID;
    3902           0 :     nScrollerHeight     = 0;
    3903           0 :     nBorder             = EXTRASPACEY;
    3904           0 :     nFirstEntry         = 0;
    3905           0 :     bScrollUp           = sal_False;
    3906           0 :     bScrollDown         = sal_False;
    3907           0 :     bIgnoreFirstMove    = sal_True;
    3908           0 :     bKeyInput           = sal_False;
    3909             : 
    3910           0 :     EnableSaveBackground();
    3911           0 :     ImplInitMenuWindow( this, sal_True, sal_False );
    3912             : 
    3913           0 :     SetPopupModeEndHdl( LINK( this, MenuFloatingWindow, PopupEnd ) );
    3914             : 
    3915           0 :     aHighlightChangedTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, HighlightChanged ) );
    3916           0 :     aHighlightChangedTimer.SetTimeout( GetSettings().GetMouseSettings().GetMenuDelay() );
    3917           0 :     aSubmenuCloseTimer.SetTimeout( GetSettings().GetMouseSettings().GetMenuDelay() );
    3918           0 :     aSubmenuCloseTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, SubmenuClose ) );
    3919           0 :     aScrollTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, AutoScroll ) );
    3920             : 
    3921           0 :     AddEventListener( LINK( this, MenuFloatingWindow, ShowHideListener ) );
    3922           0 : }
    3923             : 
    3924           0 : void MenuFloatingWindow::doShutdown()
    3925             : {
    3926           0 :     if( pMenu )
    3927             :     {
    3928             :         // #105373# notify toolkit that highlight was removed
    3929             :         // otherwise the entry will not be read when the menu is opened again
    3930           0 :         if( nHighlightedItem != ITEMPOS_INVALID )
    3931           0 :             pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
    3932             : 
    3933           0 :         if( !bKeyInput && pMenu && pMenu->pStartedFrom && !pMenu->pStartedFrom->bIsMenuBar )
    3934             :         {
    3935             :             // #102461# remove highlight in parent
    3936             :             MenuItemData* pData;
    3937           0 :             size_t i, nCount = pMenu->pStartedFrom->pItemList->size();
    3938           0 :             for(i = 0; i < nCount; i++)
    3939             :             {
    3940           0 :                 pData = pMenu->pStartedFrom->pItemList->GetDataFromPos( i );
    3941           0 :                 if( pData && ( pData->pSubMenu == pMenu ) )
    3942           0 :                     break;
    3943             :             }
    3944           0 :             if( i < nCount )
    3945             :             {
    3946           0 :                 MenuFloatingWindow* pPWin = (MenuFloatingWindow*)pMenu->pStartedFrom->ImplGetWindow();
    3947           0 :                 if( pPWin )
    3948           0 :                     pPWin->HighlightItem( i, sal_False );
    3949             :             }
    3950             :         }
    3951             : 
    3952             :         // free the reference to the accessible component
    3953           0 :         SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >() );
    3954             : 
    3955           0 :         aHighlightChangedTimer.Stop();
    3956             : 
    3957             :         // #95056# invalidate screen area covered by system window
    3958             :         // so this can be taken into account if the commandhandler performs a scroll operation
    3959           0 :         if( GetParent() )
    3960             :         {
    3961           0 :             Rectangle aInvRect( GetWindowExtentsRelative( GetParent() ) );
    3962           0 :             GetParent()->Invalidate( aInvRect );
    3963             :         }
    3964           0 :         pMenu = NULL;
    3965           0 :         RemoveEventListener( LINK( this, MenuFloatingWindow, ShowHideListener ) );
    3966             :     }
    3967           0 : }
    3968             : 
    3969           0 : MenuFloatingWindow::~MenuFloatingWindow()
    3970             : {
    3971           0 :     doShutdown();
    3972           0 : }
    3973             : 
    3974           0 : void MenuFloatingWindow::Resize()
    3975             : {
    3976           0 :     ImplInitClipRegion();
    3977           0 : }
    3978             : 
    3979           0 : long MenuFloatingWindow::ImplGetStartY() const
    3980             : {
    3981           0 :     long nY = 0;
    3982           0 :     if( pMenu )
    3983             :     {
    3984           0 :         for ( sal_uInt16 n = 0; n < nFirstEntry; n++ )
    3985           0 :             nY += pMenu->GetItemList()->GetDataFromPos( n )->aSz.Height();
    3986             :     }
    3987           0 :     return -nY;
    3988             : }
    3989             : 
    3990           0 : Region MenuFloatingWindow::ImplCalcClipRegion( sal_Bool bIncludeLogo ) const
    3991             : {
    3992           0 :     Size aOutSz = GetOutputSizePixel();
    3993           0 :     Point aPos;
    3994           0 :     Rectangle aRect( aPos, aOutSz );
    3995           0 :     aRect.Top() += nScrollerHeight;
    3996           0 :     aRect.Bottom() -= nScrollerHeight;
    3997             : 
    3998           0 :     if ( pMenu && pMenu->pLogo && !bIncludeLogo )
    3999           0 :         aRect.Left() += pMenu->pLogo->aBitmap.GetSizePixel().Width();
    4000             : 
    4001           0 :     Region aRegion = aRect;
    4002           0 :     if ( pMenu && pMenu->pLogo && bIncludeLogo && nScrollerHeight )
    4003           0 :         aRegion.Union( Rectangle( Point(), Size( pMenu->pLogo->aBitmap.GetSizePixel().Width(), aOutSz.Height() ) ) );
    4004             : 
    4005           0 :     return aRegion;
    4006             : }
    4007             : 
    4008           0 : void MenuFloatingWindow::ImplInitClipRegion()
    4009             : {
    4010           0 :     if ( IsScrollMenu() )
    4011             :     {
    4012           0 :         SetClipRegion( ImplCalcClipRegion() );
    4013             :     }
    4014             :     else
    4015             :     {
    4016           0 :         SetClipRegion();
    4017             :     }
    4018           0 : }
    4019             : 
    4020           0 : void MenuFloatingWindow::ImplHighlightItem( const MouseEvent& rMEvt, sal_Bool bMBDown )
    4021             : {
    4022           0 :     if( ! pMenu )
    4023           0 :         return;
    4024             : 
    4025           0 :     long nY = nScrollerHeight + ImplGetSVData()->maNWFData.mnMenuFormatBorderY;
    4026           0 :     long nMouseY = rMEvt.GetPosPixel().Y();
    4027           0 :     Size aOutSz = GetOutputSizePixel();
    4028           0 :     if ( ( nMouseY >= nY ) && ( nMouseY < ( aOutSz.Height() - nY ) ) )
    4029             :     {
    4030           0 :         sal_Bool bHighlighted = sal_False;
    4031           0 :         size_t nCount = pMenu->pItemList->size();
    4032           0 :         nY += ImplGetStartY();  // ggf. gescrollt.
    4033           0 :         for ( size_t n = 0; !bHighlighted && ( n < nCount ); n++ )
    4034             :         {
    4035           0 :             if ( pMenu->ImplIsVisible( n ) )
    4036             :             {
    4037           0 :                 MenuItemData* pItemData = pMenu->pItemList->GetDataFromPos( n );
    4038           0 :                 long nOldY = nY;
    4039           0 :                 nY += pItemData->aSz.Height();
    4040           0 :                 if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) && pMenu->ImplIsSelectable( n ) )
    4041             :                 {
    4042           0 :                     sal_Bool bPopupArea = sal_True;
    4043           0 :                     if ( pItemData->nBits & MIB_POPUPSELECT )
    4044             :                     {
    4045             :                         // only when clicked over the arrow...
    4046           0 :                         Size aSz = GetOutputSizePixel();
    4047           0 :                         long nFontHeight = GetTextHeight();
    4048           0 :                         bPopupArea = ( rMEvt.GetPosPixel().X() >= ( aSz.Width() - nFontHeight - nFontHeight/4 ) );
    4049             :                     }
    4050             : 
    4051           0 :                     if ( bMBDown )
    4052             :                     {
    4053           0 :                         if ( n != nHighlightedItem )
    4054             :                         {
    4055           0 :                             ChangeHighlightItem( (sal_uInt16)n, sal_False );
    4056             :                         }
    4057             : 
    4058           0 :                         sal_Bool bAllowNewPopup = sal_True;
    4059           0 :                         if ( pActivePopup )
    4060             :                         {
    4061           0 :                             MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
    4062           0 :                             bAllowNewPopup = pData && ( pData->pSubMenu != pActivePopup );
    4063           0 :                             if ( bAllowNewPopup )
    4064           0 :                                 KillActivePopup();
    4065             :                         }
    4066             : 
    4067           0 :                         if ( bPopupArea && bAllowNewPopup )
    4068             :                         {
    4069           0 :                             HighlightChanged( NULL );
    4070             :                         }
    4071             :                     }
    4072             :                     else
    4073             :                     {
    4074           0 :                         if ( n != nHighlightedItem )
    4075             :                         {
    4076           0 :                             ChangeHighlightItem( (sal_uInt16)n, sal_True );
    4077             :                         }
    4078           0 :                         else if ( pItemData->nBits & MIB_POPUPSELECT )
    4079             :                         {
    4080           0 :                             if ( bPopupArea && ( pActivePopup != pItemData->pSubMenu ) )
    4081           0 :                                 HighlightChanged( NULL );
    4082             :                         }
    4083             :                     }
    4084           0 :                     bHighlighted = sal_True;
    4085             :                 }
    4086             :             }
    4087             :         }
    4088           0 :         if ( !bHighlighted )
    4089           0 :             ChangeHighlightItem( ITEMPOS_INVALID, sal_True );
    4090             :     }
    4091             :     else
    4092             :     {
    4093           0 :         ImplScroll( rMEvt.GetPosPixel() );
    4094           0 :         ChangeHighlightItem( ITEMPOS_INVALID, sal_True );
    4095             :     }
    4096             : }
    4097             : 
    4098           0 : IMPL_LINK_NOARG(MenuFloatingWindow, PopupEnd)
    4099             : {
    4100             :     // "this" will be deleted before the end of this method!
    4101           0 :     Menu* pM = pMenu;
    4102           0 :     if ( bInExecute )
    4103             :     {
    4104           0 :         if ( pActivePopup )
    4105             :         {
    4106             :             //DBG_ASSERT( !pActivePopup->ImplGetWindow(), "PopupEnd, obwohl pActivePopup MIT Window!" );
    4107           0 :             KillActivePopup(); // should be ok to just remove it
    4108             :             //pActivePopup->bCanceled = sal_True;
    4109             :         }
    4110           0 :         bInExecute = sal_False;
    4111           0 :         pMenu->bInCallback = sal_True;
    4112           0 :         pMenu->Deactivate();
    4113           0 :         pMenu->bInCallback = sal_False;
    4114             :     }
    4115             :     else
    4116             :     {
    4117           0 :         if( pMenu )
    4118             :         {
    4119             :             // if the window was closed by TH, there is another menu
    4120             :             // which has this window as pActivePopup
    4121           0 :             if ( pMenu->pStartedFrom )
    4122             :             {
    4123             :                 // pWin from parent could be 0, if the list is
    4124             :                 // cleaned from the start, now clean up the endpopup-events
    4125           0 :                 if ( pMenu->pStartedFrom->bIsMenuBar )
    4126             :                 {
    4127           0 :                     MenuBarWindow* p = (MenuBarWindow*) pMenu->pStartedFrom->ImplGetWindow();
    4128           0 :                     if ( p )
    4129           0 :                         p->PopupClosed( pMenu );
    4130             :                 }
    4131             :                 else
    4132             :                 {
    4133           0 :                     MenuFloatingWindow* p = (MenuFloatingWindow*) pMenu->pStartedFrom->ImplGetWindow();
    4134           0 :                     if ( p )
    4135           0 :                         p->KillActivePopup( (PopupMenu*)pMenu );
    4136             :                 }
    4137             :             }
    4138             :         }
    4139             :     }
    4140             : 
    4141           0 :     if ( pM )
    4142           0 :         pM->pStartedFrom = 0;
    4143             : 
    4144           0 :     return 0;
    4145             : }
    4146             : 
    4147           0 : IMPL_LINK_NOARG(MenuFloatingWindow, AutoScroll)
    4148             : {
    4149           0 :     ImplScroll( GetPointerPosPixel() );
    4150           0 :     return 1;
    4151             : }
    4152             : 
    4153           0 : IMPL_LINK( MenuFloatingWindow, HighlightChanged, Timer*, pTimer )
    4154             : {
    4155           0 :     if( ! pMenu )
    4156           0 :         return 0;
    4157             : 
    4158           0 :     MenuItemData* pItemData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
    4159           0 :     if ( pItemData )
    4160             :     {
    4161           0 :         if ( pActivePopup && ( pActivePopup != pItemData->pSubMenu ) )
    4162             :         {
    4163           0 :             sal_uLong nOldFlags = GetPopupModeFlags();
    4164           0 :             SetPopupModeFlags( GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE );
    4165           0 :             KillActivePopup();
    4166           0 :             SetPopupModeFlags( nOldFlags );
    4167             :         }
    4168           0 :         if ( pItemData->bEnabled && pItemData->pSubMenu && pItemData->pSubMenu->GetItemCount() && ( pItemData->pSubMenu != pActivePopup ) )
    4169             :         {
    4170           0 :             pActivePopup = (PopupMenu*)pItemData->pSubMenu;
    4171           0 :             long nY = nScrollerHeight+ImplGetStartY();
    4172           0 :             MenuItemData* pData = 0;
    4173           0 :             for ( sal_uLong n = 0; n < nHighlightedItem; n++ )
    4174             :             {
    4175           0 :                 pData = pMenu->pItemList->GetDataFromPos( n );
    4176           0 :                 nY += pData->aSz.Height();
    4177             :             }
    4178           0 :             pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
    4179           0 :             Size MySize = GetOutputSizePixel();
    4180           0 :             Point aItemTopLeft( 0, nY );
    4181           0 :             Point aItemBottomRight( aItemTopLeft );
    4182           0 :             aItemBottomRight.X() += MySize.Width();
    4183           0 :             aItemBottomRight.Y() += pData->aSz.Height();
    4184             : 
    4185             :             // shift the popups a little
    4186           0 :             aItemTopLeft.X() += 2;
    4187           0 :             aItemBottomRight.X() -= 2;
    4188           0 :             if ( nHighlightedItem )
    4189           0 :                 aItemTopLeft.Y() -= 2;
    4190             :             else
    4191             :             {
    4192             :                 sal_Int32 nL, nT, nR, nB;
    4193           0 :                 GetBorder( nL, nT, nR, nB );
    4194           0 :                 aItemTopLeft.Y() -= nT;
    4195             :             }
    4196             : 
    4197             :             // pTest: crash due to Reschedule() in call of Activate()
    4198             :             // Also it is prevented that submenus are displayed which
    4199             :             // were for long in Activate Rescheduled and which should not be
    4200             :             // displayed now.
    4201           0 :             Menu* pTest = pActivePopup;
    4202           0 :             sal_uLong nOldFlags = GetPopupModeFlags();
    4203           0 :             SetPopupModeFlags( GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE );
    4204           0 :             sal_uInt16 nRet = pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_RIGHT, pMenu, pTimer ? sal_False : sal_True  );
    4205           0 :             SetPopupModeFlags( nOldFlags );
    4206             : 
    4207             :             // nRet != 0, wenn es waerend Activate() abgeschossen wurde...
    4208           0 :             if ( !nRet && ( pActivePopup == pTest ) && pActivePopup->ImplGetWindow() )
    4209           0 :                 pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this );
    4210             :         }
    4211             :     }
    4212             : 
    4213           0 :     return 0;
    4214             : }
    4215             : 
    4216           0 : IMPL_LINK_NOARG(MenuFloatingWindow, SubmenuClose)
    4217             : {
    4218           0 :     if( pMenu && pMenu->pStartedFrom )
    4219             :     {
    4220           0 :         MenuFloatingWindow* pWin = (MenuFloatingWindow*) pMenu->pStartedFrom->GetWindow();
    4221           0 :         if( pWin )
    4222           0 :             pWin->KillActivePopup();
    4223             :     }
    4224           0 :     return 0;
    4225             : }
    4226             : 
    4227           0 : IMPL_LINK( MenuFloatingWindow, ShowHideListener, VclWindowEvent*, pEvent )
    4228             : {
    4229           0 :     if( ! pMenu )
    4230           0 :         return 0;
    4231             : 
    4232           0 :     if( pEvent->GetId() == VCLEVENT_WINDOW_SHOW )
    4233           0 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_SHOW, ITEMPOS_INVALID );
    4234           0 :     else if( pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
    4235           0 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_HIDE, ITEMPOS_INVALID );
    4236           0 :     return 0;
    4237             : }
    4238             : 
    4239           0 : void MenuFloatingWindow::EnableScrollMenu( sal_Bool b )
    4240             : {
    4241           0 :     bScrollMenu = b;
    4242           0 :     nScrollerHeight = b ? (sal_uInt16) GetSettings().GetStyleSettings().GetScrollBarSize() /2 : 0;
    4243           0 :     bScrollDown = sal_True;
    4244           0 :     ImplInitClipRegion();
    4245           0 : }
    4246             : 
    4247           0 : void MenuFloatingWindow::Execute()
    4248             : {
    4249           0 :     ImplSVData* pSVData = ImplGetSVData();
    4250             : 
    4251           0 :     pSVData->maAppData.mpActivePopupMenu = (PopupMenu*)pMenu;
    4252             : 
    4253           0 :     bInExecute = sal_True;
    4254             : //  bCallingSelect = sal_False;
    4255             : 
    4256           0 :     while ( bInExecute )
    4257           0 :         Application::Yield();
    4258             : 
    4259           0 :     pSVData->maAppData.mpActivePopupMenu = NULL;
    4260           0 : }
    4261             : 
    4262           0 : void MenuFloatingWindow::StopExecute( sal_uLong nFocusId )
    4263             : {
    4264             :     // restore focus
    4265             :     // (could have been restored in Select)
    4266           0 :     if ( nSaveFocusId )
    4267             :     {
    4268           0 :         Window::EndSaveFocus( nFocusId, sal_False );
    4269           0 :         nFocusId = nSaveFocusId;
    4270           0 :         if ( nFocusId )
    4271             :         {
    4272           0 :             nSaveFocusId = 0;
    4273           0 :             ImplGetSVData()->maWinData.mbNoDeactivate = sal_False;
    4274             :         }
    4275             :     }
    4276           0 :     ImplEndPopupMode( 0, nFocusId );
    4277             : 
    4278           0 :     aHighlightChangedTimer.Stop();
    4279           0 :     bInExecute = sal_False;
    4280           0 :     if ( pActivePopup )
    4281             :     {
    4282           0 :         KillActivePopup();
    4283             :     }
    4284             :     // notify parent, needed for accessibility
    4285           0 :     if( pMenu && pMenu->pStartedFrom )
    4286           0 :         pMenu->pStartedFrom->ImplCallEventListeners( VCLEVENT_MENU_SUBMENUDEACTIVATE, nPosInParent );
    4287           0 : }
    4288             : 
    4289           0 : void MenuFloatingWindow::KillActivePopup( PopupMenu* pThisOnly )
    4290             : {
    4291           0 :     if ( pActivePopup && ( !pThisOnly || ( pThisOnly == pActivePopup ) ) )
    4292             :     {
    4293           0 :         if( pActivePopup->pWindow != NULL )
    4294           0 :             if( ((FloatingWindow *) pActivePopup->pWindow)->IsInCleanUp() )
    4295           0 :                 return; // kill it later
    4296           0 :         if ( pActivePopup->bInCallback )
    4297           0 :             pActivePopup->bCanceled = sal_True;
    4298             : 
    4299             :         // For all actions pActivePopup = 0, if e.g.
    4300             :         // PopupModeEndHdl the popups to destroy were called synchronous
    4301           0 :         PopupMenu* pPopup = pActivePopup;
    4302           0 :         pActivePopup = NULL;
    4303           0 :         pPopup->bInCallback = sal_True;
    4304           0 :         pPopup->Deactivate();
    4305           0 :         pPopup->bInCallback = sal_False;
    4306           0 :         if ( pPopup->ImplGetWindow() )
    4307             :         {
    4308           0 :             pPopup->ImplGetFloatingWindow()->StopExecute();
    4309           0 :             pPopup->ImplGetFloatingWindow()->doShutdown();
    4310           0 :             pPopup->pWindow->doLazyDelete();
    4311           0 :             pPopup->pWindow = NULL;
    4312             : 
    4313           0 :             Update();
    4314             :         }
    4315             :     }
    4316             : }
    4317             : 
    4318           0 : void MenuFloatingWindow::EndExecute()
    4319             : {
    4320           0 :     Menu* pStart = pMenu ? pMenu->ImplGetStartMenu() : NULL;
    4321           0 :     sal_uLong nFocusId = 0;
    4322           0 :     if ( pStart && pStart->bIsMenuBar )
    4323             :     {
    4324           0 :         nFocusId = ((MenuBarWindow*)((MenuBar*)pStart)->ImplGetWindow())->GetFocusId();
    4325           0 :         if ( nFocusId )
    4326             :         {
    4327           0 :             ((MenuBarWindow*)((MenuBar*)pStart)->ImplGetWindow())->SetFocusId( 0 );
    4328           0 :             ImplGetSVData()->maWinData.mbNoDeactivate = sal_False;
    4329             :         }
    4330             :     }
    4331             : 
    4332             :     // if started else where, cleanup there as well
    4333           0 :     MenuFloatingWindow* pCleanUpFrom = this;
    4334           0 :     MenuFloatingWindow* pWin = this;
    4335           0 :     while ( pWin && !pWin->bInExecute &&
    4336           0 :         pWin->pMenu->pStartedFrom && !pWin->pMenu->pStartedFrom->bIsMenuBar )
    4337             :     {
    4338           0 :         pWin = ((PopupMenu*)pWin->pMenu->pStartedFrom)->ImplGetFloatingWindow();
    4339             :     }
    4340           0 :     if ( pWin )
    4341           0 :         pCleanUpFrom = pWin;
    4342             : 
    4343             :     // this window will be destroyed => store date locally...
    4344           0 :     Menu* pM = pMenu;
    4345           0 :     sal_uInt16 nItem = nHighlightedItem;
    4346             : 
    4347           0 :     pCleanUpFrom->StopExecute( nFocusId );
    4348             : 
    4349           0 :     if ( nItem != ITEMPOS_INVALID && pM )
    4350             :     {
    4351           0 :         MenuItemData* pItemData = pM->GetItemList()->GetDataFromPos( nItem );
    4352           0 :         if ( pItemData && !pItemData->bIsTemporary )
    4353             :         {
    4354           0 :             pM->nSelectedId = pItemData->nId;
    4355           0 :             if ( pStart )
    4356           0 :                 pStart->nSelectedId = pItemData->nId;
    4357             : 
    4358           0 :             pM->ImplSelect();
    4359             :         }
    4360             :     }
    4361           0 : }
    4362             : 
    4363           0 : void MenuFloatingWindow::EndExecute( sal_uInt16 nId )
    4364             : {
    4365             :     size_t nPos;
    4366           0 :     if ( pMenu && pMenu->GetItemList()->GetData( nId, nPos ) )
    4367           0 :         nHighlightedItem = nPos;
    4368             :     else
    4369           0 :         nHighlightedItem = ITEMPOS_INVALID;
    4370             : 
    4371           0 :     EndExecute();
    4372           0 : }
    4373             : 
    4374           0 : void MenuFloatingWindow::MouseButtonDown( const MouseEvent& rMEvt )
    4375             : {
    4376             :     // TH creates a ToTop on this window, but the active popup
    4377             :     // should stay on top...
    4378             :     // due to focus change this would close all menus -> don't do it (#94123)
    4379             :     //if ( pActivePopup && pActivePopup->ImplGetWindow() && !pActivePopup->ImplGetFloatingWindow()->pActivePopup )
    4380             :     //    pActivePopup->ImplGetFloatingWindow()->ToTop( TOTOP_NOGRABFOCUS );
    4381             : 
    4382           0 :     ImplHighlightItem( rMEvt, sal_True );
    4383             : 
    4384           0 :     nMBDownPos = nHighlightedItem;
    4385           0 : }
    4386             : 
    4387           0 : void MenuFloatingWindow::MouseButtonUp( const MouseEvent& rMEvt )
    4388             : {
    4389           0 :     MenuItemData* pData = pMenu ? pMenu->GetItemList()->GetDataFromPos( nHighlightedItem ) : NULL;
    4390             :     // nMBDownPos store in local variable and reset immediately,
    4391             :     // as it will be too late after EndExecute
    4392           0 :     sal_uInt16 _nMBDownPos = nMBDownPos;
    4393           0 :     nMBDownPos = ITEMPOS_INVALID;
    4394           0 :     if ( pData && pData->bEnabled && ( pData->eType != MENUITEM_SEPARATOR ) )
    4395             :     {
    4396           0 :         if ( !pData->pSubMenu )
    4397             :         {
    4398           0 :             EndExecute();
    4399             :         }
    4400           0 :         else if ( ( pData->nBits & MIB_POPUPSELECT ) && ( nHighlightedItem == _nMBDownPos ) && ( rMEvt.GetClicks() == 2 ) )
    4401             :         {
    4402             :             // not when clicked over the arrow...
    4403           0 :             Size aSz = GetOutputSizePixel();
    4404           0 :             long nFontHeight = GetTextHeight();
    4405           0 :             if ( rMEvt.GetPosPixel().X() < ( aSz.Width() - nFontHeight - nFontHeight/4 ) )
    4406           0 :                 EndExecute();
    4407             :         }
    4408             :     }
    4409             : 
    4410           0 : }
    4411             : 
    4412           0 : void MenuFloatingWindow::MouseMove( const MouseEvent& rMEvt )
    4413             : {
    4414           0 :     if ( !IsVisible() || rMEvt.IsSynthetic() || rMEvt.IsEnterWindow() )
    4415           0 :         return;
    4416             : 
    4417           0 :     if ( rMEvt.IsLeaveWindow() )
    4418             :     {
    4419             :         // #102461# do not remove highlight if a popup menu is open at this position
    4420           0 :         MenuItemData* pData = pMenu ? pMenu->pItemList->GetDataFromPos( nHighlightedItem ) : NULL;
    4421             :         // close popup with some delayed if we leave somewhere else
    4422           0 :         if( pActivePopup && pData && pData->pSubMenu != pActivePopup )
    4423           0 :             pActivePopup->ImplGetFloatingWindow()->aSubmenuCloseTimer.Start();
    4424             : 
    4425           0 :         if( !pActivePopup || (pData && pData->pSubMenu != pActivePopup ) )
    4426           0 :             ChangeHighlightItem( ITEMPOS_INVALID, sal_False );
    4427             : 
    4428           0 :         if ( IsScrollMenu() )
    4429           0 :             ImplScroll( rMEvt.GetPosPixel() );
    4430             :     }
    4431             :     else
    4432             :     {
    4433           0 :         aSubmenuCloseTimer.Stop();
    4434           0 :         if( bIgnoreFirstMove )
    4435           0 :             bIgnoreFirstMove = sal_False;
    4436             :         else
    4437           0 :             ImplHighlightItem( rMEvt, sal_False );
    4438             :     }
    4439             : }
    4440             : 
    4441           0 : void MenuFloatingWindow::ImplScroll( sal_Bool bUp )
    4442             : {
    4443           0 :     KillActivePopup();
    4444           0 :     Update();
    4445             : 
    4446           0 :     if( ! pMenu )
    4447           0 :         return;
    4448             : 
    4449           0 :     HighlightItem( nHighlightedItem, sal_False );
    4450             : 
    4451           0 :     pMenu->ImplKillLayoutData();
    4452             : 
    4453           0 :     if ( bScrollUp && bUp )
    4454             :     {
    4455           0 :         nFirstEntry = pMenu->ImplGetPrevVisible( nFirstEntry );
    4456             :         DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" );
    4457             : 
    4458           0 :         long nScrollEntryHeight = pMenu->GetItemList()->GetDataFromPos( nFirstEntry )->aSz.Height();
    4459             : 
    4460           0 :         if ( !bScrollDown )
    4461             :         {
    4462           0 :             bScrollDown = sal_True;
    4463           0 :             ImplDrawScroller( sal_False );
    4464             :         }
    4465             : 
    4466           0 :         if ( pMenu->ImplGetPrevVisible( nFirstEntry ) == ITEMPOS_INVALID )
    4467             :         {
    4468           0 :             bScrollUp = sal_False;
    4469           0 :             ImplDrawScroller( sal_True );
    4470             :         }
    4471             : 
    4472           0 :         Scroll( 0, nScrollEntryHeight, ImplCalcClipRegion( sal_False ).GetBoundRect(), SCROLL_CLIP );
    4473             :     }
    4474           0 :     else if ( bScrollDown && !bUp )
    4475             :     {
    4476           0 :         long nScrollEntryHeight = pMenu->GetItemList()->GetDataFromPos( nFirstEntry )->aSz.Height();
    4477             : 
    4478           0 :         nFirstEntry = pMenu->ImplGetNextVisible( nFirstEntry );
    4479             :         DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" );
    4480             : 
    4481             : 
    4482           0 :         if ( !bScrollUp )
    4483             :         {
    4484           0 :             bScrollUp = sal_True;
    4485           0 :             ImplDrawScroller( sal_True );
    4486             :         }
    4487             : 
    4488           0 :         long nHeight = GetOutputSizePixel().Height();
    4489             :         sal_uInt16 nLastVisible;
    4490           0 :         ((PopupMenu*)pMenu)->ImplCalcVisEntries( nHeight, nFirstEntry, &nLastVisible );
    4491           0 :         if ( pMenu->ImplGetNextVisible( nLastVisible ) == ITEMPOS_INVALID )
    4492             :         {
    4493           0 :             bScrollDown = sal_False;
    4494           0 :             ImplDrawScroller( sal_False );
    4495             :         }
    4496             : 
    4497           0 :         Scroll( 0, -nScrollEntryHeight, ImplCalcClipRegion( sal_False ).GetBoundRect(), SCROLL_CLIP );
    4498             :     }
    4499             : 
    4500           0 :     HighlightItem( nHighlightedItem, sal_True );
    4501             : }
    4502             : 
    4503           0 : void MenuFloatingWindow::ImplScroll( const Point& rMousePos )
    4504             : {
    4505           0 :     Size aOutSz = GetOutputSizePixel();
    4506             : 
    4507           0 :     long nY = nScrollerHeight;
    4508           0 :     long nMouseY = rMousePos.Y();
    4509           0 :     long nDelta = 0;
    4510             : 
    4511           0 :     if ( bScrollUp && ( nMouseY < nY ) )
    4512             :     {
    4513           0 :         ImplScroll( sal_True );
    4514           0 :         nDelta = nY - nMouseY;
    4515             :     }
    4516           0 :     else if ( bScrollDown && ( nMouseY > ( aOutSz.Height() - nY ) ) )
    4517             :     {
    4518           0 :         ImplScroll( sal_False );
    4519           0 :         nDelta = nMouseY - ( aOutSz.Height() - nY );
    4520             :     }
    4521             : 
    4522           0 :     if ( nDelta )
    4523             :     {
    4524           0 :         aScrollTimer.Stop();    // if scrolled through MouseMove.
    4525             :         long nTimeout;
    4526           0 :         if ( nDelta < 3 )
    4527           0 :             nTimeout = 200;
    4528           0 :         else if ( nDelta < 5 )
    4529           0 :             nTimeout = 100;
    4530           0 :         else if ( nDelta < 8 )
    4531           0 :             nTimeout = 70;
    4532           0 :         else if ( nDelta < 12 )
    4533           0 :             nTimeout = 40;
    4534             :         else
    4535           0 :             nTimeout = 20;
    4536           0 :         aScrollTimer.SetTimeout( nTimeout );
    4537           0 :         aScrollTimer.Start();
    4538             :     }
    4539           0 : }
    4540           0 : void MenuFloatingWindow::ChangeHighlightItem( sal_uInt16 n, sal_Bool bStartPopupTimer )
    4541             : {
    4542             :     // #57934# ggf. immediately close the active, as TH's backgroundstorage works.
    4543             :     // #65750# we prefer to refrain from the background storage of small lines.
    4544             :     //         otherwise the menus are difficult to operate.
    4545             :     //  MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
    4546             :     //  if ( pActivePopup && pNextData && ( pActivePopup != pNextData->pSubMenu ) )
    4547             :     //      KillActivePopup();
    4548             : 
    4549           0 :     aSubmenuCloseTimer.Stop();
    4550           0 :     if( ! pMenu )
    4551           0 :         return;
    4552             : 
    4553           0 :     if ( nHighlightedItem != ITEMPOS_INVALID )
    4554             :     {
    4555           0 :         HighlightItem( nHighlightedItem, sal_False );
    4556           0 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
    4557             :     }
    4558             : 
    4559           0 :     nHighlightedItem = (sal_uInt16)n;
    4560             :     DBG_ASSERT( pMenu->ImplIsVisible( nHighlightedItem ) || nHighlightedItem == ITEMPOS_INVALID, "ChangeHighlightItem: Not visible!" );
    4561           0 :     if( nHighlightedItem != ITEMPOS_INVALID )
    4562             :     {
    4563           0 :         if( pMenu->pStartedFrom && !pMenu->pStartedFrom->bIsMenuBar )
    4564             :         {
    4565             :             // #102461# make sure parent entry is highlighted as well
    4566             :             MenuItemData* pData;
    4567           0 :             size_t i, nCount = pMenu->pStartedFrom->pItemList->size();
    4568           0 :             for(i = 0; i < nCount; i++)
    4569             :             {
    4570           0 :                 pData = pMenu->pStartedFrom->pItemList->GetDataFromPos( i );
    4571           0 :                 if( pData && ( pData->pSubMenu == pMenu ) )
    4572           0 :                     break;
    4573             :             }
    4574           0 :             if( i < nCount )
    4575             :             {
    4576           0 :                 MenuFloatingWindow* pPWin = (MenuFloatingWindow*)pMenu->pStartedFrom->ImplGetWindow();
    4577           0 :                 if( pPWin && pPWin->nHighlightedItem != i )
    4578             :                 {
    4579           0 :                     pPWin->HighlightItem( i, sal_True );
    4580           0 :                     pPWin->nHighlightedItem = i;
    4581             :                 }
    4582             :             }
    4583             :         }
    4584           0 :         HighlightItem( nHighlightedItem, sal_True );
    4585           0 :         pMenu->ImplCallHighlight( nHighlightedItem );
    4586             :     }
    4587             :     else
    4588           0 :         pMenu->nSelectedId = 0;
    4589             : 
    4590           0 :     if ( bStartPopupTimer )
    4591             :     {
    4592             :         // #102438# Menu items are not selectable
    4593             :         // If a menu item is selected by an AT-tool via the XAccessibleAction, XAccessibleValue
    4594             :         // or XAccessibleSelection interface, and the parent popup menus are not executed yet,
    4595             :         // the parent popup menus must be executed SYNCHRONOUSLY, before the menu item is selected.
    4596           0 :         if ( GetSettings().GetMouseSettings().GetMenuDelay() )
    4597           0 :             aHighlightChangedTimer.Start();
    4598             :         else
    4599           0 :             HighlightChanged( &aHighlightChangedTimer );
    4600             :     }
    4601             : }
    4602             : 
    4603           0 : void MenuFloatingWindow::HighlightItem( sal_uInt16 nPos, sal_Bool bHighlight )
    4604             : {
    4605           0 :     if( ! pMenu )
    4606             :         return;
    4607             : 
    4608           0 :     Size    aSz = GetOutputSizePixel();
    4609           0 :     long    nStartY = ImplGetStartY();
    4610           0 :     long    nY = nScrollerHeight + nStartY + ImplGetSVData()->maNWFData.mnMenuFormatBorderY;
    4611           0 :     long    nX = 0;
    4612             : 
    4613           0 :     if ( pMenu->pLogo )
    4614           0 :         nX = pMenu->pLogo->aBitmap.GetSizePixel().Width();
    4615             : 
    4616           0 :     int nOuterSpaceX = ImplGetSVData()->maNWFData.mnMenuFormatBorderX;
    4617             : 
    4618           0 :     size_t nCount = pMenu->pItemList->size();
    4619           0 :     for ( size_t n = 0; n < nCount; n++ )
    4620             :     {
    4621           0 :         MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
    4622           0 :         if ( n == nPos )
    4623             :         {
    4624             :             DBG_ASSERT( pMenu->ImplIsVisible( n ), "Highlight: Item not visible!" );
    4625           0 :             if ( pData->eType != MENUITEM_SEPARATOR )
    4626             :             {
    4627           0 :                 sal_Bool bRestoreLineColor = sal_False;
    4628           0 :                 Color oldLineColor;
    4629           0 :                 bool bDrawItemRect = true;
    4630             : 
    4631           0 :                 Rectangle aItemRect( Point( nX+nOuterSpaceX, nY ), Size( aSz.Width()-2*nOuterSpaceX, pData->aSz.Height() ) );
    4632           0 :                 if ( pData->nBits & MIB_POPUPSELECT )
    4633             :                 {
    4634           0 :                     long nFontHeight = GetTextHeight();
    4635           0 :                     aItemRect.Right() -= nFontHeight + nFontHeight/4;
    4636             :                 }
    4637             : 
    4638           0 :                 if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
    4639             :                 {
    4640           0 :                     Size aPxSize( GetOutputSizePixel() );
    4641           0 :                     Push( PUSH_CLIPREGION );
    4642           0 :                     IntersectClipRegion( Rectangle( Point( nX, nY ), Size( aSz.Width(), pData->aSz.Height() ) ) );
    4643           0 :                     Rectangle aCtrlRect( Point( nX, 0 ), Size( aPxSize.Width()-nX, aPxSize.Height() ) );
    4644           0 :                     MenupopupValue aVal( pMenu->nTextPos-GUTTERBORDER, aItemRect );
    4645             :                     DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
    4646             :                                        aCtrlRect,
    4647             :                                        CTRL_STATE_ENABLED,
    4648             :                                        aVal,
    4649           0 :                                        OUString() );
    4650           0 :                     if( bHighlight &&
    4651           0 :                         IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) )
    4652             :                     {
    4653           0 :                         bDrawItemRect = false;
    4654           0 :                         if( sal_False == DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM,
    4655             :                                                         aItemRect,
    4656             :                                                         CTRL_STATE_SELECTED | ( pData->bEnabled? CTRL_STATE_ENABLED: 0 ),
    4657             :                                                         aVal,
    4658           0 :                                                         OUString() ) )
    4659             :                         {
    4660           0 :                             bDrawItemRect = bHighlight;
    4661             :                         }
    4662             :                     }
    4663             :                     else
    4664           0 :                         bDrawItemRect = bHighlight;
    4665           0 :                     Pop();
    4666             :                 }
    4667           0 :                 if( bDrawItemRect )
    4668             :                 {
    4669           0 :                     if ( bHighlight )
    4670             :                     {
    4671           0 :                         if( pData->bEnabled )
    4672           0 :                             SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
    4673             :                         else
    4674             :                         {
    4675           0 :                             SetFillColor();
    4676           0 :                             oldLineColor = GetLineColor();
    4677           0 :                             SetLineColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
    4678           0 :                             bRestoreLineColor = sal_True;
    4679             :                         }
    4680             :                     }
    4681             :                     else
    4682           0 :                         SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
    4683             : 
    4684           0 :                     DrawRect( aItemRect );
    4685             :                 }
    4686           0 :                 pMenu->ImplPaint( this, nScrollerHeight, nStartY, pData, bHighlight );
    4687           0 :                 if( bRestoreLineColor )
    4688           0 :                     SetLineColor( oldLineColor );
    4689             :             }
    4690             :             return;
    4691             :         }
    4692             : 
    4693           0 :         nY += pData->aSz.Height();
    4694             :     }
    4695             : }
    4696             : 
    4697           0 : Rectangle MenuFloatingWindow::ImplGetItemRect( sal_uInt16 nPos )
    4698             : {
    4699           0 :     if( ! pMenu )
    4700           0 :         return Rectangle();
    4701             : 
    4702           0 :     Rectangle aRect;
    4703           0 :     Size    aSz = GetOutputSizePixel();
    4704           0 :     long    nStartY = ImplGetStartY();
    4705           0 :     long    nY = nScrollerHeight+nStartY;
    4706           0 :     long    nX = 0;
    4707             : 
    4708           0 :     if ( pMenu->pLogo )
    4709           0 :         nX = pMenu->pLogo->aBitmap.GetSizePixel().Width();
    4710             : 
    4711           0 :     size_t nCount = pMenu->pItemList->size();
    4712           0 :     for ( size_t n = 0; n < nCount; n++ )
    4713             :     {
    4714           0 :         MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
    4715           0 :         if ( n == nPos )
    4716             :         {
    4717             :             DBG_ASSERT( pMenu->ImplIsVisible( n ), "ImplGetItemRect: Item not visible!" );
    4718           0 :             if ( pData->eType != MENUITEM_SEPARATOR )
    4719             :             {
    4720           0 :                 aRect = Rectangle( Point( nX, nY ), Size( aSz.Width(), pData->aSz.Height() ) );
    4721           0 :                 if ( pData->nBits & MIB_POPUPSELECT )
    4722             :                 {
    4723           0 :                     long nFontHeight = GetTextHeight();
    4724           0 :                     aRect.Right() -= nFontHeight + nFontHeight/4;
    4725             :                 }
    4726             :             }
    4727           0 :             break;
    4728             :         }
    4729           0 :         nY += pData->aSz.Height();
    4730             :     }
    4731           0 :     return aRect;
    4732             : }
    4733             : 
    4734             : 
    4735           0 : void MenuFloatingWindow::ImplCursorUpDown( sal_Bool bUp, sal_Bool bHomeEnd )
    4736             : {
    4737           0 :     if( ! pMenu )
    4738           0 :         return;
    4739             : 
    4740           0 :     const StyleSettings& rSettings = GetSettings().GetStyleSettings();
    4741             : 
    4742           0 :     sal_uInt16 n = nHighlightedItem;
    4743           0 :     if ( n == ITEMPOS_INVALID )
    4744             :     {
    4745           0 :         if ( bUp )
    4746           0 :             n = 0;
    4747             :         else
    4748           0 :             n = pMenu->GetItemCount()-1;
    4749             :     }
    4750             : 
    4751           0 :     sal_uInt16 nLoop = n;
    4752             : 
    4753           0 :     if( bHomeEnd )
    4754             :     {
    4755             :         // absolute positioning
    4756           0 :         if( bUp )
    4757             :         {
    4758           0 :             n = pMenu->GetItemCount();
    4759           0 :             nLoop = n-1;
    4760             :         }
    4761             :         else
    4762             :         {
    4763           0 :             n = (sal_uInt16)-1;
    4764           0 :             nLoop = n+1;
    4765             :         }
    4766             :     }
    4767             : 
    4768           0 :     do
    4769             :     {
    4770           0 :         if ( bUp )
    4771             :         {
    4772           0 :             if ( n )
    4773           0 :                 n--;
    4774             :             else
    4775           0 :                 if ( !IsScrollMenu() || ( nHighlightedItem == ITEMPOS_INVALID ) )
    4776           0 :                     n = pMenu->GetItemCount()-1;
    4777             :                 else
    4778           0 :                     break;
    4779             :         }
    4780             :         else
    4781             :         {
    4782           0 :             n++;
    4783           0 :             if ( n >= pMenu->GetItemCount() )
    4784             :             {
    4785           0 :                 if ( !IsScrollMenu() || ( nHighlightedItem == ITEMPOS_INVALID ) )
    4786           0 :                     n = 0;
    4787             :                 else
    4788           0 :                     break;
    4789             :             }
    4790             :         }
    4791             : 
    4792           0 :         MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n );
    4793           0 :         if ( ( pData->bEnabled || !rSettings.GetSkipDisabledInMenus() )
    4794           0 :               && ( pData->eType != MENUITEM_SEPARATOR ) && pMenu->ImplIsVisible( n ) && pMenu->ImplIsSelectable( n ) )
    4795             :         {
    4796             :             // Is selection in visible area?
    4797           0 :             if ( IsScrollMenu() )
    4798             :             {
    4799           0 :                 ChangeHighlightItem( ITEMPOS_INVALID, sal_False );
    4800             : 
    4801           0 :                 while ( n < nFirstEntry )
    4802           0 :                     ImplScroll( sal_True );
    4803             : 
    4804           0 :                 Size aOutSz = GetOutputSizePixel();
    4805             :                 sal_uInt16 nLastVisible;
    4806           0 :                 ((PopupMenu*)pMenu)->ImplCalcVisEntries( aOutSz.Height(), nFirstEntry, &nLastVisible );
    4807           0 :                 while ( n > nLastVisible )
    4808             :                 {
    4809           0 :                     ImplScroll( sal_False );
    4810           0 :                     ((PopupMenu*)pMenu)->ImplCalcVisEntries( aOutSz.Height(), nFirstEntry, &nLastVisible );
    4811             :                 }
    4812             :             }
    4813           0 :             ChangeHighlightItem( n, sal_False );
    4814           0 :             break;
    4815             :         }
    4816             :     } while ( n != nLoop );
    4817             : }
    4818             : 
    4819           0 : void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent )
    4820             : {
    4821           0 :     ImplDelData aDelData;
    4822           0 :     ImplAddDel( &aDelData );
    4823             : 
    4824           0 :     sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
    4825           0 :     bKeyInput = sal_True;
    4826           0 :     switch ( nCode )
    4827             :     {
    4828             :         case KEY_UP:
    4829             :         case KEY_DOWN:
    4830             :         {
    4831           0 :             ImplCursorUpDown( nCode == KEY_UP );
    4832             :         }
    4833           0 :         break;
    4834             :         case KEY_END:
    4835             :         case KEY_HOME:
    4836             :         {
    4837           0 :             ImplCursorUpDown( nCode == KEY_END, sal_True );
    4838             :         }
    4839           0 :         break;
    4840             :         case KEY_F6:
    4841             :         case KEY_ESCAPE:
    4842             :         {
    4843             :             // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document
    4844           0 :             if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() )
    4845           0 :                 break;
    4846           0 :             if( pMenu )
    4847             :             {
    4848           0 :                 if ( !pMenu->pStartedFrom )
    4849             :                 {
    4850           0 :                     StopExecute();
    4851           0 :                     KillActivePopup();
    4852             :                 }
    4853           0 :                 else if ( pMenu->pStartedFrom->bIsMenuBar )
    4854             :                 {
    4855             :                     // Forward...
    4856           0 :                     ((MenuBarWindow*)((MenuBar*)pMenu->pStartedFrom)->ImplGetWindow())->KeyInput( rKEvent );
    4857             :                 }
    4858             :                 else
    4859             :                 {
    4860           0 :                     StopExecute();
    4861           0 :                     PopupMenu* pPopupMenu = (PopupMenu*)pMenu->pStartedFrom;
    4862           0 :                     MenuFloatingWindow* pFloat = pPopupMenu->ImplGetFloatingWindow();
    4863           0 :                     pFloat->GrabFocus();
    4864           0 :                     pFloat->KillActivePopup();
    4865           0 :                     pPopupMenu->ImplCallHighlight(pFloat->nHighlightedItem);
    4866             :                 }
    4867             :             }
    4868             :         }
    4869           0 :         break;
    4870             :         case KEY_LEFT:
    4871             :         {
    4872           0 :             if ( pMenu && pMenu->pStartedFrom )
    4873             :             {
    4874           0 :                 StopExecute();
    4875           0 :                 if ( pMenu->pStartedFrom->bIsMenuBar )
    4876             :                 {
    4877             :                     // Forward...
    4878           0 :                     ((MenuBarWindow*)((MenuBar*)pMenu->pStartedFrom)->ImplGetWindow())->KeyInput( rKEvent );
    4879             :                 }
    4880             :                 else
    4881             :                 {
    4882           0 :                     MenuFloatingWindow* pFloat = ((PopupMenu*)pMenu->pStartedFrom)->ImplGetFloatingWindow();
    4883           0 :                     pFloat->GrabFocus();
    4884           0 :                     pFloat->KillActivePopup();
    4885             :                 }
    4886             :             }
    4887             :         }
    4888           0 :         break;
    4889             :         case KEY_RIGHT:
    4890             :         {
    4891           0 :             if( pMenu )
    4892             :             {
    4893           0 :                 sal_Bool bDone = sal_False;
    4894           0 :                 if ( nHighlightedItem != ITEMPOS_INVALID )
    4895             :                 {
    4896           0 :                     MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
    4897           0 :                     if ( pData && pData->pSubMenu )
    4898             :                     {
    4899           0 :                         HighlightChanged( 0 );
    4900           0 :                         bDone = sal_True;
    4901             :                     }
    4902             :                 }
    4903           0 :                 if ( !bDone )
    4904             :                 {
    4905           0 :                     Menu* pStart = pMenu->ImplGetStartMenu();
    4906           0 :                     if ( pStart && pStart->bIsMenuBar )
    4907             :                     {
    4908             :                         // Forward...
    4909           0 :                         pStart->ImplGetWindow()->KeyInput( rKEvent );
    4910             :                     }
    4911             :                 }
    4912             :             }
    4913             :         }
    4914           0 :         break;
    4915             :         case KEY_RETURN:
    4916             :         {
    4917           0 :             if( pMenu )
    4918             :             {
    4919           0 :                 MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
    4920           0 :                 if ( pData && pData->bEnabled )
    4921             :                 {
    4922           0 :                     if ( pData->pSubMenu )
    4923           0 :                         HighlightChanged( 0 );
    4924             :                     else
    4925           0 :                         EndExecute();
    4926             :                 }
    4927             :                 else
    4928           0 :                     StopExecute();
    4929             :             }
    4930             :         }
    4931           0 :         break;
    4932             :         case KEY_MENU:
    4933             :         {
    4934           0 :             if( pMenu )
    4935             :             {
    4936           0 :                 Menu* pStart = pMenu->ImplGetStartMenu();
    4937           0 :                 if ( pStart && pStart->bIsMenuBar )
    4938             :                 {
    4939             :                     // Forward...
    4940           0 :                     pStart->ImplGetWindow()->KeyInput( rKEvent );
    4941             :                 }
    4942             :             }
    4943             :         }
    4944           0 :         break;
    4945             :         default:
    4946             :         {
    4947           0 :             sal_Unicode nCharCode = rKEvent.GetCharCode();
    4948           0 :             sal_uInt16 nPos = 0;
    4949           0 :             sal_uInt16 nDuplicates = 0;
    4950           0 :             MenuItemData* pData = (nCharCode && pMenu) ? pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nPos, nDuplicates, nHighlightedItem ) : NULL;
    4951           0 :             if ( pData )
    4952             :             {
    4953           0 :                 if ( pData->pSubMenu || nDuplicates > 1 )
    4954             :                 {
    4955           0 :                     ChangeHighlightItem( nPos, sal_False );
    4956           0 :                     HighlightChanged( 0 );
    4957             :                 }
    4958             :                 else
    4959             :                 {
    4960           0 :                     nHighlightedItem = nPos;
    4961           0 :                     EndExecute();
    4962             :                 }
    4963             :             }
    4964             :             else
    4965           0 :                 FloatingWindow::KeyInput( rKEvent );
    4966             :         }
    4967             :     }
    4968             :     // #105474# check if menu window was not destroyed
    4969           0 :     if ( !aDelData.IsDead() )
    4970             :     {
    4971           0 :         ImplRemoveDel( &aDelData );
    4972           0 :         bKeyInput = sal_False;
    4973           0 :     }
    4974           0 : }
    4975             : 
    4976           0 : void MenuFloatingWindow::Paint( const Rectangle& )
    4977             : {
    4978           0 :     if( ! pMenu )
    4979           0 :         return;
    4980             : 
    4981           0 :     if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
    4982             :     {
    4983           0 :         SetClipRegion();
    4984           0 :         long nX = pMenu->pLogo ? pMenu->pLogo->aBitmap.GetSizePixel().Width() : 0;
    4985           0 :         Size aPxSize( GetOutputSizePixel() );
    4986           0 :         aPxSize.Width() -= nX;
    4987           0 :         ImplControlValue aVal( pMenu->nTextPos-GUTTERBORDER );
    4988             :         DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
    4989             :                            Rectangle( Point( nX, 0 ), aPxSize ),
    4990             :                            CTRL_STATE_ENABLED,
    4991             :                            aVal,
    4992           0 :                            OUString() );
    4993           0 :         ImplInitClipRegion();
    4994             :     }
    4995           0 :     if ( IsScrollMenu() )
    4996             :     {
    4997           0 :         ImplDrawScroller( sal_True );
    4998           0 :         ImplDrawScroller( sal_False );
    4999             :     }
    5000           0 :     SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
    5001           0 :     pMenu->ImplPaint( this, nScrollerHeight, ImplGetStartY() );
    5002           0 :     if ( nHighlightedItem != ITEMPOS_INVALID )
    5003           0 :         HighlightItem( nHighlightedItem, sal_True );
    5004             : }
    5005             : 
    5006           0 : void MenuFloatingWindow::ImplDrawScroller( sal_Bool bUp )
    5007             : {
    5008           0 :     if( ! pMenu )
    5009           0 :         return;
    5010             : 
    5011           0 :     SetClipRegion();
    5012             : 
    5013           0 :     Size aOutSz = GetOutputSizePixel();
    5014           0 :     long nY = bUp ? 0 : ( aOutSz.Height() - nScrollerHeight );
    5015           0 :     long nX = pMenu->pLogo ? pMenu->pLogo->aBitmap.GetSizePixel().Width() : 0;
    5016           0 :     Rectangle aRect( Point( nX, nY ), Size( aOutSz.Width()-nX, nScrollerHeight ) );
    5017             : 
    5018           0 :     DecorationView aDecoView( this );
    5019           0 :     SymbolType eSymbol = bUp ? SYMBOL_SPIN_UP : SYMBOL_SPIN_DOWN;
    5020             : 
    5021           0 :     sal_uInt16 nStyle = 0;
    5022           0 :     if ( ( bUp && !bScrollUp ) || ( !bUp && !bScrollDown ) )
    5023           0 :         nStyle |= SYMBOL_DRAW_DISABLE;
    5024             : 
    5025           0 :     aDecoView.DrawSymbol( aRect, eSymbol, GetSettings().GetStyleSettings().GetButtonTextColor(), nStyle );
    5026             : 
    5027           0 :     ImplInitClipRegion();
    5028             : }
    5029             : 
    5030           0 : void MenuFloatingWindow::RequestHelp( const HelpEvent& rHEvt )
    5031             : {
    5032           0 :     sal_uInt16 nId = nHighlightedItem;
    5033           0 :     Menu* pM = pMenu;
    5034           0 :     Window* pW = this;
    5035             : 
    5036             :     // #102618# Get item rect before destroying the window in EndExecute() call
    5037           0 :     Rectangle aHighlightRect( ImplGetItemRect( nHighlightedItem ) );
    5038             : 
    5039           0 :     if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) )
    5040             :     {
    5041           0 :         nHighlightedItem = ITEMPOS_INVALID;
    5042           0 :         EndExecute();
    5043           0 :         pW = NULL;
    5044             :     }
    5045             : 
    5046           0 :     if( !ImplHandleHelpEvent( pW, pM, nId, rHEvt, aHighlightRect ) )
    5047           0 :         Window::RequestHelp( rHEvt );
    5048           0 : }
    5049             : 
    5050           0 : void MenuFloatingWindow::StateChanged( StateChangedType nType )
    5051             : {
    5052           0 :     FloatingWindow::StateChanged( nType );
    5053             : 
    5054           0 :     if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) || ( nType == STATE_CHANGE_CONTROLBACKGROUND ) )
    5055             :     {
    5056           0 :         ImplInitMenuWindow( this, sal_False, sal_False );
    5057           0 :         Invalidate();
    5058             :     }
    5059           0 : }
    5060             : 
    5061           0 : void MenuFloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
    5062             : {
    5063           0 :     FloatingWindow::DataChanged( rDCEvt );
    5064             : 
    5065           0 :     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
    5066           0 :          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
    5067           0 :          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
    5068           0 :           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    5069             :     {
    5070           0 :         ImplInitMenuWindow( this, sal_False, sal_False );
    5071           0 :         Invalidate();
    5072             :     }
    5073           0 : }
    5074             : 
    5075           0 : void MenuFloatingWindow::Command( const CommandEvent& rCEvt )
    5076             : {
    5077           0 :     if ( rCEvt.GetCommand() == COMMAND_WHEEL )
    5078             :     {
    5079           0 :         const CommandWheelData* pData = rCEvt.GetWheelData();
    5080           0 :         if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
    5081             :         {
    5082             : //          ImplCursorUpDown( pData->GetDelta() > 0L );
    5083           0 :             ImplScroll( pData->GetDelta() > 0L );
    5084           0 :             MouseMove( MouseEvent( GetPointerPosPixel(), 0 ) );
    5085             :         }
    5086             :     }
    5087           0 : }
    5088             : 
    5089           0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > MenuFloatingWindow::CreateAccessible()
    5090             : {
    5091           0 :     ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc;
    5092             : 
    5093           0 :     if ( pMenu && !pMenu->pStartedFrom )
    5094           0 :         xAcc = pMenu->GetAccessible();
    5095             : 
    5096           0 :     return xAcc;
    5097             : }
    5098             : 
    5099         236 : MenuBarWindow::MenuBarWindow( Window* pParent ) :
    5100             :     Window( pParent, 0 ),
    5101             :     aCloser( this ),
    5102             :     aFloatBtn( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE ),
    5103         236 :     aHideBtn( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE )
    5104             : {
    5105         236 :     SetType( WINDOW_MENUBARWINDOW );
    5106         236 :     pMenu = NULL;
    5107         236 :     pActivePopup = NULL;
    5108         236 :     nSaveFocusId = 0;
    5109         236 :     nHighlightedItem = ITEMPOS_INVALID;
    5110         236 :     mbAutoPopup = sal_True;
    5111         236 :     nSaveFocusId = 0;
    5112         236 :     bIgnoreFirstMove = sal_True;
    5113         236 :     bStayActive = sal_False;
    5114             : 
    5115         236 :     ResMgr* pResMgr = ImplGetResMgr();
    5116             : 
    5117         236 :     if( pResMgr )
    5118             :     {
    5119         236 :         BitmapEx aBitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) );
    5120         236 :         aCloser.maImage = Image( aBitmap );
    5121             : 
    5122         236 :         aCloser.SetOutStyle( TOOLBOX_STYLE_FLAT );
    5123         236 :         aCloser.SetBackground();
    5124         236 :         aCloser.SetPaintTransparent( sal_True );
    5125         236 :         aCloser.SetParentClipMode( PARENTCLIPMODE_NOCLIP );
    5126             : 
    5127         236 :         aCloser.InsertItem( IID_DOCUMENTCLOSE, aCloser.maImage, 0 );
    5128         236 :         aCloser.SetSelectHdl( LINK( this, MenuBarWindow, CloserHdl ) );
    5129         236 :         aCloser.AddEventListener( LINK( this, MenuBarWindow, ToolboxEventHdl ) );
    5130         236 :         aCloser.SetQuickHelpText( IID_DOCUMENTCLOSE, ResId(SV_HELPTEXT_CLOSEDOCUMENT, *pResMgr).toString() );
    5131             : 
    5132         236 :         aFloatBtn.SetClickHdl( LINK( this, MenuBarWindow, FloatHdl ) );
    5133         236 :         aFloatBtn.SetSymbol( SYMBOL_FLOAT );
    5134         236 :         aFloatBtn.SetQuickHelpText( ResId(SV_HELPTEXT_RESTORE, *pResMgr).toString() );
    5135             : 
    5136         236 :         aHideBtn.SetClickHdl( LINK( this, MenuBarWindow, HideHdl ) );
    5137         236 :         aHideBtn.SetSymbol( SYMBOL_HIDE );
    5138         236 :         aHideBtn.SetQuickHelpText( ResId(SV_HELPTEXT_MINIMIZE, *pResMgr).toString() );
    5139             :     }
    5140             : 
    5141         236 :     ImplInitStyleSettings();
    5142             : 
    5143         236 :     AddEventListener( LINK( this, MenuBarWindow, ShowHideListener ) );
    5144         236 : }
    5145             : 
    5146         189 : MenuBarWindow::~MenuBarWindow()
    5147             : {
    5148          63 :     aCloser.RemoveEventListener( LINK( this, MenuBarWindow, ToolboxEventHdl ) );
    5149          63 :     RemoveEventListener( LINK( this, MenuBarWindow, ShowHideListener ) );
    5150         126 : }
    5151             : 
    5152         236 : void MenuBarWindow::SetMenu( MenuBar* pMen )
    5153             : {
    5154         236 :     pMenu = pMen;
    5155         236 :     KillActivePopup();
    5156         236 :     nHighlightedItem = ITEMPOS_INVALID;
    5157         236 :     ImplInitMenuWindow( this, sal_True, sal_True );
    5158         236 :     if ( pMen )
    5159             :     {
    5160         236 :         aCloser.ShowItem( IID_DOCUMENTCLOSE, pMen->HasCloser() );
    5161         236 :         aCloser.Show( pMen->HasCloser() || !m_aAddButtons.empty() );
    5162         236 :         aFloatBtn.Show( pMen->HasFloatButton() );
    5163         236 :         aHideBtn.Show( pMen->HasHideButton() );
    5164             :     }
    5165         236 :     Invalidate();
    5166             : 
    5167             :     // show and connect native menubar
    5168         236 :     if( pMenu && pMenu->ImplGetSalMenu() )
    5169             :     {
    5170           0 :         if( pMenu->ImplGetSalMenu()->VisibleMenuBar() )
    5171           0 :             ImplGetFrame()->SetMenu( pMenu->ImplGetSalMenu() );
    5172             : 
    5173           0 :         pMenu->ImplGetSalMenu()->SetFrame( ImplGetFrame() );
    5174             :     }
    5175         236 : }
    5176             : 
    5177          25 : void MenuBarWindow::ShowButtons( sal_Bool bClose, sal_Bool bFloat, sal_Bool bHide )
    5178             : {
    5179          25 :     aCloser.ShowItem( IID_DOCUMENTCLOSE, bClose );
    5180          25 :     aCloser.Show( bClose || ! m_aAddButtons.empty() );
    5181          25 :     aFloatBtn.Show( bFloat );
    5182          25 :     aHideBtn.Show( bHide );
    5183          25 :     Resize();
    5184          25 : }
    5185             : 
    5186         236 : Size MenuBarWindow::MinCloseButtonSize()
    5187             : {
    5188         236 :     return aCloser.getMinSize();
    5189             : }
    5190             : 
    5191           0 : IMPL_LINK_NOARG(MenuBarWindow, CloserHdl)
    5192             : {
    5193           0 :     if( ! pMenu )
    5194           0 :         return 0;
    5195             : 
    5196           0 :     if( aCloser.GetCurItemId() == IID_DOCUMENTCLOSE )
    5197             :     {
    5198             :         // #i106052# call close hdl asynchronously to ease handler implementation
    5199             :         // this avoids still being in the handler while the DecoToolBox already
    5200             :         // gets destroyed
    5201           0 :         Application::PostUserEvent( ((MenuBar*)pMenu)->GetCloserHdl(), pMenu );
    5202             :     }
    5203             :     else
    5204             :     {
    5205           0 :         std::map<sal_uInt16,AddButtonEntry>::iterator it = m_aAddButtons.find( aCloser.GetCurItemId() );
    5206           0 :         if( it != m_aAddButtons.end() )
    5207             :         {
    5208             :             MenuBar::MenuBarButtonCallbackArg aArg;
    5209           0 :             aArg.nId = it->first;
    5210           0 :             aArg.bHighlight = (aCloser.GetHighlightItemId() == it->first);
    5211           0 :             aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
    5212           0 :             return it->second.m_aSelectLink.Call( &aArg );
    5213             :         }
    5214             :     }
    5215           0 :     return 0;
    5216             : }
    5217             : 
    5218        1142 : IMPL_LINK( MenuBarWindow, ToolboxEventHdl, VclWindowEvent*, pEvent )
    5219             : {
    5220         571 :     if( ! pMenu )
    5221           0 :         return 0;
    5222             : 
    5223             :     MenuBar::MenuBarButtonCallbackArg aArg;
    5224         571 :     aArg.nId = 0xffff;
    5225         571 :     aArg.bHighlight = (pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT);
    5226         571 :     aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
    5227         571 :     if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT )
    5228           0 :         aArg.nId = aCloser.GetHighlightItemId();
    5229         571 :     else if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHTOFF )
    5230             :     {
    5231           0 :         sal_uInt16 nPos = static_cast< sal_uInt16 >(reinterpret_cast<sal_IntPtr>(pEvent->GetData()));
    5232           0 :         aArg.nId = aCloser.GetItemId( nPos );
    5233             :     }
    5234         571 :     std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( aArg.nId );
    5235         571 :     if( it != m_aAddButtons.end() )
    5236             :     {
    5237           0 :         it->second.m_aHighlightLink.Call( &aArg );
    5238             :     }
    5239         571 :     return 0;
    5240             : }
    5241             : 
    5242        2108 : IMPL_LINK( MenuBarWindow, ShowHideListener, VclWindowEvent*, pEvent )
    5243             : {
    5244        1054 :     if( ! pMenu )
    5245           0 :         return 0;
    5246             : 
    5247        1054 :     if( pEvent->GetId() == VCLEVENT_WINDOW_SHOW )
    5248         330 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_SHOW, ITEMPOS_INVALID );
    5249         724 :     else if( pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
    5250           0 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_HIDE, ITEMPOS_INVALID );
    5251        1054 :     return 0;
    5252             : }
    5253             : 
    5254           0 : IMPL_LINK_NOARG(MenuBarWindow, FloatHdl)
    5255             : {
    5256           0 :     return pMenu ? ((MenuBar*)pMenu)->GetFloatButtonClickHdl().Call( pMenu ) : 0;
    5257             : }
    5258             : 
    5259           0 : IMPL_LINK_NOARG(MenuBarWindow, HideHdl)
    5260             : {
    5261           0 :     return pMenu ? ((MenuBar*)pMenu)->GetHideButtonClickHdl().Call( pMenu ) : 0;
    5262             : }
    5263             : 
    5264           0 : void MenuBarWindow::ImplCreatePopup( sal_Bool bPreSelectFirst )
    5265             : {
    5266           0 :     MenuItemData* pItemData = pMenu ? pMenu->GetItemList()->GetDataFromPos( nHighlightedItem ) : NULL;
    5267           0 :     if ( pItemData )
    5268             :     {
    5269           0 :         bIgnoreFirstMove = sal_True;
    5270           0 :         if ( pActivePopup && ( pActivePopup != pItemData->pSubMenu ) )
    5271             :         {
    5272           0 :             KillActivePopup();
    5273             :         }
    5274           0 :         if ( pItemData->bEnabled && pItemData->pSubMenu && ( nHighlightedItem != ITEMPOS_INVALID ) && ( pItemData->pSubMenu != pActivePopup ) )
    5275             :         {
    5276           0 :             pActivePopup = (PopupMenu*)pItemData->pSubMenu;
    5277           0 :             long nX = 0;
    5278           0 :             MenuItemData* pData = 0;
    5279           0 :             for ( sal_uLong n = 0; n < nHighlightedItem; n++ )
    5280             :             {
    5281           0 :                 pData = pMenu->GetItemList()->GetDataFromPos( n );
    5282           0 :                 nX += pData->aSz.Width();
    5283             :             }
    5284           0 :             pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
    5285           0 :             Point aItemTopLeft( nX, 0 );
    5286           0 :             Point aItemBottomRight( aItemTopLeft );
    5287           0 :             aItemBottomRight.X() += pData->aSz.Width();
    5288             : 
    5289             :             // the menu bar could have height 0 in fullscreen mode:
    5290             :             // so do not use always WindowHeight, as ItemHeight < WindowHeight.
    5291           0 :             if ( GetSizePixel().Height() )
    5292             :             {
    5293             :                 // #107747# give menuitems the height of the menubar
    5294           0 :                 aItemBottomRight.Y() += GetOutputSizePixel().Height()-1;
    5295             :             }
    5296             : 
    5297             :             // ImplExecute is not modal...
    5298             :             // #99071# do not grab the focus, otherwise it will be restored to the menubar
    5299             :             // when the frame is reactivated later
    5300             :             //GrabFocus();
    5301           0 :             pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_DOWN, pMenu, bPreSelectFirst );
    5302           0 :             if ( pActivePopup )
    5303             :             {
    5304             :                 // does not have a window, if aborted before or if there are no entries
    5305           0 :                 if ( pActivePopup->ImplGetFloatingWindow() )
    5306           0 :                     pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this );
    5307             :                 else
    5308           0 :                     pActivePopup = NULL;
    5309             :             }
    5310             :         }
    5311             :     }
    5312           0 : }
    5313             : 
    5314             : 
    5315         299 : void MenuBarWindow::KillActivePopup()
    5316             : {
    5317         299 :     if ( pActivePopup )
    5318             :     {
    5319           0 :         if( pActivePopup->pWindow != NULL )
    5320           0 :             if( ((FloatingWindow *) pActivePopup->pWindow)->IsInCleanUp() )
    5321         299 :                 return; // kill it later
    5322             : 
    5323           0 :         if ( pActivePopup->bInCallback )
    5324           0 :             pActivePopup->bCanceled = sal_True;
    5325             : 
    5326           0 :         pActivePopup->bInCallback = sal_True;
    5327           0 :         pActivePopup->Deactivate();
    5328           0 :         pActivePopup->bInCallback = sal_False;
    5329             :         // check for pActivePopup, if stopped by deactivate...
    5330           0 :         if ( pActivePopup->ImplGetWindow() )
    5331             :         {
    5332           0 :             pActivePopup->ImplGetFloatingWindow()->StopExecute();
    5333           0 :             pActivePopup->ImplGetFloatingWindow()->doShutdown();
    5334           0 :             pActivePopup->pWindow->doLazyDelete();
    5335           0 :             pActivePopup->pWindow = NULL;
    5336             :         }
    5337           0 :         pActivePopup = 0;
    5338             :     }
    5339             : }
    5340             : 
    5341           0 : void MenuBarWindow::PopupClosed( Menu* pPopup )
    5342             : {
    5343           0 :     if ( pPopup == pActivePopup )
    5344             :     {
    5345           0 :         KillActivePopup();
    5346           0 :         ChangeHighlightItem( ITEMPOS_INVALID, sal_False, ImplGetFrameWindow()->ImplGetFrameData()->mbHasFocus, sal_False );
    5347             :     }
    5348           0 : }
    5349             : 
    5350           0 : void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt )
    5351             : {
    5352           0 :     mbAutoPopup = sal_True;
    5353           0 :     sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
    5354           0 :     if ( ( nEntry != ITEMPOS_INVALID ) && ( nEntry != nHighlightedItem ) )
    5355             :     {
    5356           0 :         ChangeHighlightItem( nEntry, sal_False );
    5357             :     }
    5358             :     else
    5359             :     {
    5360           0 :         KillActivePopup();
    5361           0 :         ChangeHighlightItem( ITEMPOS_INVALID, sal_False );
    5362             :     }
    5363           0 : }
    5364             : 
    5365           0 : void MenuBarWindow::MouseButtonUp( const MouseEvent& )
    5366             : {
    5367           0 : }
    5368             : 
    5369           0 : void MenuBarWindow::MouseMove( const MouseEvent& rMEvt )
    5370             : {
    5371             :     // only highlight during Move if if was already highlighted.
    5372           0 :     if ( rMEvt.IsSynthetic() || rMEvt.IsLeaveWindow() || rMEvt.IsEnterWindow() || ( nHighlightedItem == ITEMPOS_INVALID ) )
    5373           0 :         return;
    5374             : 
    5375           0 :     if( bIgnoreFirstMove )
    5376             :     {
    5377           0 :         bIgnoreFirstMove = sal_False;
    5378           0 :         return;
    5379             :     }
    5380             : 
    5381           0 :     sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
    5382           0 :     if ( ( nEntry != ITEMPOS_INVALID )
    5383             :        && ( nEntry != nHighlightedItem ) )
    5384           0 :         ChangeHighlightItem( nEntry, sal_False );
    5385             : }
    5386             : 
    5387           0 : void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, sal_Bool bSelectEntry, sal_Bool bAllowRestoreFocus, sal_Bool bDefaultToDocument)
    5388             : {
    5389           0 :     if( ! pMenu )
    5390           0 :         return;
    5391             : 
    5392             :     // #57934# close active popup if applicable, as TH's background storage works.
    5393           0 :     MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
    5394           0 :     if ( pActivePopup && pActivePopup->ImplGetWindow() && ( !pNextData || ( pActivePopup != pNextData->pSubMenu ) ) )
    5395           0 :         KillActivePopup(); // pActivePopup when applicable without pWin, if Rescheduled in  Activate()
    5396             : 
    5397             :     // activate menubar only ones per cycle...
    5398           0 :     sal_Bool bJustActivated = sal_False;
    5399           0 :     if ( ( nHighlightedItem == ITEMPOS_INVALID ) && ( n != ITEMPOS_INVALID ) )
    5400             :     {
    5401           0 :         ImplGetSVData()->maWinData.mbNoDeactivate = sal_True;
    5402           0 :         if( !bStayActive )
    5403             :         {
    5404             :             // #105406# avoid saving the focus when we already have the focus
    5405           0 :             sal_Bool bNoSaveFocus = (this == ImplGetSVData()->maWinData.mpFocusWin );
    5406             : 
    5407           0 :             if( nSaveFocusId )
    5408             :             {
    5409           0 :                 if( !ImplGetSVData()->maWinData.mbNoSaveFocus )
    5410             :                 {
    5411             :                     // we didn't clean up last time
    5412           0 :                     Window::EndSaveFocus( nSaveFocusId, sal_False );    // clean up
    5413           0 :                     nSaveFocusId = 0;
    5414           0 :                     if( !bNoSaveFocus )
    5415           0 :                         nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated
    5416             :                 }
    5417             :                 else {
    5418             :                     ; // do nothing: we 're activated again from taskpanelist, focus was already saved
    5419             :                 }
    5420             :             }
    5421             :             else
    5422             :             {
    5423           0 :                 if( !bNoSaveFocus )
    5424           0 :                     nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated
    5425             :             }
    5426             :         }
    5427             :         else
    5428           0 :             bStayActive = sal_False;
    5429           0 :         pMenu->bInCallback = sal_True;  // set here if Activate overloaded
    5430           0 :         pMenu->Activate();
    5431           0 :         pMenu->bInCallback = sal_False;
    5432           0 :         bJustActivated = sal_True;
    5433             :     }
    5434           0 :     else if ( ( nHighlightedItem != ITEMPOS_INVALID ) && ( n == ITEMPOS_INVALID ) )
    5435             :     {
    5436           0 :         pMenu->bInCallback = sal_True;
    5437           0 :         pMenu->Deactivate();
    5438           0 :         pMenu->bInCallback = sal_False;
    5439           0 :         ImplGetSVData()->maWinData.mbNoDeactivate = sal_False;
    5440           0 :         if( !ImplGetSVData()->maWinData.mbNoSaveFocus )
    5441             :         {
    5442           0 :             sal_uLong nTempFocusId = nSaveFocusId;
    5443           0 :             nSaveFocusId = 0;
    5444           0 :             Window::EndSaveFocus( nTempFocusId, bAllowRestoreFocus );
    5445             :             // #105406# restore focus to document if we could not save focus before
    5446           0 :             if( bDefaultToDocument && !nTempFocusId && bAllowRestoreFocus )
    5447           0 :                 GrabFocusToDocument();
    5448             :         }
    5449             :     }
    5450             : 
    5451           0 :     if ( nHighlightedItem != ITEMPOS_INVALID )
    5452             :     {
    5453           0 :         HighlightItem( nHighlightedItem, sal_False );
    5454           0 :         pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
    5455             :     }
    5456             : 
    5457           0 :     nHighlightedItem = (sal_uInt16)n;
    5458             :     DBG_ASSERT( ( nHighlightedItem == ITEMPOS_INVALID ) || pMenu->ImplIsVisible( nHighlightedItem ), "ChangeHighlightItem: Not visible!" );
    5459           0 :     HighlightItem( nHighlightedItem, sal_True );
    5460           0 :     pMenu->ImplCallHighlight( nHighlightedItem );
    5461             : 
    5462           0 :     if( mbAutoPopup )
    5463           0 :         ImplCreatePopup( bSelectEntry );
    5464             : 
    5465             :     // #58935# #73659# Focus, if no popup underneath...
    5466           0 :     if ( bJustActivated && !pActivePopup )
    5467           0 :         GrabFocus();
    5468             : }
    5469             : 
    5470           0 : void MenuBarWindow::HighlightItem( sal_uInt16 nPos, sal_Bool bHighlight )
    5471             : {
    5472           0 :     if( ! pMenu )
    5473           0 :         return;
    5474             : 
    5475           0 :     long nX = 0;
    5476           0 :     size_t nCount = pMenu->pItemList->size();
    5477           0 :     for ( size_t n = 0; n < nCount; n++ )
    5478             :     {
    5479           0 :         MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
    5480           0 :         if ( n == nPos )
    5481             :         {
    5482           0 :             if ( pData->eType != MENUITEM_SEPARATOR )
    5483             :             {
    5484             :                 // #107747# give menuitems the height of the menubar
    5485           0 :                 Rectangle aRect = Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), GetOutputSizePixel().Height()-2 ) );
    5486           0 :                 Push( PUSH_CLIPREGION );
    5487           0 :                 IntersectClipRegion( aRect );
    5488           0 :                 if ( bHighlight )
    5489             :                 {
    5490           0 :                     if( IsNativeControlSupported( CTRL_MENUBAR, PART_MENU_ITEM ) &&
    5491           0 :                         IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) )
    5492             :                     {
    5493             :                         // draw background (transparency)
    5494           0 :                         MenubarValue aControlValue;
    5495           0 :                         aControlValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this );
    5496             : 
    5497           0 :                         Point tmp(0,0);
    5498           0 :                         Rectangle aBgRegion( tmp, GetOutputSizePixel() );
    5499             :                         DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL,
    5500             :                                            aBgRegion,
    5501             :                                            CTRL_STATE_ENABLED,
    5502             :                                            aControlValue,
    5503           0 :                                            OUString() );
    5504           0 :                         ImplAddNWFSeparator( this, aControlValue );
    5505             : 
    5506             :                         // draw selected item
    5507             :                         DrawNativeControl( CTRL_MENUBAR, PART_MENU_ITEM,
    5508             :                                            aRect,
    5509             :                                            CTRL_STATE_ENABLED | CTRL_STATE_SELECTED,
    5510             :                                            aControlValue,
    5511           0 :                                            OUString() );
    5512             :                     }
    5513             :                     else
    5514             :                     {
    5515           0 :                         SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
    5516           0 :                         SetLineColor();
    5517           0 :                         DrawRect( aRect );
    5518             :                     }
    5519             :                 }
    5520             :                 else
    5521             :                 {
    5522           0 :                     if( IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) )
    5523             :                     {
    5524           0 :                         MenubarValue aMenubarValue;
    5525           0 :                         aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this );
    5526             : 
    5527             :                         // use full window size to get proper gradient
    5528             :                         // but clip accordingly
    5529           0 :                         Point aPt;
    5530           0 :                         Rectangle aCtrlRect( aPt, GetOutputSizePixel() );
    5531             : 
    5532           0 :                         DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED, aMenubarValue, rtl::OUString() );
    5533           0 :                         ImplAddNWFSeparator( this, aMenubarValue );
    5534             :                     }
    5535             :                     else
    5536           0 :                         Erase( aRect );
    5537             :                 }
    5538           0 :                 Pop();
    5539           0 :                 pMenu->ImplPaint( this, 0, 0, pData, bHighlight );
    5540             :             }
    5541           0 :             return;
    5542             :         }
    5543             : 
    5544           0 :         nX += pData->aSz.Width();
    5545             :     }
    5546             : }
    5547             : 
    5548           0 : Rectangle MenuBarWindow::ImplGetItemRect( sal_uInt16 nPos )
    5549             : {
    5550           0 :     Rectangle aRect;
    5551           0 :     if( pMenu )
    5552             :     {
    5553           0 :         long nX = 0;
    5554           0 :         size_t nCount = pMenu->pItemList->size();
    5555           0 :         for ( size_t n = 0; n < nCount; n++ )
    5556             :         {
    5557           0 :             MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
    5558           0 :             if ( n == nPos )
    5559             :             {
    5560           0 :                 if ( pData->eType != MENUITEM_SEPARATOR )
    5561             :                     // #107747# give menuitems the height of the menubar
    5562           0 :                     aRect = Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), GetOutputSizePixel().Height()-2 ) );
    5563           0 :                 break;
    5564             :             }
    5565             : 
    5566           0 :             nX += pData->aSz.Width();
    5567             :         }
    5568             :     }
    5569           0 :     return aRect;
    5570             : }
    5571             : 
    5572           0 : void MenuBarWindow::KeyInput( const KeyEvent& rKEvent )
    5573             : {
    5574           0 :     if ( !ImplHandleKeyEvent( rKEvent ) )
    5575           0 :         Window::KeyInput( rKEvent );
    5576           0 : }
    5577             : 
    5578           0 : sal_Bool MenuBarWindow::ImplHandleKeyEvent( const KeyEvent& rKEvent, sal_Bool bFromMenu )
    5579             : {
    5580           0 :     if( ! pMenu )
    5581           0 :         return sal_False;
    5582             : 
    5583           0 :     if ( pMenu->bInCallback )
    5584           0 :         return sal_True;    // swallow
    5585             : 
    5586           0 :     sal_Bool bDone = sal_False;
    5587           0 :     sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
    5588             : 
    5589           0 :     if( GetParent() )
    5590             :     {
    5591           0 :         if( GetParent()->GetWindow( WINDOW_CLIENT )->IsSystemWindow() )
    5592             :         {
    5593           0 :             SystemWindow *pSysWin = (SystemWindow*)GetParent()->GetWindow( WINDOW_CLIENT );
    5594           0 :             if( pSysWin->GetTaskPaneList() )
    5595           0 :                 if( pSysWin->GetTaskPaneList()->HandleKeyEvent( rKEvent ) )
    5596           0 :                     return sal_True;
    5597             :         }
    5598             :     }
    5599             : 
    5600           0 :     if ( nCode == KEY_MENU && !rKEvent.GetKeyCode().IsShift() ) // only F10, not Shift-F10
    5601             :     {
    5602           0 :         mbAutoPopup = ImplGetSVData()->maNWFData.mbOpenMenuOnF10;
    5603           0 :         if ( nHighlightedItem == ITEMPOS_INVALID )
    5604             :         {
    5605           0 :             ChangeHighlightItem( 0, sal_False );
    5606           0 :             GrabFocus();
    5607             :         }
    5608             :         else
    5609             :         {
    5610           0 :             ChangeHighlightItem( ITEMPOS_INVALID, sal_False );
    5611           0 :             nSaveFocusId = 0;
    5612             :         }
    5613           0 :         bDone = sal_True;
    5614             :     }
    5615           0 :     else if ( bFromMenu )
    5616             :     {
    5617           0 :         if ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) ||
    5618             :             ( nCode == KEY_HOME ) || ( nCode == KEY_END ) )
    5619             :         {
    5620           0 :             sal_uInt16 n = nHighlightedItem;
    5621           0 :             if ( n == ITEMPOS_INVALID )
    5622             :             {
    5623           0 :                 if ( nCode == KEY_LEFT)
    5624           0 :                     n = 0;
    5625             :                 else
    5626           0 :                     n = pMenu->GetItemCount()-1;
    5627             :             }
    5628             : 
    5629             :             // handling gtk like (aka mbOpenMenuOnF10)
    5630             :             // do not highlight an item when opening a sub menu
    5631             :             // unless there already was a higlighted sub menu item
    5632           0 :             bool bWasHighlight = false;
    5633           0 :             if( pActivePopup )
    5634             :             {
    5635           0 :                 MenuFloatingWindow* pSubWindow = dynamic_cast<MenuFloatingWindow*>(pActivePopup->ImplGetWindow());
    5636           0 :                 if( pSubWindow )
    5637           0 :                     bWasHighlight = (pSubWindow->GetHighlightedItem() != ITEMPOS_INVALID);
    5638             :             }
    5639             : 
    5640           0 :             sal_uInt16 nLoop = n;
    5641             : 
    5642           0 :             if( nCode == KEY_HOME )
    5643           0 :                 { n = (sal_uInt16)-1; nLoop = n+1; }
    5644           0 :             if( nCode == KEY_END )
    5645           0 :                 { n = pMenu->GetItemCount(); nLoop = n-1; }
    5646             : 
    5647           0 :             do
    5648             :             {
    5649           0 :                 if ( nCode == KEY_LEFT || nCode == KEY_END )
    5650             :                 {
    5651           0 :                     if ( n )
    5652           0 :                         n--;
    5653             :                     else
    5654           0 :                         n = pMenu->GetItemCount()-1;
    5655             :                 }
    5656           0 :                 if ( nCode == KEY_RIGHT || nCode == KEY_HOME )
    5657             :                 {
    5658           0 :                     n++;
    5659           0 :                     if ( n >= pMenu->GetItemCount() )
    5660           0 :                         n = 0;
    5661             :                 }
    5662             : 
    5663           0 :                 MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n );
    5664           0 :                 if ( ( pData->eType != MENUITEM_SEPARATOR ) && pMenu->ImplIsVisible( n ) )
    5665             :                 {
    5666           0 :                     sal_Bool bDoSelect = sal_True;
    5667           0 :                     if( ImplGetSVData()->maNWFData.mbOpenMenuOnF10 )
    5668           0 :                         bDoSelect = bWasHighlight;
    5669           0 :                     ChangeHighlightItem( n, bDoSelect );
    5670           0 :                     break;
    5671             :                 }
    5672             :             } while ( n != nLoop );
    5673           0 :             bDone = sal_True;
    5674             :         }
    5675           0 :         else if ( nCode == KEY_RETURN )
    5676             :         {
    5677           0 :             if( pActivePopup ) KillActivePopup();
    5678             :             else
    5679           0 :                 if ( !mbAutoPopup )
    5680             :                 {
    5681           0 :                     ImplCreatePopup( sal_True );
    5682           0 :                     mbAutoPopup = sal_True;
    5683             :                 }
    5684           0 :             bDone = sal_True;
    5685             :         }
    5686           0 :         else if ( ( nCode == KEY_UP ) || ( nCode == KEY_DOWN ) )
    5687             :         {
    5688           0 :             if ( !mbAutoPopup )
    5689             :             {
    5690           0 :                 ImplCreatePopup( sal_True );
    5691           0 :                 mbAutoPopup = sal_True;
    5692             :             }
    5693           0 :             bDone = sal_True;
    5694             :         }
    5695           0 :         else if ( nCode == KEY_ESCAPE || ( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() ) )
    5696             :         {
    5697           0 :             if( pActivePopup )
    5698             :             {
    5699             :                 // bring focus to menu bar without any open popup
    5700           0 :                 mbAutoPopup = sal_False;
    5701           0 :                 sal_uInt16 n = nHighlightedItem;
    5702           0 :                 nHighlightedItem = ITEMPOS_INVALID;
    5703           0 :                 bStayActive = sal_True;
    5704           0 :                 ChangeHighlightItem( n, sal_False );
    5705           0 :                 bStayActive = sal_False;
    5706           0 :                 KillActivePopup();
    5707           0 :                 GrabFocus();
    5708             :             }
    5709             :             else
    5710           0 :                 ChangeHighlightItem( ITEMPOS_INVALID, sal_False );
    5711             : 
    5712           0 :             if( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() )
    5713             :             {
    5714             :                 // put focus into document
    5715           0 :                 GrabFocusToDocument();
    5716             :             }
    5717             : 
    5718           0 :             bDone = sal_True;
    5719             :         }
    5720             :     }
    5721             : 
    5722           0 :     if ( !bDone && ( bFromMenu || rKEvent.GetKeyCode().IsMod2() ) )
    5723             :     {
    5724           0 :         sal_Unicode nCharCode = rKEvent.GetCharCode();
    5725           0 :         if ( nCharCode )
    5726             :         {
    5727             :             sal_uInt16 nEntry, nDuplicates;
    5728           0 :             MenuItemData* pData = pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nEntry, nDuplicates, nHighlightedItem );
    5729           0 :             if ( pData && (nEntry != ITEMPOS_INVALID) )
    5730             :             {
    5731           0 :                 mbAutoPopup = sal_True;
    5732           0 :                 ChangeHighlightItem( nEntry, sal_True );
    5733           0 :                 bDone = sal_True;
    5734             :             }
    5735             :         }
    5736             :     }
    5737           0 :     return bDone;
    5738             : }
    5739             : 
    5740         177 : void MenuBarWindow::Paint( const Rectangle& )
    5741             : {
    5742         177 :     if( ! pMenu )
    5743           0 :         return;
    5744             : 
    5745             :     // no VCL paint if native menus
    5746         177 :     if( pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar() )
    5747             :     {
    5748           0 :         ImplGetFrame()->DrawMenuBar();
    5749           0 :         return;
    5750             :     }
    5751             : 
    5752         177 :     if( IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) )
    5753             :     {
    5754           0 :         Point aPt;
    5755           0 :         Rectangle aCtrlRegion( aPt, GetOutputSizePixel() );
    5756             : 
    5757           0 :         MenubarValue aMenubarValue;
    5758           0 :         aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this );
    5759             : 
    5760           0 :         DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aMenubarValue, rtl::OUString() );
    5761           0 :         ImplAddNWFSeparator( this, aMenubarValue );
    5762             :     }
    5763         177 :     SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
    5764         177 :     pMenu->ImplPaint( this, 0 );
    5765         177 :     if ( nHighlightedItem != ITEMPOS_INVALID )
    5766           0 :         HighlightItem( nHighlightedItem, sal_True );
    5767             : 
    5768             :     // in high contrast mode draw a separating line on the lower edge
    5769         354 :     if( ! IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) &&
    5770         177 :         GetSettings().GetStyleSettings().GetHighContrastMode() )
    5771             :     {
    5772           0 :         Push( PUSH_LINECOLOR | PUSH_MAPMODE );
    5773           0 :         SetLineColor( Color( COL_WHITE ) );
    5774           0 :         SetMapMode( MapMode( MAP_PIXEL ) );
    5775           0 :         Size aSize = GetSizePixel();
    5776           0 :         DrawLine( Point( 0, aSize.Height()-1 ), Point( aSize.Width()-1, aSize.Height()-1 ) );
    5777           0 :         Pop();
    5778             :     }
    5779             : 
    5780             : }
    5781             : 
    5782         311 : void MenuBarWindow::Resize()
    5783             : {
    5784         311 :     Size aOutSz = GetOutputSizePixel();
    5785         311 :     long n      = aOutSz.Height()-4;
    5786         311 :     long nX     = aOutSz.Width()-3;
    5787         311 :     long nY     = 2;
    5788             : 
    5789         311 :     if ( aCloser.IsVisible() )
    5790             :     {
    5791          17 :         aCloser.Hide();
    5792          17 :         aCloser.SetImages( n );
    5793          17 :         Size aTbxSize( aCloser.CalcWindowSizePixel() );
    5794          17 :         nX -= aTbxSize.Width();
    5795          17 :         long nTbxY = (aOutSz.Height() - aTbxSize.Height())/2;
    5796          17 :         aCloser.setPosSizePixel( nX, nTbxY, aTbxSize.Width(), aTbxSize.Height() );
    5797          17 :         nX -= 3;
    5798          17 :         aCloser.Show();
    5799             :     }
    5800         311 :     if ( aFloatBtn.IsVisible() )
    5801             :     {
    5802           0 :         nX -= n;
    5803           0 :         aFloatBtn.setPosSizePixel( nX, nY, n, n );
    5804             :     }
    5805         311 :     if ( aHideBtn.IsVisible() )
    5806             :     {
    5807           0 :         nX -= n;
    5808           0 :         aHideBtn.setPosSizePixel( nX, nY, n, n );
    5809             :     }
    5810             : 
    5811         311 :     aFloatBtn.SetSymbol( SYMBOL_FLOAT );
    5812         311 :     aHideBtn.SetSymbol( SYMBOL_HIDE );
    5813             :     //aCloser.SetSymbol( SYMBOL_CLOSE ); //is a toolbox now
    5814             : 
    5815         311 :     Invalidate();
    5816         311 : }
    5817             : 
    5818           0 : sal_uInt16 MenuBarWindow::ImplFindEntry( const Point& rMousePos ) const
    5819             : {
    5820           0 :     if( pMenu )
    5821             :     {
    5822           0 :         long nX = 0;
    5823           0 :         size_t nCount = pMenu->pItemList->size();
    5824           0 :         for ( size_t n = 0; n < nCount; n++ )
    5825             :         {
    5826           0 :             MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
    5827           0 :             if ( pMenu->ImplIsVisible( n ) )
    5828             :             {
    5829           0 :                 nX += pData->aSz.Width();
    5830           0 :                 if ( nX > rMousePos.X() )
    5831           0 :                     return (sal_uInt16)n;
    5832             :             }
    5833             :         }
    5834             :     }
    5835           0 :     return ITEMPOS_INVALID;
    5836             : }
    5837             : 
    5838           0 : void MenuBarWindow::RequestHelp( const HelpEvent& rHEvt )
    5839             : {
    5840           0 :     sal_uInt16 nId = nHighlightedItem;
    5841           0 :     if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) )
    5842           0 :         ChangeHighlightItem( ITEMPOS_INVALID, sal_True );
    5843             : 
    5844           0 :     Rectangle aHighlightRect( ImplGetItemRect( nHighlightedItem ) );
    5845           0 :     if( !ImplHandleHelpEvent( this, pMenu, nId, rHEvt, aHighlightRect ) )
    5846           0 :         Window::RequestHelp( rHEvt );
    5847           0 : }
    5848             : 
    5849         582 : void MenuBarWindow::StateChanged( StateChangedType nType )
    5850             : {
    5851         582 :     Window::StateChanged( nType );
    5852             : 
    5853         582 :     if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) ||
    5854             :          ( nType == STATE_CHANGE_CONTROLBACKGROUND ) )
    5855             :     {
    5856           0 :         ImplInitMenuWindow( this, sal_False, sal_True );
    5857           0 :         Invalidate();
    5858             :     }
    5859         582 :     else if( pMenu )
    5860         582 :         pMenu->ImplKillLayoutData();
    5861             : 
    5862         582 : }
    5863             : 
    5864           0 : void MenuBarWindow::ImplLayoutChanged()
    5865             : {
    5866           0 :     if( pMenu )
    5867             :     {
    5868           0 :         ImplInitMenuWindow( this, sal_True, sal_True );
    5869             :         // if the font was changed.
    5870           0 :         long nHeight = pMenu->ImplCalcSize( this ).Height();
    5871             : 
    5872             :         // depending on the native implementation or the displayable flag
    5873             :         // the menubar windows is supressed (ie, height=0)
    5874           0 :         if( !((MenuBar*) pMenu)->IsDisplayable() ||
    5875           0 :             ( pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar() ) )
    5876           0 :             nHeight = 0;
    5877             : 
    5878           0 :         setPosSizePixel( 0, 0, 0, nHeight, WINDOW_POSSIZE_HEIGHT );
    5879           0 :         GetParent()->Resize();
    5880           0 :         Invalidate();
    5881           0 :         Resize();
    5882           0 :         if( pMenu )
    5883           0 :             pMenu->ImplKillLayoutData();
    5884             :     }
    5885           0 : }
    5886             : 
    5887         236 : void MenuBarWindow::ImplInitStyleSettings()
    5888             : {
    5889         236 :     if( IsNativeControlSupported( CTRL_MENUBAR, PART_MENU_ITEM ) &&
    5890           0 :         IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) )
    5891             :     {
    5892           0 :         Color aHighlightTextColor = ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor;
    5893           0 :         if( aHighlightTextColor != Color( COL_TRANSPARENT ) )
    5894             :         {
    5895           0 :             AllSettings aSettings( GetSettings() );
    5896           0 :             StyleSettings aStyle( aSettings.GetStyleSettings() );
    5897           0 :             aStyle.SetMenuHighlightTextColor( aHighlightTextColor );
    5898           0 :             aSettings.SetStyleSettings( aStyle );
    5899           0 :             OutputDevice::SetSettings( aSettings );
    5900             :         }
    5901             :     }
    5902         236 : }
    5903             : 
    5904          92 : void MenuBarWindow::DataChanged( const DataChangedEvent& rDCEvt )
    5905             : {
    5906          92 :     Window::DataChanged( rDCEvt );
    5907             : 
    5908         368 :     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
    5909          92 :          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
    5910          92 :          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
    5911          92 :           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    5912             :     {
    5913           0 :         ImplLayoutChanged();
    5914           0 :         ImplInitStyleSettings();
    5915             :     }
    5916          92 : }
    5917             : 
    5918           0 : void MenuBarWindow::LoseFocus()
    5919             : {
    5920           0 :     if ( !HasChildPathFocus( sal_True ) )
    5921           0 :         ChangeHighlightItem( ITEMPOS_INVALID, sal_False, sal_False );
    5922           0 : }
    5923             : 
    5924           0 : void MenuBarWindow::GetFocus()
    5925             : {
    5926           0 :     if ( nHighlightedItem == ITEMPOS_INVALID )
    5927             :     {
    5928           0 :         mbAutoPopup = sal_False;    // do not open menu when activated by focus handling like taskpane cycling
    5929           0 :         ChangeHighlightItem( 0, sal_False );
    5930             :     }
    5931           0 : }
    5932             : 
    5933           0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > MenuBarWindow::CreateAccessible()
    5934             : {
    5935           0 :     ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc;
    5936             : 
    5937           0 :     if ( pMenu )
    5938           0 :         xAcc = pMenu->GetAccessible();
    5939             : 
    5940           0 :     return xAcc;
    5941             : }
    5942             : 
    5943           0 : sal_uInt16 MenuBarWindow::AddMenuBarButton( const Image& i_rImage, const Link& i_rLink, const String& i_rToolTip, sal_uInt16 i_nPos )
    5944             : {
    5945             :     // find first free button id
    5946           0 :     sal_uInt16 nId = IID_DOCUMENTCLOSE;
    5947           0 :     std::map< sal_uInt16, AddButtonEntry >::const_iterator it;
    5948           0 :     if( i_nPos > m_aAddButtons.size() )
    5949           0 :         i_nPos = static_cast<sal_uInt16>(m_aAddButtons.size());
    5950           0 :     do
    5951             :     {
    5952           0 :         nId++;
    5953           0 :         it = m_aAddButtons.find( nId );
    5954           0 :     } while( it != m_aAddButtons.end() && nId < 128 );
    5955             :     DBG_ASSERT( nId < 128, "too many addbuttons in menubar" );
    5956           0 :     AddButtonEntry& rNewEntry = m_aAddButtons[nId];
    5957           0 :     rNewEntry.m_nId = nId;
    5958           0 :     rNewEntry.m_aSelectLink = i_rLink;
    5959           0 :     aCloser.InsertItem( nId, i_rImage, 0, 0 );
    5960           0 :     aCloser.calcMinSize();
    5961           0 :     ShowButtons( aCloser.IsItemVisible( IID_DOCUMENTCLOSE ),
    5962           0 :                  aFloatBtn.IsVisible(),
    5963           0 :                  aHideBtn.IsVisible() );
    5964           0 :     ImplLayoutChanged();
    5965             : 
    5966           0 :     if( pMenu->mpSalMenu )
    5967           0 :         pMenu->mpSalMenu->AddMenuBarButton( SalMenuButtonItem( nId, i_rImage, i_rToolTip ) );
    5968             : 
    5969           0 :     return nId;
    5970             : }
    5971             : 
    5972           0 : void MenuBarWindow::SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link& rLink )
    5973             : {
    5974           0 :     std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( nId );
    5975           0 :     if( it != m_aAddButtons.end() )
    5976           0 :         it->second.m_aHighlightLink = rLink;
    5977           0 : }
    5978             : 
    5979           0 : Rectangle MenuBarWindow::GetMenuBarButtonRectPixel( sal_uInt16 nId )
    5980             : {
    5981           0 :     Rectangle aRect;
    5982           0 :     if( m_aAddButtons.find( nId ) != m_aAddButtons.end() )
    5983             :     {
    5984           0 :         if( pMenu->mpSalMenu )
    5985             :         {
    5986           0 :             aRect = pMenu->mpSalMenu->GetMenuBarButtonRectPixel( nId, ImplGetWindowImpl()->mpFrame );
    5987           0 :             if( aRect == Rectangle( Point( -1, -1 ), Size( 1, 1 ) ) )
    5988             :             {
    5989             :                 // system menu button is somehwere but location cannot be determined
    5990           0 :                 return Rectangle();
    5991             :             }
    5992             :         }
    5993             : 
    5994           0 :         if( aRect.IsEmpty() )
    5995             :         {
    5996           0 :             aRect = aCloser.GetItemRect( nId );
    5997           0 :             Point aOffset = aCloser.OutputToScreenPixel( Point() );
    5998           0 :             aRect.Move( aOffset.X(), aOffset.Y() );
    5999             :         }
    6000             :     }
    6001           0 :     return aRect;
    6002             : }
    6003             : 
    6004           0 : void MenuBarWindow::RemoveMenuBarButton( sal_uInt16 nId )
    6005             : {
    6006           0 :     sal_uInt16 nPos = aCloser.GetItemPos( nId );
    6007           0 :     aCloser.RemoveItem( nPos );
    6008           0 :     m_aAddButtons.erase( nId );
    6009           0 :     aCloser.calcMinSize();
    6010           0 :     ImplLayoutChanged();
    6011             : 
    6012           0 :     if( pMenu->mpSalMenu )
    6013           0 :         pMenu->mpSalMenu->RemoveMenuBarButton( nId );
    6014           0 : }
    6015             : 
    6016           0 : bool MenuBarWindow::HandleMenuButtonEvent( sal_uInt16 i_nButtonId )
    6017             : {
    6018           0 :     std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( i_nButtonId );
    6019           0 :     if( it != m_aAddButtons.end() )
    6020             :     {
    6021             :         MenuBar::MenuBarButtonCallbackArg aArg;
    6022           0 :         aArg.nId = it->first;
    6023           0 :         aArg.bHighlight = true;
    6024           0 :         aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
    6025           0 :         return it->second.m_aSelectLink.Call( &aArg );
    6026             :     }
    6027           0 :     return sal_False;
    6028             : }
    6029             : 
    6030         948 : ImplMenuDelData::ImplMenuDelData( const Menu* pMenu )
    6031             : : mpNext( 0 )
    6032         948 : , mpMenu( 0 )
    6033             : {
    6034         948 :     if( pMenu )
    6035         948 :         const_cast< Menu* >( pMenu )->ImplAddDel( *this );
    6036         948 : }
    6037             : 
    6038         948 : ImplMenuDelData::~ImplMenuDelData()
    6039             : {
    6040         948 :     if( mpMenu )
    6041         948 :         const_cast< Menu* >( mpMenu )->ImplRemoveDel( *this );
    6042         948 : }
    6043             : 
    6044             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10