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