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