LibreOffice Module vcl (master) 1
menu.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21#include <sal/log.hxx>
22
23#include <comphelper/lok.hxx>
24#include <vcl/dialoghelper.hxx>
25#include <vcl/svapp.hxx>
26#include <vcl/mnemonic.hxx>
27#include <vcl/image.hxx>
28#include <vcl/event.hxx>
29#include <vcl/help.hxx>
31#include <vcl/decoview.hxx>
32#include <vcl/menu.hxx>
33#include <vcl/taskpanelist.hxx>
34#include <vcl/settings.hxx>
36
37#include <salinst.hxx>
38#include <svdata.hxx>
39#include <strings.hrc>
40#include <window.h>
41#include <salmenu.hxx>
42#include <salframe.hxx>
43
44#include "menubarwindow.hxx"
46#include "menuitemlist.hxx"
47
48#include <com/sun/star/uno/Reference.h>
49#include <com/sun/star/lang/XComponent.hpp>
50#include <com/sun/star/accessibility/XAccessible.hpp>
52#include <rtl/ustrbuf.hxx>
53
54#include <configsettings.hxx>
55
56#include <map>
57#include <string_view>
58#include <vector>
59
60namespace vcl
61{
62
64{
65 std::vector< sal_uInt16 > m_aLineItemIds;
66 std::map< sal_uInt16, tools::Rectangle > m_aVisibleItemBoundRects;
67};
68
69}
70
71using namespace vcl;
72
73#define EXTRAITEMHEIGHT 4
74#define SPACE_AROUND_TITLE 4
75
76static bool ImplAccelDisabled()
77{
78 // display of accelerator strings may be suppressed via configuration
79 static int nAccelDisabled = -1;
80
81 if( nAccelDisabled == -1 )
82 {
83 OUString aStr =
85 getValue( "Menu", "SuppressAccelerators" );
86 nAccelDisabled = aStr.equalsIgnoreAsciiCase("true") ? 1 : 0;
87 }
88 return nAccelDisabled == 1;
89}
90
91static void ImplSetMenuItemData( MenuItemData* pData )
92{
93 // convert data
94 if ( !pData->aImage )
96 else if ( pData->aText.isEmpty() )
98 else
100}
101
102namespace {
103
104void ImplClosePopupToolBox( const VclPtr<vcl::Window>& pWin )
105{
106 if ( pWin->GetType() == WindowType::TOOLBOX && ImplGetDockingManager()->IsInPopupMode( pWin ) )
107 {
108 SystemWindow* pFloatingWindow = ImplGetDockingManager()->GetFloatingWindow(pWin);
109 if (pFloatingWindow)
110 static_cast<FloatingWindow*>(pFloatingWindow)->EndPopupMode( FloatWinPopupEndFlags::CloseAll );
111 }
112}
113
114// TODO: Move to common code with the same function in toolbox
115// Draw the ">>" - more indicator at the coordinates
116void lclDrawMoreIndicator(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
117{
118 rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
119 rRenderContext.SetLineColor();
120
121 if (rRenderContext.GetSettings().GetStyleSettings().GetFaceColor().IsDark())
122 rRenderContext.SetFillColor(COL_WHITE);
123 else
124 rRenderContext.SetFillColor(COL_BLACK);
125 float fScaleFactor = rRenderContext.GetDPIScaleFactor();
126
127 int linewidth = 1 * fScaleFactor;
128 int space = 4 * fScaleFactor;
129
130 tools::Long width = 8 * fScaleFactor;
131 tools::Long height = 5 * fScaleFactor;
132
133 //Keep odd b/c drawing code works better
134 if ( height % 2 == 0 )
135 height--;
136
137 tools::Long heightOrig = height;
138
139 tools::Long x = rRect.Left() + (rRect.getOpenWidth() - width)/2 + 1;
140 tools::Long y = rRect.Top() + (rRect.getOpenHeight() - height)/2 + 1;
141 while( height >= 1)
142 {
143 rRenderContext.DrawRect( tools::Rectangle( x, y, x + linewidth, y ) );
144 x += space;
145 rRenderContext.DrawRect( tools::Rectangle( x, y, x + linewidth, y ) );
146 x -= space;
147 y++;
148 if( height <= heightOrig / 2 + 1) x--;
149 else x++;
150 height--;
151 }
152 rRenderContext.Pop();
153}
154
155} // end anonymous namespace
156
157
159 : mpFirstDel(nullptr),
160 pItemList(new MenuItemList),
161 pStartedFrom(nullptr),
162 pWindow(nullptr),
163 nTitleHeight(0),
164 nEventId(nullptr),
165 mnHighlightedItemPos(ITEMPOS_INVALID),
166 nMenuFlags(MenuFlags::NONE),
167 nSelectedId(0),
168 nImgOrChkPos(0),
169 nTextPos(0),
170 bCanceled(false),
171 bInCallback(false),
172 bKilled(false)
173{
174}
175
177{
178 disposeOnce();
179}
180
182{
184
185 // at the window free the reference to the accessible component
186 // and make sure the MenuFloatingWindow knows about our destruction
187 if ( pWindow )
188 {
189 MenuFloatingWindow* pFloat = static_cast<MenuFloatingWindow*>(pWindow.get());
190 if( pFloat->pMenu.get() == this )
191 pFloat->pMenu.clear();
192 pWindow->SetAccessible( css::uno::Reference< css::accessibility::XAccessible >() );
193 }
194
195 // dispose accessible components
196 if ( mxAccessible.is() )
197 {
198 css::uno::Reference< css::lang::XComponent> xComponent( mxAccessible, css::uno::UNO_QUERY );
199 if ( xComponent.is() )
200 xComponent->dispose();
201 }
202
203 if ( nEventId )
205
206 // Notify deletion of this menu
207 ImplMenuDelData* pDelData = mpFirstDel;
208 while ( pDelData )
209 {
210 pDelData->mpMenu = nullptr;
211 pDelData = pDelData->mpNext;
212 }
213
214 bKilled = true;
215
216 // tdf#140225 when clearing pItemList, keep SalMenu in sync with
217 // their removal during menu teardown
218 for (size_t n = pItemList->size(); n;)
219 {
220 --n;
221 if (mpSalMenu)
222 mpSalMenu->RemoveItem(n);
223 pItemList->Remove(n);
224 }
225
226 assert(!pItemList->size());
227
228 mpLayoutData.reset();
229
230 // Native-support: destroy SalMenu
231 mpSalMenu.reset();
232
234 pWindow.clear();
236}
237
239{
240 MnemonicGenerator aMnemonicGenerator;
241 size_t n;
242 for ( n = 0; n < pItemList->size(); n++ )
243 {
244 MenuItemData* pData = pItemList->GetDataFromPos( n );
245 if ( ! (pData->nBits & MenuItemBits::NOSELECT ) )
246 aMnemonicGenerator.RegisterMnemonic( pData->aText );
247 }
248 for ( n = 0; n < pItemList->size(); n++ )
249 {
250 MenuItemData* pData = pItemList->GetDataFromPos( n );
251 if ( ! (pData->nBits & MenuItemBits::NOSELECT ) )
252 pData->aText = aMnemonicGenerator.CreateMnemonic( pData->aText );
253 }
254}
255
257{
258 bInCallback = true;
259
260 ImplMenuDelData aDelData( this );
261
263
264 if( !aDelData.isDeleted() )
265 {
266 if ( !aActivateHdl.Call( this ) )
267 {
268 if( !aDelData.isDeleted() )
269 {
270 Menu* pStartMenu = ImplGetStartMenu();
271 if ( pStartMenu && ( pStartMenu != this ) )
272 {
273 pStartMenu->bInCallback = true;
274 // MT 11/01: Call EventListener here? I don't know...
275 pStartMenu->aActivateHdl.Call( this );
276 pStartMenu->bInCallback = false;
277 }
278 }
279 }
280 bInCallback = false;
281 }
282
283 if (!aDelData.isDeleted() && !(nMenuFlags & MenuFlags::NoAutoMnemonics))
285}
286
288{
289 for ( size_t n = pItemList->size(); n; )
290 {
291 MenuItemData* pData = pItemList->GetDataFromPos( --n );
292 if ( pData->bIsTemporary )
293 {
294 if ( ImplGetSalMenu() )
296
297 pItemList->Remove( n );
298 }
299 }
300
301 bInCallback = true;
302
303 ImplMenuDelData aDelData( this );
304
305 Menu* pStartMenu = ImplGetStartMenu();
307
308 if( !aDelData.isDeleted() )
309 {
310 if ( !aDeactivateHdl.Call( this ) )
311 {
312 if( !aDelData.isDeleted() )
313 {
314 if ( pStartMenu && ( pStartMenu != this ) )
315 {
316 pStartMenu->bInCallback = true;
317 pStartMenu->aDeactivateHdl.Call( this );
318 pStartMenu->bInCallback = false;
319 }
320 }
321 }
322 }
323
324 if( !aDelData.isDeleted() )
325 {
326 bInCallback = false;
327 }
328}
329
331{
333 if ( pData && (pData->nBits & MenuItemBits::AUTOCHECK) )
334 {
335 bool bChecked = IsItemChecked( nSelectedId );
336 if ( pData->nBits & MenuItemBits::RADIOCHECK )
337 {
338 if ( !bChecked )
340 }
341 else
342 CheckItem( nSelectedId, !bChecked );
343 }
344
345 // call select
346 ImplSVData* pSVData = ImplGetSVData();
347 pSVData->maAppData.mpActivePopupMenu = nullptr; // if new execute in select()
348 nEventId = Application::PostUserEvent( LINK( this, Menu, ImplCallSelect ) );
349}
350
352{
353 ImplMenuDelData aDelData( this );
354
356 if (aDelData.isDeleted())
357 return;
358 if (aSelectHdl.Call(this))
359 return;
360 if (aDelData.isDeleted())
361 return;
362 Menu* pStartMenu = ImplGetStartMenu();
363 if (!pStartMenu || (pStartMenu == this))
364 return;
365 pStartMenu->nSelectedId = nSelectedId;
366 pStartMenu->sSelectedIdent = sSelectedIdent;
367 pStartMenu->aSelectHdl.Call( this );
368}
369
370#if defined(MACOSX)
371void Menu::ImplSelectWithStart( Menu* pSMenu )
372{
373 auto pOldStartedFrom = pStartedFrom;
374 pStartedFrom = pSMenu;
375 auto pOldStartedStarted = pOldStartedFrom ? pOldStartedFrom->pStartedFrom : VclPtr<Menu>();
376 Select();
377 if( pOldStartedFrom )
378 pOldStartedFrom->pStartedFrom = pOldStartedStarted;
379 pStartedFrom = pOldStartedFrom;
380}
381#endif
382
383void Menu::ImplCallEventListeners( VclEventId nEvent, sal_uInt16 nPos )
384{
385 ImplMenuDelData aDelData( this );
386
387 VclMenuEvent aEvent( this, nEvent, nPos );
388
389 // This is needed by atk accessibility bridge
390 if ( nEvent == VclEventId::MenuHighlight )
391 {
393 }
394
395 if ( !aDelData.isDeleted() )
396 {
397 // Copy the list, because this can be destroyed when calling a Link...
398 std::list<Link<VclMenuEvent&,void>> aCopy( maEventListeners );
399 for ( const auto& rLink : aCopy )
400 {
401 if( std::find(maEventListeners.begin(), maEventListeners.end(), rLink) != maEventListeners.end() )
402 rLink.Call( aEvent );
403 }
404 }
405}
406
408{
409 maEventListeners.push_back( rEventListener );
410}
411
413{
414 maEventListeners.remove( rEventListener );
415}
416
418 const OUString& rStr, Menu* pMenu,
419 size_t nPos, const OUString &rIdent)
420{
421 // put Item in MenuItemList
423 nBits, rStr, pMenu, nPos, rIdent);
424
425 // update native menu
426 if (ImplGetSalMenu() && pData->pSalMenuItem)
427 ImplGetSalMenu()->InsertItem(pData->pSalMenuItem.get(), nPos);
428
429 return pData;
430}
431
432void Menu::InsertItem(sal_uInt16 nItemId, const OUString& rStr, MenuItemBits nItemBits,
433 const OUString &rIdent, sal_uInt16 nPos)
434{
435 SAL_WARN_IF( !nItemId, "vcl", "Menu::InsertItem(): ItemId == 0" );
436 SAL_WARN_IF( GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND, "vcl",
437 "Menu::InsertItem(): ItemId already exists" );
438
439 // if Position > ItemCount, append
440 if ( nPos >= pItemList->size() )
442
443 // put Item in MenuItemList
444 NbcInsertItem(nItemId, nItemBits, rStr, this, nPos, rIdent);
445
446 vcl::Window* pWin = ImplGetWindow();
447 mpLayoutData.reset();
448 if ( pWin )
449 {
450 ImplCalcSize( pWin );
451 if ( pWin->IsVisible() )
452 pWin->Invalidate();
453 }
455}
456
457void Menu::InsertItem(sal_uInt16 nItemId, const Image& rImage,
458 MenuItemBits nItemBits, const OUString &rIdent, sal_uInt16 nPos)
459{
460 InsertItem(nItemId, OUString(), nItemBits, rIdent, nPos);
461 SetItemImage( nItemId, rImage );
462}
463
464void Menu::InsertItem(sal_uInt16 nItemId, const OUString& rStr,
465 const Image& rImage, MenuItemBits nItemBits,
466 const OUString &rIdent, sal_uInt16 nPos)
467{
468 InsertItem(nItemId, rStr, nItemBits, rIdent, nPos);
469 SetItemImage( nItemId, rImage );
470}
471
472void Menu::InsertSeparator(const OUString &rIdent, sal_uInt16 nPos)
473{
474 // do nothing if it's a menu bar
475 if (IsMenuBar())
476 return;
477
478 // if position > ItemCount, append
479 if ( nPos >= pItemList->size() )
481
482 // put separator in item list
483 pItemList->InsertSeparator(rIdent, nPos);
484
485 // update native menu
486 size_t itemPos = ( nPos != MENU_APPEND ) ? nPos : pItemList->size() - 1;
487 MenuItemData *pData = pItemList->GetDataFromPos( itemPos );
488 if( ImplGetSalMenu() && pData && pData->pSalMenuItem )
489 ImplGetSalMenu()->InsertItem( pData->pSalMenuItem.get(), nPos );
490
491 mpLayoutData.reset();
492
494}
495
496void Menu::RemoveItem( sal_uInt16 nPos )
497{
498 bool bRemove = false;
499
500 if ( nPos < GetItemCount() )
501 {
502 // update native menu
503 if( ImplGetSalMenu() )
505
506 pItemList->Remove( nPos );
507 bRemove = true;
508 }
509
510 vcl::Window* pWin = ImplGetWindow();
511 if ( pWin )
512 {
513 ImplCalcSize( pWin );
514 if ( pWin->IsVisible() )
515 pWin->Invalidate();
516 }
517 mpLayoutData.reset();
518
519 if ( bRemove )
521}
522
523static void ImplCopyItem( Menu* pThis, const Menu& rMenu, sal_uInt16 nPos, sal_uInt16 nNewPos )
524{
526
528 return;
529
531 pThis->InsertSeparator( {}, nNewPos );
532 else
533 {
534 sal_uInt16 nId = rMenu.GetItemId( nPos );
535
536 SAL_WARN_IF( pThis->GetItemPos( nId ) != MENU_ITEM_NOTFOUND, "vcl",
537 "Menu::CopyItem(): ItemId already exists" );
538
540
541 if (!pData)
542 return;
543
545 pThis->InsertItem( nId, pData->aText, pData->aImage, pData->nBits, pData->sIdent, nNewPos );
546 else if ( eType == MenuItemType::STRING )
547 pThis->InsertItem( nId, pData->aText, pData->nBits, pData->sIdent, nNewPos );
548 else
549 pThis->InsertItem( nId, pData->aImage, pData->nBits, pData->sIdent, nNewPos );
550
551 if ( rMenu.IsItemChecked( nId ) )
552 pThis->CheckItem( nId );
553 if ( !rMenu.IsItemEnabled( nId ) )
554 pThis->EnableItem( nId, false );
555 pThis->SetHelpId( nId, pData->aHelpId );
556 pThis->SetHelpText( nId, pData->aHelpText );
557 pThis->SetAccelKey( nId, pData->aAccelKey );
558 pThis->SetItemCommand( nId, pData->aCommandStr );
559 pThis->SetHelpCommand( nId, pData->aHelpCommandStr );
560
561 PopupMenu* pSubMenu = rMenu.GetPopupMenu( nId );
562 if ( pSubMenu )
563 {
564 // create auto-copy
565 VclPtr<PopupMenu> pNewMenu = VclPtr<PopupMenu>::Create( *pSubMenu );
566 pThis->SetPopupMenu( nId, pNewMenu );
567 }
568 }
569}
570
572{
573 for ( sal_uInt16 i = GetItemCount(); i; i-- )
574 RemoveItem( 0 );
575}
576
577sal_uInt16 Menu::GetItemCount() const
578{
579 return static_cast<sal_uInt16>(pItemList->size());
580}
581
582bool Menu::HasValidEntries(bool bCheckPopups) const
583{
584 bool bValidEntries = false;
585 sal_uInt16 nCount = GetItemCount();
586 for (sal_uInt16 n = 0; !bValidEntries && (n < nCount); n++)
587 {
588 MenuItemData* pItem = pItemList->GetDataFromPos(n);
589 if (pItem->bEnabled && (pItem->eType != MenuItemType::SEPARATOR))
590 {
591 if (bCheckPopups && pItem->pSubMenu)
592 bValidEntries = pItem->pSubMenu->HasValidEntries(true);
593 else
594 bValidEntries = true;
595 }
596 }
597 return bValidEntries;
598}
599
601{
602 sal_uInt16 nItems = 0;
603 for ( size_t n = pItemList->size(); n; )
604 {
605 if ( ImplIsVisible( --n ) )
606 nItems++;
607 }
608 return nItems;
609}
610
612{
613 for ( size_t n = 0; n < pItemList->size(); n++ )
614 {
615 if ( ImplIsVisible( n ) )
616 return n;
617 }
618 return ITEMPOS_INVALID;
619}
620
621sal_uInt16 Menu::ImplGetPrevVisible( sal_uInt16 nPos ) const
622{
623 for ( size_t n = nPos; n; )
624 {
625 if (ImplIsVisible(--n))
626 return n;
627 }
628 return ITEMPOS_INVALID;
629}
630
631sal_uInt16 Menu::ImplGetNextVisible( sal_uInt16 nPos ) const
632{
633 for ( size_t n = nPos+1; n < pItemList->size(); n++ )
634 {
635 if ( ImplIsVisible( n ) )
636 return n;
637 }
638 return ITEMPOS_INVALID;
639}
640
641sal_uInt16 Menu::GetItemId(sal_uInt16 nPos) const
642{
643 MenuItemData* pData = pItemList->GetDataFromPos( nPos );
644
645 if ( pData )
646 return pData->nId;
647 else
648 return 0;
649}
650
651sal_uInt16 Menu::GetItemId(std::u16string_view rIdent) const
652{
653 for (size_t n = 0; n < pItemList->size(); ++n)
654 {
655 MenuItemData* pData = pItemList->GetDataFromPos(n);
656 if (pData && pData->sIdent == rIdent)
657 return pData->nId;
658 }
659 return MENU_ITEM_NOTFOUND;
660}
661
662sal_uInt16 Menu::GetItemPos( sal_uInt16 nItemId ) const
663{
664 size_t nPos;
665 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
666
667 if ( pData )
668 return static_cast<sal_uInt16>(nPos);
669 else
670 return MENU_ITEM_NOTFOUND;
671}
672
673MenuItemType Menu::GetItemType( sal_uInt16 nPos ) const
674{
675 MenuItemData* pData = pItemList->GetDataFromPos( nPos );
676
677 if ( pData )
678 return pData->eType;
679 else
681}
682
683OUString Menu::GetItemIdent(sal_uInt16 nId) const
684{
685 const MenuItemData* pData = pItemList->GetData(nId);
686 return pData ? pData->sIdent : OUString();
687}
688
689void Menu::SetItemBits( sal_uInt16 nItemId, MenuItemBits nBits )
690{
691 size_t nPos;
692 MenuItemData* pData = pItemList->GetData(nItemId, nPos);
693
694 if (pData && (pData->nBits != nBits))
695 {
696 // these two menu item bits are relevant for (accessible) role
698 const bool bRoleBitsChanged = (pData->nBits & nRoleMask) != (nBits & nRoleMask);
699
700 pData->nBits = nBits;
701
702 // update native menu
703 if (ImplGetSalMenu())
705
706 if (bRoleBitsChanged)
708 }
709}
710
711MenuItemBits Menu::GetItemBits( sal_uInt16 nItemId ) const
712{
714 MenuItemData* pData = pItemList->GetData( nItemId );
715 if ( pData )
716 nBits = pData->nBits;
717 return nBits;
718}
719
720void Menu::SetUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc)
721{
722 MenuItemData* pData = pItemList->GetData(nItemId);
723 if (pData)
724 {
725 if (pData->aUserValueReleaseFunc)
726 pData->aUserValueReleaseFunc(pData->nUserValue);
727 pData->aUserValueReleaseFunc = aFunc;
728 pData->nUserValue = nUserValue;
729 }
730}
731
732void* Menu::GetUserValue( sal_uInt16 nItemId ) const
733{
734 MenuItemData* pData = pItemList->GetData( nItemId );
735 return pData ? pData->nUserValue : nullptr;
736}
737
738void Menu::SetPopupMenu( sal_uInt16 nItemId, PopupMenu* pMenu )
739{
740 size_t nPos;
741 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
742
743 // Item does not exist -> return NULL
744 if ( !pData )
745 return;
746
747 // same menu, nothing to do
748 if ( static_cast<PopupMenu*>(pData->pSubMenu.get()) == pMenu )
749 return;
750
751 // remove old menu
752 auto oldSubMenu = pData->pSubMenu;
753
754 // data exchange
755 pData->pSubMenu = pMenu;
756
757 // #112023# Make sure pStartedFrom does not point to invalid (old) data
758 if ( pData->pSubMenu )
759 pData->pSubMenu->pStartedFrom = nullptr;
760
761 // set native submenu
762 if( ImplGetSalMenu() && pData->pSalMenuItem )
763 {
764 if( pMenu )
765 ImplGetSalMenu()->SetSubMenu( pData->pSalMenuItem.get(), pMenu->ImplGetSalMenu(), nPos );
766 else
767 ImplGetSalMenu()->SetSubMenu( pData->pSalMenuItem.get(), nullptr, nPos );
768 }
769
770 oldSubMenu.disposeAndClear();
771
773}
774
775PopupMenu* Menu::GetPopupMenu( sal_uInt16 nItemId ) const
776{
777 MenuItemData* pData = pItemList->GetData( nItemId );
778
779 if ( pData )
780 return static_cast<PopupMenu*>(pData->pSubMenu.get());
781 else
782 return nullptr;
783}
784
785void Menu::SetAccelKey( sal_uInt16 nItemId, const KeyCode& rKeyCode )
786{
787 size_t nPos;
788 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
789
790 if ( !pData )
791 return;
792
793 if ( pData->aAccelKey == rKeyCode )
794 return;
795
796 pData->aAccelKey = rKeyCode;
797
798 // update native menu
799 if( ImplGetSalMenu() && pData->pSalMenuItem )
800 ImplGetSalMenu()->SetAccelerator( nPos, pData->pSalMenuItem.get(), rKeyCode, rKeyCode.GetName() );
801}
802
803KeyCode Menu::GetAccelKey( sal_uInt16 nItemId ) const
804{
805 MenuItemData* pData = pItemList->GetData( nItemId );
806
807 if ( pData )
808 return pData->aAccelKey;
809 else
810 return KeyCode();
811}
812
813KeyEvent Menu::GetActivationKey( sal_uInt16 nItemId ) const
814{
815 KeyEvent aRet;
816 MenuItemData* pData = pItemList->GetData( nItemId );
817 if( pData )
818 {
819 sal_Int32 nPos = pData->aText.indexOf( '~' );
820 if( nPos != -1 && nPos < pData->aText.getLength()-1 )
821 {
822 sal_uInt16 nCode = 0;
823 sal_Unicode cAccel = pData->aText[nPos+1];
824 if( cAccel >= 'a' && cAccel <= 'z' )
825 nCode = KEY_A + (cAccel-'a');
826 else if( cAccel >= 'A' && cAccel <= 'Z' )
827 nCode = KEY_A + (cAccel-'A');
828 else if( cAccel >= '0' && cAccel <= '9' )
829 nCode = KEY_0 + (cAccel-'0');
830
831 aRet = KeyEvent( cAccel, KeyCode( nCode, KEY_MOD2 ) );
832 }
833
834 }
835 return aRet;
836}
837
838void Menu::CheckItem( sal_uInt16 nItemId, bool bCheck )
839{
840 size_t nPos;
841 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
842
843 if ( !pData || pData->bChecked == bCheck )
844 return;
845
846 // if radio-check, then uncheck previous
847 if ( bCheck && (pData->nBits & MenuItemBits::AUTOCHECK) &&
849 {
850 MenuItemData* pGroupData;
851 sal_uInt16 nGroupPos;
852 sal_uInt16 nItemCount = GetItemCount();
853 bool bFound = false;
854
855 nGroupPos = nPos;
856 while ( nGroupPos )
857 {
858 pGroupData = pItemList->GetDataFromPos( nGroupPos-1 );
859 if ( pGroupData->nBits & MenuItemBits::RADIOCHECK )
860 {
861 if ( IsItemChecked( pGroupData->nId ) )
862 {
863 CheckItem( pGroupData->nId, false );
864 bFound = true;
865 break;
866 }
867 }
868 else
869 break;
870 nGroupPos--;
871 }
872
873 if ( !bFound )
874 {
875 nGroupPos = nPos+1;
876 while ( nGroupPos < nItemCount )
877 {
878 pGroupData = pItemList->GetDataFromPos( nGroupPos );
879 if ( pGroupData->nBits & MenuItemBits::RADIOCHECK )
880 {
881 if ( IsItemChecked( pGroupData->nId ) )
882 {
883 CheckItem( pGroupData->nId, false );
884 break;
885 }
886 }
887 else
888 break;
889 nGroupPos++;
890 }
891 }
892 }
893
894 pData->bChecked = bCheck;
895
896 // update native menu
897 if( ImplGetSalMenu() )
898 ImplGetSalMenu()->CheckItem( nPos, bCheck );
899
901}
902
903void Menu::CheckItem( std::u16string_view rIdent , bool bCheck )
904{
905 CheckItem( GetItemId( rIdent ), bCheck );
906}
907
908bool Menu::IsItemChecked( sal_uInt16 nItemId ) const
909{
910 size_t nPos;
911 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
912
913 if ( !pData )
914 return false;
915
916 return pData->bChecked;
917}
918
919void Menu::EnableItem( sal_uInt16 nItemId, bool bEnable )
920{
921 size_t nPos;
922 MenuItemData* pItemData = pItemList->GetData( nItemId, nPos );
923
924 if ( !(pItemData && ( pItemData->bEnabled != bEnable )) )
925 return;
926
927 pItemData->bEnabled = bEnable;
928
929 vcl::Window* pWin = ImplGetWindow();
930 if ( pWin && pWin->IsVisible() )
931 {
932 SAL_WARN_IF(!IsMenuBar(), "vcl", "Menu::EnableItem - Popup visible!" );
933 tools::Long nX = 0;
934 size_t nCount = pItemList->size();
935 for ( size_t n = 0; n < nCount; n++ )
936 {
937 MenuItemData* pData = pItemList->GetDataFromPos( n );
938 if ( n == nPos )
939 {
940 pWin->Invalidate( tools::Rectangle( Point( nX, 0 ), Size( pData->aSz.Width(), pData->aSz.Height() ) ) );
941 break;
942 }
943 nX += pData->aSz.Width();
944 }
945 }
946 // update native menu
947 if( ImplGetSalMenu() )
948 ImplGetSalMenu()->EnableItem( nPos, bEnable );
949
951}
952
953bool Menu::IsItemEnabled( sal_uInt16 nItemId ) const
954{
955 size_t nPos;
956 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
957
958 if ( !pData )
959 return false;
960
961 return pData->bEnabled;
962}
963
964void Menu::ShowItem( sal_uInt16 nItemId, bool bVisible )
965{
966 size_t nPos;
967 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
968
969 SAL_WARN_IF(IsMenuBar() && !bVisible , "vcl", "Menu::ShowItem - ignored for menu bar entries!");
970 if (IsMenuBar() || !pData || (pData->bVisible == bVisible))
971 return;
972
973 vcl::Window* pWin = ImplGetWindow();
974 if ( pWin && pWin->IsVisible() )
975 {
976 SAL_WARN( "vcl", "Menu::ShowItem - ignored for visible popups!" );
977 return;
978 }
979 pData->bVisible = bVisible;
980
981 // update native menu
982 if( ImplGetSalMenu() )
984}
985
986void Menu::SetItemText( sal_uInt16 nItemId, const OUString& rStr )
987{
988 size_t nPos;
989 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
990
991 if ( !pData )
992 return;
993
994 if ( rStr == pData->aText )
995 return;
996
997 pData->aText = rStr;
998 // Clear layout for aText.
999 pData->aTextGlyphs.Invalidate();
1001 // update native menu
1002 if( ImplGetSalMenu() && pData->pSalMenuItem )
1003 ImplGetSalMenu()->SetItemText( nPos, pData->pSalMenuItem.get(), rStr );
1004
1005 vcl::Window* pWin = ImplGetWindow();
1006 mpLayoutData.reset();
1007 if (pWin && IsMenuBar())
1008 {
1009 ImplCalcSize( pWin );
1010 if ( pWin->IsVisible() )
1011 pWin->Invalidate();
1012 }
1013
1015}
1016
1017OUString Menu::GetItemText( sal_uInt16 nItemId ) const
1018{
1019 size_t nPos;
1020 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
1021
1022 if ( pData )
1023 return pData->aText;
1024
1025 return OUString();
1026}
1027
1028void Menu::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
1029{
1030 size_t nPos;
1031 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
1032
1033 if ( !pData )
1034 return;
1035
1036 pData->aImage = rImage;
1038
1039 // update native menu
1040 if( ImplGetSalMenu() && pData->pSalMenuItem )
1041 ImplGetSalMenu()->SetItemImage( nPos, pData->pSalMenuItem.get(), rImage );
1042}
1043
1044Image Menu::GetItemImage( sal_uInt16 nItemId ) const
1045{
1046 MenuItemData* pData = pItemList->GetData( nItemId );
1047
1048 if ( pData )
1049 return pData->aImage;
1050 else
1051 return Image();
1052}
1053
1054void Menu::SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand )
1055{
1056 size_t nPos;
1057 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
1058
1059 if ( pData )
1060 pData->aCommandStr = rCommand;
1061}
1062
1063OUString Menu::GetItemCommand( sal_uInt16 nItemId ) const
1064{
1065 MenuItemData* pData = pItemList->GetData( nItemId );
1066
1067 if (pData)
1068 return pData->aCommandStr;
1069
1070 return OUString();
1071}
1072
1073void Menu::SetHelpCommand( sal_uInt16 nItemId, const OUString& rStr )
1074{
1075 MenuItemData* pData = pItemList->GetData( nItemId );
1076
1077 if ( pData )
1078 pData->aHelpCommandStr = rStr;
1079}
1080
1081OUString Menu::GetHelpCommand( sal_uInt16 nItemId ) const
1082{
1083 MenuItemData* pData = pItemList->GetData( nItemId );
1084
1085 if ( pData )
1086 return pData->aHelpCommandStr;
1087
1088 return OUString();
1089}
1090
1091void Menu::SetHelpText( sal_uInt16 nItemId, const OUString& rStr )
1092{
1093 MenuItemData* pData = pItemList->GetData( nItemId );
1094
1095 if ( pData )
1096 pData->aHelpText = rStr;
1097}
1098
1099OUString Menu::ImplGetHelpText( sal_uInt16 nItemId ) const
1100{
1101 MenuItemData* pData = pItemList->GetData( nItemId );
1102
1103 if (!pData)
1104 return OUString();
1105
1106 if ( pData->aHelpText.isEmpty() &&
1107 (( !pData->aHelpId.isEmpty() ) || ( !pData->aCommandStr.isEmpty() )))
1108 {
1109 Help* pHelp = Application::GetHelp();
1110 if ( pHelp )
1111 {
1112 if (!pData->aCommandStr.isEmpty())
1113 pData->aHelpText = pHelp->GetHelpText( pData->aCommandStr, static_cast<weld::Widget*>(nullptr) );
1114 if (pData->aHelpText.isEmpty() && !pData->aHelpId.isEmpty())
1115 pData->aHelpText = pHelp->GetHelpText( pData->aHelpId, static_cast<weld::Widget*>(nullptr) );
1116 }
1117 }
1118
1119 //Fallback to Menu::GetAccessibleDescription without reentry to GetHelpText()
1120 if (pData->aHelpText.isEmpty())
1121 return pData->aAccessibleDescription;
1122 return pData->aHelpText;
1123}
1124
1125OUString Menu::GetHelpText( sal_uInt16 nItemId ) const
1126{
1127 return ImplGetHelpText( nItemId );
1128}
1129
1130void Menu::SetTipHelpText( sal_uInt16 nItemId, const OUString& rStr )
1131{
1132 MenuItemData* pData = pItemList->GetData( nItemId );
1133
1134 if ( pData )
1135 pData->aTipHelpText = rStr;
1136}
1137
1138OUString Menu::GetTipHelpText( sal_uInt16 nItemId ) const
1139{
1140 MenuItemData* pData = pItemList->GetData( nItemId );
1141
1142 if ( pData )
1143 return pData->aTipHelpText;
1144
1145 return OUString();
1146}
1147
1148void Menu::SetHelpId( sal_uInt16 nItemId, const OUString& rHelpId )
1149{
1150 MenuItemData* pData = pItemList->GetData( nItemId );
1151
1152 if ( pData )
1153 pData->aHelpId = rHelpId;
1154}
1155
1156OUString Menu::GetHelpId( sal_uInt16 nItemId ) const
1157{
1158 OUString aRet;
1159
1160 MenuItemData* pData = pItemList->GetData( nItemId );
1161
1162 if ( pData )
1163 {
1164 if ( !pData->aHelpId.isEmpty() )
1165 aRet = pData->aHelpId;
1166 else
1167 aRet = pData->aCommandStr;
1168 }
1169
1170 return aRet;
1171}
1172
1173Menu& Menu::operator=( const Menu& rMenu )
1174{
1175 if(this == &rMenu)
1176 return *this;
1177
1178 // clean up
1179 Clear();
1180
1181 // copy items
1182 sal_uInt16 nCount = rMenu.GetItemCount();
1183 for ( sal_uInt16 i = 0; i < nCount; i++ )
1184 ImplCopyItem( this, rMenu, i, MENU_APPEND );
1185
1186 aActivateHdl = rMenu.aActivateHdl;
1188 aSelectHdl = rMenu.aSelectHdl;
1189 aTitleText = rMenu.aTitleText;
1190 nTitleHeight = rMenu.nTitleHeight;
1191
1192 return *this;
1193}
1194
1195// Returns true if the item is completely hidden on the GUI and shouldn't
1196// be possible to interact with
1197bool Menu::ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const
1198{
1199 MenuItemData* pData = pItemList->GetDataFromPos(nPos);
1200 if (pData)
1201 {
1202 MenuItemData* pPreviousData = pItemList->GetDataFromPos( nPos - 1 );
1203 if (pPreviousData && pPreviousData->bHiddenOnGUI)
1204 {
1205 return true;
1206 }
1207 }
1208 return false;
1209}
1210
1211bool Menu::ImplIsVisible( sal_uInt16 nPos ) const
1212{
1213 bool bVisible = true;
1214
1215 MenuItemData* pData = pItemList->GetDataFromPos( nPos );
1216 // check general visibility first
1217 if( pData && !pData->bVisible )
1218 bVisible = false;
1219
1220 if ( bVisible && pData && pData->eType == MenuItemType::SEPARATOR )
1221 {
1222 if( nPos == 0 ) // no separator should be shown at the very beginning
1223 bVisible = false;
1224 else
1225 {
1226 // always avoid adjacent separators
1227 size_t nCount = pItemList->size();
1228 size_t n;
1229 MenuItemData* pNextData = nullptr;
1230 // search next visible item
1231 for( n = nPos + 1; n < nCount; n++ )
1232 {
1233 pNextData = pItemList->GetDataFromPos( n );
1234 if( pNextData && pNextData->bVisible )
1235 {
1236 if( pNextData->eType == MenuItemType::SEPARATOR || ImplIsVisible(n) )
1237 break;
1238 }
1239 }
1240 if( n == nCount ) // no next visible item
1241 bVisible = false;
1242 // check for separator
1243 if( pNextData && pNextData->bVisible && pNextData->eType == MenuItemType::SEPARATOR )
1244 bVisible = false;
1245
1246 if( bVisible )
1247 {
1248 for( n = nPos; n > 0; n-- )
1249 {
1250 pNextData = pItemList->GetDataFromPos( n-1 );
1251 if( pNextData && pNextData->bVisible )
1252 {
1253 if( pNextData->eType != MenuItemType::SEPARATOR && ImplIsVisible(n-1) )
1254 break;
1255 }
1256 }
1257 if( n == 0 ) // no previous visible item
1258 bVisible = false;
1259 }
1260 }
1261 }
1262
1263 // not allowed for menubar, as I do not know
1264 // whether a menu-entry will disappear or will appear
1267 {
1268 if( !pData ) // e.g. nPos == ITEMPOS_INVALID
1269 bVisible = false;
1270 else if ( pData->eType != MenuItemType::SEPARATOR ) // separators handled above
1271 {
1272 // tdf#86850 Always display clipboard functions
1273 if ( pData->aCommandStr == ".uno:Cut" || pData->aCommandStr == ".uno:Copy" || pData->aCommandStr == ".uno:Paste" ||
1274 pData->sIdent == ".uno:Cut" || pData->sIdent == ".uno:Copy" || pData->sIdent == ".uno:Paste" )
1275 bVisible = true;
1276 else
1277 // bVisible = pData->bEnabled && ( !pData->pSubMenu || pData->pSubMenu->HasValidEntries( true ) );
1278 bVisible = pData->bEnabled; // do not check submenus as they might be filled at Activate().
1279 }
1280 }
1281
1282 return bVisible;
1283}
1284
1285bool Menu::IsItemPosVisible( sal_uInt16 nItemPos ) const
1286{
1287 return IsMenuVisible() && ImplIsVisible( nItemPos );
1288}
1289
1291{
1292 return pWindow && pWindow->IsReallyVisible();
1293}
1294
1295bool Menu::ImplIsSelectable( sal_uInt16 nPos ) const
1296{
1297 bool bSelectable = true;
1298
1299 MenuItemData* pData = pItemList->GetDataFromPos( nPos );
1300 // check general visibility first
1301 if ( pData && ( pData->nBits & MenuItemBits::NOSELECT ) )
1302 bSelectable = false;
1303
1304 return bSelectable;
1305}
1306
1307css::uno::Reference<css::accessibility::XAccessible> Menu::GetAccessible()
1308{
1309 // Since PopupMenu are sometimes shared by different instances of MenuBar, the mxAccessible member gets
1310 // overwritten and may contain a disposed object when the initial menubar gets set again. So use the
1311 // mxAccessible member only for sub menus.
1312 if (pStartedFrom && pStartedFrom != this)
1313 {
1314 for ( sal_uInt16 i = 0, nCount = pStartedFrom->GetItemCount(); i < nCount; ++i )
1315 {
1316 sal_uInt16 nItemId = pStartedFrom->GetItemId( i );
1317 if ( static_cast< Menu* >( pStartedFrom->GetPopupMenu( nItemId ) ) == this )
1318 {
1319 css::uno::Reference<css::accessibility::XAccessible> xParent = pStartedFrom->GetAccessible();
1320 if ( xParent.is() )
1321 {
1322 css::uno::Reference<css::accessibility::XAccessibleContext> xParentContext( xParent->getAccessibleContext() );
1323 if (xParentContext.is())
1324 return xParentContext->getAccessibleChild( i );
1325 }
1326 }
1327 }
1328 }
1329 else if ( !mxAccessible.is() )
1330 {
1332 if ( pWrapper )
1333 mxAccessible = pWrapper->CreateAccessible(this, IsMenuBar());
1334 }
1335
1336 return mxAccessible;
1337}
1338
1339void Menu::SetAccessible(const css::uno::Reference<css::accessibility::XAccessible>& rxAccessible )
1340{
1341 mxAccessible = rxAccessible;
1342}
1343
1344Size Menu::ImplGetNativeCheckAndRadioSize(vcl::RenderContext const & rRenderContext, tools::Long& rCheckHeight, tools::Long& rRadioHeight ) const
1345{
1346 tools::Long nCheckWidth = 0, nRadioWidth = 0;
1347 rCheckHeight = rRadioHeight = 0;
1348
1349 if (!IsMenuBar())
1350 {
1351 ImplControlValue aVal;
1352 tools::Rectangle aNativeBounds;
1353 tools::Rectangle aNativeContent;
1354
1355 tools::Rectangle aCtrlRegion(tools::Rectangle(Point(), Size(100, 15)));
1357 {
1359 aCtrlRegion, ControlState::ENABLED, aVal,
1360 aNativeBounds, aNativeContent))
1361 {
1362 rCheckHeight = aNativeBounds.GetHeight() - 1;
1363 nCheckWidth = aNativeContent.GetWidth() - 1;
1364 }
1365 }
1367 {
1369 aCtrlRegion, ControlState::ENABLED, aVal,
1370 aNativeBounds, aNativeContent))
1371 {
1372 rRadioHeight = aNativeBounds.GetHeight() - 1;
1373 nRadioWidth = aNativeContent.GetWidth() - 1;
1374 }
1375 }
1376 }
1377 return Size(std::max(nCheckWidth, nRadioWidth), std::max(rCheckHeight, rRadioHeight));
1378}
1379
1380bool Menu::ImplGetNativeSubmenuArrowSize(vcl::RenderContext const & rRenderContext, Size& rArrowSize, tools::Long& rArrowSpacing)
1381{
1382 ImplControlValue aVal;
1383 tools::Rectangle aCtrlRegion(tools::Rectangle(Point(), Size(100, 15)));
1385 {
1386 tools::Rectangle aNativeContent;
1387 tools::Rectangle aNativeBounds;
1389 aCtrlRegion, ControlState::ENABLED,
1390 aVal, aNativeBounds, aNativeContent))
1391 {
1392 Size aSize(aNativeContent.GetWidth(), aNativeContent.GetHeight());
1393 rArrowSize = aSize;
1394 rArrowSpacing = aNativeBounds.GetWidth() - aNativeContent.GetWidth();
1395 return true;
1396 }
1397 }
1398 return false;
1399}
1400
1402{
1403 SAL_WARN_IF( rDel.mpMenu, "vcl", "Menu::ImplAddDel(): cannot add ImplMenuDelData twice !" );
1404 if( !rDel.mpMenu )
1405 {
1406 rDel.mpMenu = this;
1407 rDel.mpNext = mpFirstDel;
1408 mpFirstDel = &rDel;
1409 }
1410}
1411
1413{
1414 rDel.mpMenu = nullptr;
1415 if ( mpFirstDel == &rDel )
1416 {
1417 mpFirstDel = rDel.mpNext;
1418 }
1419 else
1420 {
1422 while ( pData && (pData->mpNext != &rDel) )
1423 pData = pData->mpNext;
1424
1425 SAL_WARN_IF( !pData, "vcl", "Menu::ImplRemoveDel(): ImplMenuDelData not registered !" );
1426 if( pData )
1427 pData->mpNext = rDel.mpNext;
1428 }
1429}
1430
1432{
1433 // | Check/Radio/Image| Text| Accel/Popup|
1434
1435 // for symbols: nFontHeight x nFontHeight
1436 tools::Long nFontHeight = pWin->GetTextHeight();
1437 tools::Long nExtra = nFontHeight/4;
1438
1439 tools::Long nMinMenuItemHeight = nFontHeight;
1440 tools::Long nCheckHeight = 0, nRadioHeight = 0;
1441 Size aMarkSize = ImplGetNativeCheckAndRadioSize(*pWin->GetOutDev(), nCheckHeight, nRadioHeight);
1442 if( aMarkSize.Height() > nMinMenuItemHeight )
1443 nMinMenuItemHeight = aMarkSize.Height();
1444
1445 tools::Long aMaxImgWidth = 0;
1446
1447 const StyleSettings& rSettings = pWin->GetSettings().GetStyleSettings();
1448 if ( rSettings.GetUseImagesInMenus() )
1449 {
1450 if ( 16 > nMinMenuItemHeight )
1451 nMinMenuItemHeight = 16;
1452 for ( size_t i = pItemList->size(); i; )
1453 {
1454 MenuItemData* pData = pItemList->GetDataFromPos( --i );
1455 if ( ImplIsVisible( i )
1456 && ( ( pData->eType == MenuItemType::IMAGE )
1457 || ( pData->eType == MenuItemType::STRINGIMAGE )
1458 )
1459 )
1460 {
1461 Size aImgSz = pData->aImage.GetSizePixel();
1462 if ( aImgSz.Width() > aMaxImgWidth )
1463 aMaxImgWidth = aImgSz.Width();
1464 if ( aImgSz.Height() > nMinMenuItemHeight )
1465 nMinMenuItemHeight = aImgSz.Height();
1466 break;
1467 }
1468 }
1469 }
1470
1471 Size aSz;
1472 tools::Long nMaxWidth = 0;
1473
1474 for ( size_t n = pItemList->size(); n; )
1475 {
1476 MenuItemData* pData = pItemList->GetDataFromPos( --n );
1477
1478 pData->aSz.setHeight( 0 );
1479 pData->aSz.setWidth( 0 );
1480
1481 if ( ImplIsVisible( n ) )
1482 {
1483 tools::Long nWidth = 0;
1484
1485 // Separator
1486 if (!IsMenuBar()&& (pData->eType == MenuItemType::SEPARATOR))
1487 {
1488 pData->aSz.setHeight( 4 );
1489 }
1490
1491 // Image:
1492 if (!IsMenuBar() && ((pData->eType == MenuItemType::IMAGE) || (pData->eType == MenuItemType::STRINGIMAGE)))
1493 {
1494 tools::Long aImgHeight = pData->aImage.GetSizePixel().Height();
1495
1496 aImgHeight += 4; // add a border for native marks
1497 if (aImgHeight > pData->aSz.Height())
1498 pData->aSz.setHeight(aImgHeight);
1499 }
1500
1501 // Check Buttons:
1502 if (!IsMenuBar() && pData->HasCheck())
1503 {
1504 // checks / images take the same place
1505 if( ( pData->eType != MenuItemType::IMAGE ) && ( pData->eType != MenuItemType::STRINGIMAGE ) )
1506 {
1507 nWidth += aMarkSize.Width() + nExtra * 2;
1508 if (aMarkSize.Height() > pData->aSz.Height())
1509 pData->aSz.setHeight(aMarkSize.Height());
1510 }
1511 }
1512
1513 // Text:
1514 if ( (pData->eType == MenuItemType::STRING) || (pData->eType == MenuItemType::STRINGIMAGE) )
1515 {
1516 const SalLayoutGlyphs* pGlyphs = pData->GetTextGlyphs(pWin->GetOutDev());
1517 tools::Long nTextWidth = pWin->GetOutDev()->GetCtrlTextWidth(pData->aText, pGlyphs);
1518 tools::Long nTextHeight = pWin->GetTextHeight() + EXTRAITEMHEIGHT;
1519
1520 if (IsMenuBar())
1521 {
1522 if ( nTextHeight > pData->aSz.Height() )
1523 pData->aSz.setHeight( nTextHeight );
1524
1525 pData->aSz.setWidth( nTextWidth + 4*nExtra );
1526 aSz.AdjustWidth(pData->aSz.Width() );
1527 }
1528 else
1529 pData->aSz.setHeight( std::max( std::max( nTextHeight, pData->aSz.Height() ), nMinMenuItemHeight ) );
1530
1531 nWidth += nTextWidth;
1532 }
1533
1534 // Accel
1535 if (!IsMenuBar()&& pData->aAccelKey.GetCode() && !ImplAccelDisabled())
1536 {
1537 OUString aName = pData->aAccelKey.GetName();
1538 tools::Long nAccWidth = pWin->GetTextWidth( aName );
1539 nAccWidth += nExtra;
1540 nWidth += nAccWidth;
1541 }
1542
1543 // SubMenu?
1544 if (!IsMenuBar() && pData->pSubMenu)
1545 {
1546 if ( nFontHeight > nWidth )
1547 nWidth += nFontHeight;
1548
1549 pData->aSz.setHeight( std::max( std::max( nFontHeight, pData->aSz.Height() ), nMinMenuItemHeight ) );
1550 }
1551
1552 if (!IsMenuBar())
1553 aSz.AdjustHeight(pData->aSz.Height() );
1554
1555 if ( nWidth > nMaxWidth )
1556 nMaxWidth = nWidth;
1557
1558 }
1559 }
1560
1561 // Additional space for title
1562 nTitleHeight = 0;
1563 if (!IsMenuBar() && aTitleText.getLength() > 0) {
1564 // Set expected font
1565 pWin->GetOutDev()->Push(PushFlags::FONT);
1566 vcl::Font aFont = pWin->GetFont();
1567 aFont.SetWeight(WEIGHT_BOLD);
1568 pWin->SetFont(aFont);
1569
1570 // Compute text bounding box
1571 tools::Rectangle aTextBoundRect;
1572 pWin->GetOutDev()->GetTextBoundRect(aTextBoundRect, aTitleText);
1573
1574 // Vertically, one height of char + extra space for decoration
1575 nTitleHeight = aTextBoundRect.GetSize().Height() + 4 * SPACE_AROUND_TITLE ;
1577
1578 tools::Long nWidth = aTextBoundRect.GetSize().Width() + 4 * SPACE_AROUND_TITLE;
1579 pWin->GetOutDev()->Pop();
1580 if ( nWidth > nMaxWidth )
1581 nMaxWidth = nWidth;
1582 }
1583
1584 if (!IsMenuBar())
1585 {
1586 // popup menus should not be wider than half the screen
1587 // except on rather small screens
1588 // TODO: move GetScreenNumber from SystemWindow to Window ?
1589 // currently we rely on internal privileges
1590 unsigned int nDisplayScreen = pWin->ImplGetWindowImpl()->mpFrame->maGeometry.screen();
1591 tools::Rectangle aDispRect( Application::GetScreenPosSizePixel( nDisplayScreen ) );
1592 tools::Long nScreenWidth = aDispRect.GetWidth() >= 800 ? aDispRect.GetWidth() : 800;
1593 if( nMaxWidth > nScreenWidth/2 )
1594 nMaxWidth = nScreenWidth/2;
1595
1596 sal_uInt16 gfxExtra = static_cast<sal_uInt16>(std::max( nExtra, tools::Long(7) )); // #107710# increase space between checkmarks/images/text
1597 nImgOrChkPos = static_cast<sal_uInt16>(nExtra);
1598 tools::Long nImgOrChkWidth = 0;
1599 if( aMarkSize.Height() > 0 ) // NWF case
1600 nImgOrChkWidth = aMarkSize.Height() + nExtra;
1601 else // non NWF case
1602 nImgOrChkWidth = nFontHeight/2 + gfxExtra;
1603 nImgOrChkWidth = std::max( nImgOrChkWidth, aMaxImgWidth + gfxExtra );
1604 nTextPos = static_cast<sal_uInt16>(nImgOrChkPos + nImgOrChkWidth);
1605 nTextPos = nTextPos + gfxExtra;
1606
1607 aSz.setWidth( nTextPos + nMaxWidth + nExtra );
1608 aSz.AdjustWidth(4*nExtra ); // a _little_ more ...
1609
1612 }
1613 else
1614 {
1615 nTextPos = static_cast<sal_uInt16>(2*nExtra);
1616 aSz.setHeight( nFontHeight+6 );
1617
1618 // get menubar height from native methods if supported
1620 {
1621 ImplControlValue aVal;
1622 tools::Rectangle aNativeBounds;
1623 tools::Rectangle aNativeContent;
1624 Point tmp( 0, 0 );
1625 tools::Rectangle aCtrlRegion( tmp, Size( 100, 15 ) );
1628 aCtrlRegion,
1630 aVal,
1631 aNativeBounds,
1632 aNativeContent )
1633 )
1634 {
1635 int nNativeHeight = aNativeBounds.GetHeight();
1636 if( nNativeHeight > aSz.Height() )
1637 aSz.setHeight( nNativeHeight );
1638 }
1639 }
1640
1641 // account for the size of the close button, which actually is a toolbox
1642 // due to NWF this is variable
1643 tools::Long nCloseButtonHeight = static_cast<MenuBarWindow*>(pWindow.get())->MinCloseButtonSize().Height();
1644 if (aSz.Height() < nCloseButtonHeight)
1645 aSz.setHeight( nCloseButtonHeight );
1646 }
1647
1648 return aSz;
1649}
1650
1651static void ImplPaintCheckBackground(vcl::RenderContext & rRenderContext, vcl::Window const & rWindow, const tools::Rectangle& i_rRect, bool i_bHighlight)
1652{
1653 bool bNativeOk = false;
1655 {
1656 ImplControlValue aControlValue;
1657 aControlValue.setTristateVal(ButtonValue::On);
1658 tools::Rectangle r = i_rRect;
1659 r.AdjustBottom(1);
1660
1662 r,
1664 aControlValue,
1665 OUString());
1666 }
1667
1668 if (!bNativeOk)
1669 {
1670 const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
1671 Color aColor( i_bHighlight ? rSettings.GetMenuHighlightTextColor() : rSettings.GetHighlightColor() );
1672 RenderTools::DrawSelectionBackground(rRenderContext, rWindow, i_rRect, 0, i_bHighlight, true, false, nullptr, 2, &aColor);
1673 }
1674}
1675
1676static OUString getShortenedString( const OUString& i_rLong, vcl::RenderContext const & rRenderContext, tools::Long i_nMaxWidth )
1677{
1678 sal_Int32 nPos = -1;
1679 OUString aNonMnem(removeMnemonicFromString(i_rLong, nPos));
1680 aNonMnem = rRenderContext.GetEllipsisString( aNonMnem, i_nMaxWidth, DrawTextFlags::CenterEllipsis);
1681 // re-insert mnemonic
1682 if (nPos != -1)
1683 {
1684 if (nPos < aNonMnem.getLength() && i_rLong[nPos+1] == aNonMnem[nPos])
1685 {
1686 OUString aTmp = OUString::Concat(aNonMnem.subView(0, nPos)) + "~" + aNonMnem.subView(nPos);
1687 aNonMnem = aTmp;
1688 }
1689 }
1690 return aNonMnem;
1691}
1692
1693void Menu::ImplPaintMenuTitle(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) const
1694{
1695 // Save previous graphical settings, set new one
1696 rRenderContext.Push(PushFlags::FONT | PushFlags::FILLCOLOR);
1697 Wallpaper aOldBackground = rRenderContext.GetBackground();
1698
1699 Color aBackgroundColor = rRenderContext.GetSettings().GetStyleSettings().GetMenuBarColor();
1700 rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
1701 rRenderContext.SetFillColor(aBackgroundColor);
1702 vcl::Font aFont = rRenderContext.GetFont();
1703 aFont.SetWeight(WEIGHT_BOLD);
1704 rRenderContext.SetFont(aFont);
1705
1706 // Draw background rectangle
1707 tools::Rectangle aBgRect(rRect);
1708 int nOuterSpaceX = ImplGetSVData()->maNWFData.mnMenuFormatBorderX;
1710 aBgRect.setWidth(aBgRect.getOpenWidth() - 2 * SPACE_AROUND_TITLE - 2 * nOuterSpaceX);
1712 rRenderContext.DrawRect(aBgRect);
1713
1714 // Draw the text centered
1715 Point aTextTopLeft(aBgRect.TopLeft());
1716 tools::Rectangle aTextBoundRect;
1717 rRenderContext.GetTextBoundRect( aTextBoundRect, aTitleText );
1718 aTextTopLeft.AdjustX((aBgRect.getOpenWidth() - aTextBoundRect.GetSize().Width()) / 2 );
1719 aTextTopLeft.AdjustY((aBgRect.GetHeight() - aTextBoundRect.GetSize().Height()) / 2
1720 - aTextBoundRect.Top() );
1721 rRenderContext.DrawText(aTextTopLeft, aTitleText, 0, aTitleText.getLength());
1722
1723 // Restore
1724 rRenderContext.Pop();
1725 rRenderContext.SetBackground(aOldBackground);
1726}
1727
1728void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize,
1729 sal_uInt16 nBorder, tools::Long nStartY, MenuItemData const * pThisItemOnly,
1730 bool bHighlighted, bool bLayout, bool bRollover) const
1731{
1732 // for symbols: nFontHeight x nFontHeight
1733 tools::Long nFontHeight = rRenderContext.GetTextHeight();
1734 tools::Long nExtra = nFontHeight / 4;
1735
1736 tools::Long nCheckHeight = 0, nRadioHeight = 0;
1737 ImplGetNativeCheckAndRadioSize(rRenderContext, nCheckHeight, nRadioHeight);
1738
1739 DecorationView aDecoView(&rRenderContext);
1740 const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
1741
1742 Point aTopLeft, aTmpPos;
1743
1744 int nOuterSpaceX = 0;
1745 if (!IsMenuBar())
1746 {
1748 aTopLeft.AdjustX(nOuterSpaceX );
1749 aTopLeft.AdjustY(ImplGetSVData()->maNWFData.mnMenuFormatBorderY );
1750 }
1751
1752 // for the computations, use size of the underlying window, not of RenderContext
1753 Size aOutSz(rSize);
1754
1755 size_t nCount = pItemList->size();
1756 if (bLayout)
1757 mpLayoutData->m_aVisibleItemBoundRects.clear();
1758
1759 // Paint title
1760 if (!pThisItemOnly && !IsMenuBar() && nTitleHeight > 0)
1761 ImplPaintMenuTitle(rRenderContext, tools::Rectangle(aTopLeft, aOutSz));
1762
1763 bool bHiddenItems = false; // are any items on the GUI hidden
1764
1765 for (size_t n = 0; n < nCount; n++)
1766 {
1767 MenuItemData* pData = pItemList->GetDataFromPos( n );
1768 if (ImplIsVisible(n) && (!pThisItemOnly || (pData == pThisItemOnly)))
1769 {
1770 if (pThisItemOnly)
1771 {
1772 if (IsMenuBar())
1773 {
1774 if (!ImplGetSVData()->maNWFData.mbRolloverMenubar)
1775 {
1776 if (bRollover)
1777 rRenderContext.SetTextColor(rSettings.GetMenuBarRolloverTextColor());
1778 else if (bHighlighted)
1779 rRenderContext.SetTextColor(rSettings.GetMenuBarHighlightTextColor());
1780 }
1781 else
1782 {
1783 if (bHighlighted)
1784 rRenderContext.SetTextColor(rSettings.GetMenuBarHighlightTextColor());
1785 else if (bRollover)
1786 rRenderContext.SetTextColor(rSettings.GetMenuBarRolloverTextColor());
1787 }
1788 if (!bRollover && !bHighlighted)
1789 rRenderContext.SetTextColor(rSettings.GetMenuBarTextColor());
1790 }
1791 else if (bHighlighted)
1792 rRenderContext.SetTextColor(rSettings.GetMenuHighlightTextColor());
1793 }
1794
1795 Point aPos(aTopLeft);
1796 aPos.AdjustY(nBorder );
1797 aPos.AdjustY(nStartY );
1798
1799 if (aPos.Y() >= 0)
1800 {
1801 tools::Long nTextOffsetY = (pData->aSz.Height() - nFontHeight) / 2;
1802 if (IsMenuBar())
1803 nTextOffsetY += (aOutSz.Height()-pData->aSz.Height()) / 2;
1807
1808 // submenus without items are not disabled when no items are
1809 // contained. The application itself should check for this!
1810 // Otherwise it could happen entries are disabled due to
1811 // asynchronous loading
1812 if (!pData->bEnabled || !pWindow->IsEnabled())
1813 {
1814 nTextStyle |= DrawTextFlags::Disable;
1815 nSymbolStyle |= DrawSymbolFlags::Disable;
1816 nImageStyle |= DrawImageFlags::Disable;
1817 }
1818
1819 // Separator
1820 if (!bLayout && !IsMenuBar() && (pData->eType == MenuItemType::SEPARATOR))
1821 {
1822 bool bNativeOk = false;
1824 {
1826 if (pData->bEnabled && pWindow->IsEnabled())
1828 if (bHighlighted)
1830 Size aSz(pData->aSz);
1831 aSz.setWidth( aOutSz.Width() - 2*nOuterSpaceX );
1832 tools::Rectangle aItemRect(aPos, aSz);
1833 MenupopupValue aVal(nTextPos - GUTTERBORDER, aItemRect);
1835 aItemRect, nState, aVal, OUString());
1836 }
1837 if (!bNativeOk)
1838 {
1839 aTmpPos.setY( aPos.Y() + ((pData->aSz.Height() - 2) / 2) );
1840 aTmpPos.setX( aPos.X() + 2 + nOuterSpaceX );
1841 rRenderContext.SetLineColor(rSettings.GetShadowColor());
1842 rRenderContext.DrawLine(aTmpPos, Point(aOutSz.Width() - 3 - 2 * nOuterSpaceX, aTmpPos.Y()));
1843 aTmpPos.AdjustY( 1 );
1844 rRenderContext.SetLineColor(rSettings.GetLightColor());
1845 rRenderContext.DrawLine(aTmpPos, Point(aOutSz.Width() - 3 - 2 * nOuterSpaceX, aTmpPos.Y()));
1846 rRenderContext.SetLineColor();
1847 }
1848 }
1849
1850 tools::Rectangle aOuterCheckRect(Point(aPos.X()+nImgOrChkPos, aPos.Y()),
1851 Size(pData->aSz.Height(), pData->aSz.Height()));
1852
1853 // CheckMark
1854 if (!bLayout && !IsMenuBar() && pData->HasCheck())
1855 {
1856 // draw selection transparent marker if checked
1857 // onto that either a checkmark or the item image
1858 // will be painted
1859 // however do not do this if native checks will be painted since
1860 // the selection color too often does not fit the theme's check and/or radio
1861
1862 if( (pData->eType != MenuItemType::IMAGE) && (pData->eType != MenuItemType::STRINGIMAGE))
1863 {
1868 {
1869 ControlPart nPart = ((pData->nBits & MenuItemBits::RADIOCHECK)
1872
1874
1875 if (pData->bChecked)
1877
1878 if (pData->bEnabled && pWindow->IsEnabled())
1880
1881 if (bHighlighted)
1883
1884 tools::Long nCtrlHeight = (pData->nBits & MenuItemBits::RADIOCHECK) ? nCheckHeight : nRadioHeight;
1885 aTmpPos.setX( aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - nCtrlHeight) / 2 );
1886 aTmpPos.setY( aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight) / 2 );
1887
1888 tools::Rectangle aCheckRect(aTmpPos, Size(nCtrlHeight, nCtrlHeight));
1889 Size aSz(pData->aSz);
1890 aSz.setWidth( aOutSz.Width() - 2 * nOuterSpaceX );
1891 tools::Rectangle aItemRect(aPos, aSz);
1892 MenupopupValue aVal(nTextPos - GUTTERBORDER, aItemRect);
1893 rRenderContext.DrawNativeControl(ControlType::MenuPopup, nPart, aCheckRect,
1894 nState, aVal, OUString());
1895 }
1896 else if (pData->bChecked) // by default do nothing for unchecked items
1897 {
1898 ImplPaintCheckBackground(rRenderContext, *pWindow, aOuterCheckRect, pThisItemOnly && bHighlighted);
1899
1901 Size aSymbolSize;
1902 if (pData->nBits & MenuItemBits::RADIOCHECK)
1903 {
1905 aSymbolSize = Size(nFontHeight / 2, nFontHeight / 2);
1906 }
1907 else
1908 {
1910 aSymbolSize = Size((nFontHeight * 25) / 40, nFontHeight / 2);
1911 }
1912 aTmpPos.setX( aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - aSymbolSize.Width()) / 2 );
1913 aTmpPos.setY( aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - aSymbolSize.Height()) / 2 );
1914 tools::Rectangle aRect(aTmpPos, aSymbolSize);
1915 aDecoView.DrawSymbol(aRect, eSymbol, rRenderContext.GetTextColor(), nSymbolStyle);
1916 }
1917 }
1918 }
1919
1920 // Image:
1921 if (!bLayout && !IsMenuBar() && ((pData->eType == MenuItemType::IMAGE) || (pData->eType == MenuItemType::STRINGIMAGE)))
1922 {
1923 // Don't render an image for a check thing
1924 if (pData->bChecked)
1925 ImplPaintCheckBackground(rRenderContext, *pWindow, aOuterCheckRect, pThisItemOnly && bHighlighted);
1926
1927 Image aImage = pData->aImage;
1928
1929 aTmpPos = aOuterCheckRect.TopLeft();
1930 aTmpPos.AdjustX((aOuterCheckRect.GetWidth() - aImage.GetSizePixel().Width()) / 2 );
1931 aTmpPos.AdjustY((aOuterCheckRect.GetHeight() - aImage.GetSizePixel().Height()) / 2 );
1932 rRenderContext.DrawImage(aTmpPos, aImage, nImageStyle);
1933 }
1934
1935 // Text:
1936 if ((pData->eType == MenuItemType::STRING ) || (pData->eType == MenuItemType::STRINGIMAGE))
1937 {
1938 aTmpPos.setX( aPos.X() + nTextPos );
1939 aTmpPos.setY( aPos.Y() );
1940 aTmpPos.AdjustY(nTextOffsetY );
1941 DrawTextFlags nStyle = nTextStyle | DrawTextFlags::Mnemonic;
1942
1943 if (pData->bIsTemporary)
1944 nStyle |= DrawTextFlags::Disable;
1945 std::vector< tools::Rectangle >* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : nullptr;
1946 OUString* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : nullptr;
1947 if (bLayout)
1948 {
1949 mpLayoutData->m_aLineIndices.push_back(mpLayoutData->m_aDisplayText.getLength());
1950 mpLayoutData->m_aLineItemIds.push_back(pData->nId);
1951 }
1952 // #i47946# with NWF painted menus the background is transparent
1953 // since DrawCtrlText can depend on the background (e.g. for
1954 // DrawTextFlags::Disable), temporarily set a background which
1955 // hopefully matches the NWF background since it is read
1956 // from the system style settings
1957 bool bSetTmpBackground = !rRenderContext.IsBackground()
1959 if (bSetTmpBackground)
1960 {
1961 Color aBg = IsMenuBar() ? rRenderContext.GetSettings().GetStyleSettings().GetMenuBarColor()
1962 : rRenderContext.GetSettings().GetStyleSettings().GetMenuColor();
1963 rRenderContext.SetBackground(Wallpaper(aBg));
1964 }
1965 // how much space is there for the text?
1966 tools::Long nMaxItemTextWidth = aOutSz.Width() - aTmpPos.X() - nExtra - nOuterSpaceX;
1967 if (!IsMenuBar() && pData->aAccelKey.GetCode() && !ImplAccelDisabled())
1968 {
1969 OUString aAccText = pData->aAccelKey.GetName();
1970 nMaxItemTextWidth -= rRenderContext.GetTextWidth(aAccText) + 3 * nExtra;
1971 }
1972 if (!IsMenuBar() && pData->pSubMenu)
1973 {
1974 nMaxItemTextWidth -= nFontHeight - nExtra;
1975 }
1976
1977 OUString aItemText(pData->aText);
1978 pData->bHiddenOnGUI = false;
1979
1980 if (IsMenuBar()) // In case of menubar if we are out of bounds we shouldn't paint the item
1981 {
1982 if (nMaxItemTextWidth < rRenderContext.GetTextWidth(aItemText))
1983 {
1984 aItemText = "";
1985 pData->bHiddenOnGUI = true;
1986 bHiddenItems = true;
1987 }
1988 }
1989 else
1990 {
1991 aItemText = getShortenedString(aItemText, rRenderContext, nMaxItemTextWidth);
1992 pData->bHiddenOnGUI = false;
1993 }
1994
1995 const SalLayoutGlyphs* pGlyphs = pData->GetTextGlyphs(&rRenderContext);
1996 if (aItemText != pData->aText)
1997 // Can't use pre-computed glyphs, item text was
1998 // changed.
1999 pGlyphs = nullptr;
2000 rRenderContext.DrawCtrlText(aTmpPos, aItemText, 0, aItemText.getLength(),
2001 nStyle, pVector, pDisplayText, pGlyphs);
2002 if (bSetTmpBackground)
2003 rRenderContext.SetBackground();
2004 }
2005
2006 // Accel
2007 if (!bLayout && !IsMenuBar() && pData->aAccelKey.GetCode() && !ImplAccelDisabled())
2008 {
2009 OUString aAccText = pData->aAccelKey.GetName();
2010 aTmpPos.setX( aOutSz.Width() - rRenderContext.GetTextWidth(aAccText) );
2011 aTmpPos.AdjustX( -(4 * nExtra) );
2012
2013 aTmpPos.AdjustX( -nOuterSpaceX );
2014 aTmpPos.setY( aPos.Y() );
2015 aTmpPos.AdjustY(nTextOffsetY );
2016 rRenderContext.DrawCtrlText(aTmpPos, aAccText, 0, aAccText.getLength(), nTextStyle);
2017 }
2018
2019 // SubMenu?
2020 if (!bLayout && !IsMenuBar() && pData->pSubMenu)
2021 {
2022 bool bNativeOk = false;
2024 {
2026 Size aTmpSz(0, 0);
2027 tools::Long aSpacing = 0;
2028
2029 if (!ImplGetNativeSubmenuArrowSize(rRenderContext, aTmpSz, aSpacing))
2030 {
2031 aTmpSz = Size(nFontHeight, nFontHeight);
2032 aSpacing = nOuterSpaceX;
2033 }
2034
2035 if (pData->bEnabled && pWindow->IsEnabled())
2037 if (bHighlighted)
2039
2040 aTmpPos.setX( aOutSz.Width() - aTmpSz.Width() - aSpacing - nOuterSpaceX );
2041 aTmpPos.setY( aPos.Y() + ( pData->aSz.Height() - aTmpSz.Height() ) / 2 );
2042 aTmpPos.AdjustY(nExtra / 2 );
2043
2044 tools::Rectangle aItemRect(aTmpPos, aTmpSz);
2045 MenupopupValue aVal(nTextPos - GUTTERBORDER, aItemRect);
2047 aItemRect, nState, aVal, OUString());
2048 }
2049 if (!bNativeOk)
2050 {
2051 aTmpPos.setX( aOutSz.Width() - nFontHeight + nExtra - nOuterSpaceX );
2052 aTmpPos.setY( aPos.Y() );
2053 aTmpPos.AdjustY(nExtra/2 );
2054 aTmpPos.AdjustY((pData->aSz.Height() / 2) - (nFontHeight / 4) );
2055 if (pData->nBits & MenuItemBits::POPUPSELECT)
2056 {
2057 rRenderContext.SetTextColor(rSettings.GetMenuTextColor());
2058 Point aTmpPos2(aPos);
2059 aTmpPos2.setX( aOutSz.Width() - nFontHeight - nFontHeight/4 );
2060 aDecoView.DrawFrame(tools::Rectangle(aTmpPos2, Size(nFontHeight + nFontHeight / 4,
2061 pData->aSz.Height())),
2063 }
2064 aDecoView.DrawSymbol(tools::Rectangle(aTmpPos, Size(nFontHeight / 2, nFontHeight / 2)),
2065 SymbolType::SPIN_RIGHT, rRenderContext.GetTextColor(), nSymbolStyle);
2066 }
2067 }
2068
2069 if (pThisItemOnly && bHighlighted)
2070 {
2071 // This restores the normal menu or menu bar text
2072 // color for when it is no longer highlighted.
2073 if (IsMenuBar())
2074 rRenderContext.SetTextColor(rSettings.GetMenuBarTextColor());
2075 else
2076 rRenderContext.SetTextColor(rSettings.GetMenuTextColor());
2077 }
2078 }
2079 if( bLayout )
2080 {
2081 if (!IsMenuBar())
2082 mpLayoutData->m_aVisibleItemBoundRects[ n ] = tools::Rectangle(aTopLeft, Size(aOutSz.Width(), pData->aSz.Height()));
2083 else
2084 mpLayoutData->m_aVisibleItemBoundRects[ n ] = tools::Rectangle(aTopLeft, pData->aSz);
2085 }
2086 }
2087
2088 if (!IsMenuBar())
2089 aTopLeft.AdjustY(pData->aSz.Height() );
2090 else
2091 aTopLeft.AdjustX(pData->aSz.Width() );
2092 }
2093
2094 // draw "more" (">>") indicator if some items have been hidden as they go out of visible area
2095 if (bHiddenItems)
2096 {
2097 sal_Int32 nSize = nFontHeight;
2098 tools::Rectangle aRectangle(Point(aOutSz.Width() - nSize, (aOutSz.Height() / 2) - (nSize / 2)), Size(nSize, nSize));
2099 lclDrawMoreIndicator(rRenderContext, aRectangle);
2100 }
2101}
2102
2104{
2105 Menu* pStart = this;
2106 while ( pStart && pStart->pStartedFrom && ( pStart->pStartedFrom != pStart ) )
2107 pStart = pStart->pStartedFrom;
2108 return pStart;
2109}
2110
2111void Menu::ImplCallHighlight(sal_uInt16 nItem)
2112{
2113 ImplMenuDelData aDelData( this );
2114
2115 nSelectedId = 0;
2116 sSelectedIdent.clear();
2117 MenuItemData* pData = pItemList->GetDataFromPos(nItem);
2118 if (pData)
2119 {
2120 nSelectedId = pData->nId;
2121 sSelectedIdent = pData->sIdent;
2122 }
2124
2125 if( !aDelData.isDeleted() )
2126 {
2127 nSelectedId = 0;
2128 sSelectedIdent.clear();
2129 }
2130}
2131
2132IMPL_LINK_NOARG(Menu, ImplCallSelect, void*, void)
2133{
2134 nEventId = nullptr;
2135 Select();
2136}
2137
2139{
2140 Menu* pSelMenu = nEventId ? this : nullptr;
2141
2142 for ( size_t n = GetItemList()->size(); n && !pSelMenu; )
2143 {
2145
2146 if ( pData->pSubMenu )
2147 pSelMenu = pData->pSubMenu->ImplFindSelectMenu();
2148 }
2149
2150 return pSelMenu;
2151}
2152
2153Menu* Menu::ImplFindMenu( sal_uInt16 nItemId )
2154{
2155 Menu* pSelMenu = nullptr;
2156
2157 for ( size_t n = GetItemList()->size(); n && !pSelMenu; )
2158 {
2160
2161 if( pData->nId == nItemId )
2162 pSelMenu = this;
2163 else if ( pData->pSubMenu )
2164 pSelMenu = pData->pSubMenu->ImplFindMenu( nItemId );
2165 }
2166
2167 return pSelMenu;
2168}
2169
2170void Menu::RemoveDisabledEntries( bool bRemoveEmptyPopups )
2171{
2172 for ( sal_uInt16 n = 0; n < GetItemCount(); n++ )
2173 {
2174 bool bRemove = false;
2175 MenuItemData* pItem = pItemList->GetDataFromPos( n );
2176 if ( pItem->eType == MenuItemType::SEPARATOR )
2177 {
2178 if ( !n || ( GetItemType( n-1 ) == MenuItemType::SEPARATOR ) )
2179 bRemove = true;
2180 }
2181 else
2182 bRemove = !pItem->bEnabled;
2183
2184 if ( pItem->pSubMenu )
2185 {
2187 if ( bRemoveEmptyPopups && !pItem->pSubMenu->GetItemCount() )
2188 bRemove = true;
2189 }
2190
2191 if ( bRemove )
2192 RemoveItem( n-- );
2193 }
2194
2195 if ( GetItemCount() )
2196 {
2197 sal_uInt16 nLast = GetItemCount() - 1;
2198 MenuItemData* pItem = pItemList->GetDataFromPos( nLast );
2199 if ( pItem->eType == MenuItemType::SEPARATOR )
2200 RemoveItem( nLast );
2201 }
2202 mpLayoutData.reset();
2203}
2204
2206{
2207 if ( ImplGetSalMenu() )
2209}
2210
2212{
2213}
2214
2216{
2217 mpLayoutData.reset();
2218}
2219
2221{
2222 if (!(pWindow && pWindow->IsReallyVisible()))
2223 return;
2224
2225 mpLayoutData.reset(new MenuLayoutData);
2226 if (IsMenuBar())
2227 {
2228 ImplPaint(*pWindow->GetOutDev(), pWindow->GetOutputSizePixel(), 0, 0, nullptr, false, true); // FIXME
2229 }
2230 else
2231 {
2232 MenuFloatingWindow* pFloat = static_cast<MenuFloatingWindow*>(pWindow.get());
2234 nullptr, false, true); //FIXME
2235 }
2236}
2237
2238tools::Rectangle Menu::GetCharacterBounds( sal_uInt16 nItemID, tools::Long nIndex ) const
2239{
2240 tools::Long nItemIndex = -1;
2241 if( ! mpLayoutData )
2243 if( mpLayoutData )
2244 {
2245 for( size_t i = 0; i < mpLayoutData->m_aLineItemIds.size(); i++ )
2246 {
2247 if( mpLayoutData->m_aLineItemIds[i] == nItemID )
2248 {
2249 nItemIndex = mpLayoutData->m_aLineIndices[i];
2250 break;
2251 }
2252 }
2253 }
2254 return (mpLayoutData && nItemIndex != -1) ? mpLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : tools::Rectangle();
2255}
2256
2257tools::Long Menu::GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const
2258{
2259 tools::Long nIndex = -1;
2260 rItemID = 0;
2261 if( ! mpLayoutData )
2263 if( mpLayoutData )
2264 {
2265 nIndex = mpLayoutData->GetIndexForPoint( rPoint );
2266 for( size_t i = 0; i < mpLayoutData->m_aLineIndices.size(); i++ )
2267 {
2268 if( mpLayoutData->m_aLineIndices[i] <= nIndex &&
2269 (i == mpLayoutData->m_aLineIndices.size()-1 || mpLayoutData->m_aLineIndices[i+1] > nIndex) )
2270 {
2271 // make index relative to item
2272 nIndex -= mpLayoutData->m_aLineIndices[i];
2273 rItemID = mpLayoutData->m_aLineItemIds[i];
2274 break;
2275 }
2276 }
2277 }
2278 return nIndex;
2279}
2280
2282{
2283 tools::Rectangle aRet;
2284
2285 if (!mpLayoutData )
2287 if (mpLayoutData)
2288 {
2289 std::map< sal_uInt16, tools::Rectangle >::const_iterator it = mpLayoutData->m_aVisibleItemBoundRects.find( nPos );
2290 if( it != mpLayoutData->m_aVisibleItemBoundRects.end() )
2291 aRet = it->second;
2292 }
2293 return aRet;
2294}
2295
2296void Menu::SetAccessibleName( sal_uInt16 nItemId, const OUString& rStr )
2297{
2298 size_t nPos;
2299 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
2300
2301 if (pData && !rStr.equals(pData->aAccessibleName))
2302 {
2303 pData->aAccessibleName = rStr;
2305 }
2306}
2307
2308OUString Menu::GetAccessibleName( sal_uInt16 nItemId ) const
2309{
2310 MenuItemData* pData = pItemList->GetData( nItemId );
2311
2312 if ( pData )
2313 return pData->aAccessibleName;
2314
2315 return OUString();
2316}
2317
2318void Menu::SetAccessibleDescription( sal_uInt16 nItemId, const OUString& rStr )
2319{
2320 MenuItemData* pData = pItemList->GetData( nItemId );
2321
2322 if ( pData )
2323 pData->aAccessibleDescription = rStr;
2324}
2325
2326OUString Menu::GetAccessibleDescription( sal_uInt16 nItemId ) const
2327{
2328 MenuItemData* pData = pItemList->GetData( nItemId );
2329
2330 if (pData && !pData->aAccessibleDescription.isEmpty())
2331 return pData->aAccessibleDescription;
2332
2333 return GetHelpText(nItemId);
2334}
2335
2337{
2338 Menu* pMenu = const_cast<Menu*>(this);
2339 if( pData && pMenu->ImplGetSalMenu() )
2340 {
2342 }
2343}
2344
2345bool Menu::IsHighlighted( sal_uInt16 nItemPos ) const
2346{
2347 bool bRet = false;
2348
2349 if( pWindow )
2350 {
2351 if (IsMenuBar())
2352 bRet = ( nItemPos == static_cast< MenuBarWindow * > (pWindow.get())->GetHighlightedItem() );
2353 else
2354 bRet = ( nItemPos == static_cast< MenuFloatingWindow * > (pWindow.get())->GetHighlightedItem() );
2355 }
2356
2357 return bRet;
2358}
2359
2360void Menu::HighlightItem( sal_uInt16 nItemPos )
2361{
2362 if ( !pWindow )
2363 return;
2364
2365 if (IsMenuBar())
2366 {
2367 MenuBarWindow* pMenuWin = static_cast< MenuBarWindow* >( pWindow.get() );
2368 pMenuWin->SetAutoPopup( false );
2369 pMenuWin->ChangeHighlightItem( nItemPos, false );
2370 }
2371 else
2372 {
2373 static_cast< MenuFloatingWindow* >( pWindow.get() )->ChangeHighlightItem( nItemPos, false );
2374 }
2375}
2376
2378{
2379 // so far just a dynamic_cast, hopefully to be turned into something saner
2380 // at some stage
2381 MenuBarWindow *pWin = dynamic_cast<MenuBarWindow*>(pWindow.get());
2382 //either there is no window (fdo#87663) or it is a MenuBarWindow
2383 assert(!pWindow || pWin);
2384 return pWin;
2385}
2386
2388 : mbCloseBtnVisible(false),
2389 mbFloatBtnVisible(false),
2390 mbHideBtnVisible(false),
2391 mbDisplayable(true)
2392{
2393 mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(true, this);
2394}
2395
2397 : mbCloseBtnVisible(false),
2398 mbFloatBtnVisible(false),
2399 mbHideBtnVisible(false),
2400 mbDisplayable(true)
2401{
2402 mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(true, this);
2403 *this = rMenu;
2404}
2405
2407{
2408 disposeOnce();
2409}
2410
2412{
2413 ImplDestroy( this, true );
2414 Menu::dispose();
2415}
2416
2418{
2419 MenuBarWindow* pMenuWin = getMenuBarWindow();
2420 if (!pMenuWin)
2421 return;
2422 pMenuWin->PopupClosed(pMenu);
2423}
2424
2426{
2427 pWindow->KeyInput(rEvent);
2428}
2429
2431{
2433}
2434
2435void MenuBar::ShowButtons( bool bClose, bool bFloat, bool bHide )
2436{
2437 if ((bClose != mbCloseBtnVisible) ||
2438 (bFloat != mbFloatBtnVisible) ||
2439 (bHide != mbHideBtnVisible))
2440 {
2441 mbCloseBtnVisible = bClose;
2442 mbFloatBtnVisible = bFloat;
2443 mbHideBtnVisible = bHide;
2444 MenuBarWindow* pMenuWin = getMenuBarWindow();
2445 if (pMenuWin)
2446 pMenuWin->ShowButtons(bClose, bFloat, bHide);
2447 }
2448}
2449
2451{
2452 MenuBarWindow* pMenuWin = getMenuBarWindow();
2453 if (pMenuWin)
2454 pMenuWin->LayoutChanged();
2455}
2456
2457void MenuBar::SetDisplayable( bool bDisplayable )
2458{
2459 if( bDisplayable != mbDisplayable )
2460 {
2461 if ( ImplGetSalMenu() )
2462 ImplGetSalMenu()->ShowMenuBar( bDisplayable );
2463
2464 mbDisplayable = bDisplayable;
2465 LayoutChanged();
2466 }
2467}
2468
2470{
2471 VclPtr<MenuBarWindow> pMenuBarWindow = dynamic_cast<MenuBarWindow*>(pWindow);
2472 if (!pMenuBarWindow)
2473 {
2474 pWindow = pMenuBarWindow = VclPtr<MenuBarWindow>::Create( pParent );
2475 }
2476
2477 pMenu->pStartedFrom = nullptr;
2478 pMenu->pWindow = pWindow;
2479 pMenuBarWindow->SetMenu(pMenu);
2480 tools::Long nHeight = pWindow ? pMenu->ImplCalcSize(pWindow).Height() : 0;
2481
2482 // depending on the native implementation or the displayable flag
2483 // the menubar windows is suppressed (ie, height=0)
2484 if (!pMenu->IsDisplayable() || (pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar()))
2485 {
2486 nHeight = 0;
2487 }
2488
2489 pMenuBarWindow->SetHeight(nHeight);
2490 return pWindow;
2491}
2492
2493void MenuBar::ImplDestroy( MenuBar* pMenu, bool bDelete )
2494{
2495 vcl::Window *pWindow = pMenu->ImplGetWindow();
2496 if (pWindow && bDelete)
2497 {
2498 MenuBarWindow* pMenuWin = pMenu->getMenuBarWindow();
2499 if (pMenuWin)
2500 pMenuWin->KillActivePopup();
2502 }
2503 pMenu->pWindow = nullptr;
2504 if (pMenu->mpSalMenu) {
2505 pMenu->mpSalMenu->ShowMenuBar(false);
2506 }
2507}
2508
2510{
2511 // No keyboard processing when our menubar is invisible
2512 if (!IsDisplayable())
2513 return false;
2514
2515 // No keyboard processing when system handles the menu.
2516 SalMenu *pNativeMenu = ImplGetSalMenu();
2517 if (pNativeMenu && pNativeMenu->VisibleMenuBar())
2518 {
2519 // Except when the event is the F6 cycle pane event and we can put our
2520 // focus into it (i.e. the gtk3 menubar case but not the mac/unity case
2521 // where it's not part of the application window)
2522 if (!TaskPaneList::IsCycleKey(rKEvent.GetKeyCode()))
2523 return false;
2524 if (!pNativeMenu->CanGetFocus())
2525 return false;
2526 }
2527
2528 bool bDone = false;
2529 // check for enabled, if this method is called from another window...
2530 vcl::Window* pWin = ImplGetWindow();
2531 if (pWin && pWin->IsEnabled() && pWin->IsInputEnabled() && !pWin->IsInModalMode())
2532 {
2533 MenuBarWindow* pMenuWin = getMenuBarWindow();
2534 bDone = pMenuWin && pMenuWin->HandleKeyEvent(rKEvent, false/*bFromMenu*/);
2535 }
2536 return bDone;
2537}
2538
2539void MenuBar::SelectItem(sal_uInt16 nId)
2540{
2541 if (!pWindow)
2542 return;
2543
2544 pWindow->GrabFocus();
2545 nId = GetItemPos( nId );
2546
2547 MenuBarWindow* pMenuWin = getMenuBarWindow();
2548 if (pMenuWin)
2549 {
2550 // #99705# popup the selected menu
2551 pMenuWin->SetAutoPopup( true );
2552 if (ITEMPOS_INVALID != pMenuWin->GetHighlightedItem())
2553 {
2554 pMenuWin->KillActivePopup();
2555 pMenuWin->ChangeHighlightItem( ITEMPOS_INVALID, false );
2556 }
2557 if (nId != ITEMPOS_INVALID)
2558 pMenuWin->ChangeHighlightItem( nId, false );
2559 }
2560}
2561
2562// handler for native menu selection and command events
2564{
2565 if( pMenu )
2566 {
2567 ImplMenuDelData aDelData( this );
2568
2569 pMenu->pStartedFrom = const_cast<Menu*>(this);
2570 pMenu->bInCallback = true;
2571 pMenu->Activate();
2572
2573 if( !aDelData.isDeleted() )
2574 pMenu->bInCallback = false;
2575 }
2576 return true;
2577}
2578
2580{
2581 if( pMenu )
2582 {
2583 ImplMenuDelData aDelData( this );
2584
2585 pMenu->pStartedFrom = const_cast<Menu*>(this);
2586 pMenu->bInCallback = true;
2587 pMenu->Deactivate();
2588 if( !aDelData.isDeleted() )
2589 pMenu->bInCallback = false;
2590 }
2591 return true;
2592}
2593
2594bool MenuBar::HandleMenuHighlightEvent( Menu *pMenu, sal_uInt16 nHighlightEventId ) const
2595{
2596 if( !pMenu )
2597 pMenu = const_cast<MenuBar*>(this)->ImplFindMenu(nHighlightEventId);
2598 if( pMenu )
2599 {
2600 ImplMenuDelData aDelData( pMenu );
2601
2604
2605 if( !aDelData.isDeleted() )
2606 {
2607 pMenu->mnHighlightedItemPos = pMenu->GetItemPos( nHighlightEventId );
2608 pMenu->nSelectedId = nHighlightEventId;
2609 pMenu->sSelectedIdent = pMenu->GetItemIdent( nHighlightEventId );
2610 pMenu->pStartedFrom = const_cast<MenuBar*>(this);
2611 pMenu->ImplCallHighlight( pMenu->mnHighlightedItemPos );
2612 }
2613 return true;
2614 }
2615 else
2616 return false;
2617}
2618
2619bool Menu::HandleMenuCommandEvent( Menu *pMenu, sal_uInt16 nCommandEventId ) const
2620{
2621 if( !pMenu )
2622 pMenu = const_cast<Menu*>(this)->ImplFindMenu(nCommandEventId);
2623 if( pMenu )
2624 {
2625 pMenu->nSelectedId = nCommandEventId;
2626 pMenu->sSelectedIdent = pMenu->GetItemIdent(nCommandEventId);
2627 pMenu->pStartedFrom = const_cast<Menu*>(this);
2628 pMenu->ImplSelect();
2629 return true;
2630 }
2631 else
2632 return false;
2633}
2634
2635sal_uInt16 MenuBar::AddMenuBarButton( const Image& i_rImage, const Link<MenuBarButtonCallbackArg&,bool>& i_rLink, const OUString& i_rToolTip )
2636{
2637 MenuBarWindow* pMenuWin = getMenuBarWindow();
2638 return pMenuWin ? pMenuWin->AddMenuBarButton(i_rImage, i_rLink, i_rToolTip) : 0;
2639}
2640
2642{
2643 MenuBarWindow* pMenuWin = getMenuBarWindow();
2644 if (!pMenuWin)
2645 return;
2646 pMenuWin->SetMenuBarButtonHighlightHdl(nId, rLink);
2647}
2648
2649void MenuBar::RemoveMenuBarButton( sal_uInt16 nId )
2650{
2651 MenuBarWindow* pMenuWin = getMenuBarWindow();
2652 if (!pMenuWin)
2653 return;
2654 pMenuWin->RemoveMenuBarButton(nId);
2655}
2656
2658{
2659 MenuBarWindow* pMenuWin = getMenuBarWindow();
2660 return pMenuWin ? pMenuWin->GetMenuBarButtonRectPixel(nId) : tools::Rectangle();
2661}
2662
2663bool MenuBar::HandleMenuButtonEvent( sal_uInt16 i_nButtonId )
2664{
2665 MenuBarWindow* pMenuWin = getMenuBarWindow();
2666 return pMenuWin && pMenuWin->HandleMenuButtonEvent(i_nButtonId);
2667}
2668
2670{
2671 MenuBar* pMenuBar = const_cast<MenuBar*>(this);
2672 const SalMenu *pNativeMenu = pMenuBar->ImplGetSalMenu();
2673 int nMenubarHeight;
2674 if (pNativeMenu)
2675 nMenubarHeight = pNativeMenu->GetMenuBarHeight();
2676 else
2677 {
2678 vcl::Window* pMenubarWin = GetWindow();
2679 nMenubarHeight = pMenubarWin ? pMenubarWin->GetOutputSizePixel().Height() : 0;
2680 }
2681 return nMenubarHeight;
2682}
2683
2684// bool PopupMenu::bAnyPopupInExecute = false;
2685
2687 return static_cast<MenuFloatingWindow *>(Menu::ImplGetWindow());
2688}
2689
2691{
2692 mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(false, this);
2693}
2694
2696{
2697 mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(false, this);
2698 *this = rMenu;
2699}
2700
2702{
2703 disposeOnce();
2704}
2705
2707{
2709 PopupMenu *pPopup = dynamic_cast<PopupMenu*>(pMenu);
2710 if (p && pPopup)
2711 p->KillActivePopup(pPopup);
2712}
2713
2714namespace vcl
2715{
2717 {
2718 return PopupMenu::GetActivePopupMenu() != nullptr;
2719 }
2720}
2721
2723{
2724 ImplSVData* pSVData = ImplGetSVData();
2725 return pSVData->maAppData.mpActivePopupMenu;
2726}
2727
2729{
2730 if ( ImplGetWindow() )
2732}
2733
2734void PopupMenu::SelectItem(sal_uInt16 nId)
2735{
2736 if ( !ImplGetWindow() )
2737 return;
2738
2739 if( nId != ITEMPOS_INVALID )
2740 {
2741 size_t nPos = 0;
2743 if (pData && pData->pSubMenu)
2745 else
2747 }
2748 else
2749 {
2751 pFloat->GrabFocus();
2752
2753 for( size_t nPos = 0; nPos < GetItemList()->size(); nPos++ )
2754 {
2756 if( pData->pSubMenu )
2757 {
2758 pFloat->KillActivePopup();
2759 }
2760 }
2761 pFloat->ChangeHighlightItem( ITEMPOS_INVALID, false );
2762 }
2763}
2764
2765void PopupMenu::SetSelectedEntry( sal_uInt16 nId )
2766{
2767 nSelectedId = nId;
2769}
2770
2771sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const Point& rPopupPos )
2772{
2773 return Execute( pExecWindow, tools::Rectangle( rPopupPos, rPopupPos ), PopupMenuFlags::ExecuteDown );
2774}
2775
2777{
2779 if ( nFlags & PopupMenuFlags::ExecuteDown )
2780 nPopupModeFlags = FloatWinPopupFlags::Down;
2781 else if ( nFlags & PopupMenuFlags::ExecuteUp )
2782 nPopupModeFlags = FloatWinPopupFlags::Up;
2783 else if ( nFlags & PopupMenuFlags::ExecuteRight )
2784 nPopupModeFlags = FloatWinPopupFlags::Right;
2785 else
2786 nPopupModeFlags = FloatWinPopupFlags::Down;
2787
2788 if (nFlags & PopupMenuFlags::NoMouseUpClose ) // allow popup menus to stay open on mouse button up
2789 nPopupModeFlags |= FloatWinPopupFlags::NoMouseUpClose; // useful if the menu was opened on mousebutton down (eg toolbox configuration)
2790
2791 return nPopupModeFlags;
2792}
2793
2794sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const tools::Rectangle& rRect, PopupMenuFlags nFlags )
2795{
2796 ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL window!", 0 );
2797 return ImplExecute( pExecWindow, rRect, lcl_TranslateFlags(nFlags), nullptr, false );
2798}
2799
2801{
2802 // is there still Select?
2803 Menu* pSelect = ImplFindSelectMenu();
2804 if (pSelect)
2805 {
2806 // Select should be called prior to leaving execute in a popup menu!
2808 pSelect->nEventId = nullptr;
2809 pSelect->Select();
2810 }
2811}
2812
2814 FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom,
2815 bool& bRealExecute, VclPtr<MenuFloatingWindow>& pWin)
2816{
2817 bRealExecute = false;
2818 const sal_uInt16 nItemCount = GetItemCount();
2819 if (!pSFrom && (vcl::IsInPopupMenuExecute() || !nItemCount))
2820 return false;
2821
2822 mpLayoutData.reset();
2823
2824 ImplSVData* pSVData = ImplGetSVData();
2825
2826 pStartedFrom = pSFrom;
2827 nSelectedId = 0;
2828 sSelectedIdent.clear();
2829 bCanceled = false;
2830
2831 VclPtr<vcl::Window> xFocusId;
2832 if ( !pStartedFrom )
2833 {
2834 pSVData->mpWinData->mbNoDeactivate = true;
2835 xFocusId = Window::SaveFocus();
2836 bRealExecute = true;
2837 }
2838 else
2839 {
2840 // assure that only one menu is open at a time
2841 if (pStartedFrom->IsMenuBar() && pSVData->mpWinData->mpFirstFloat)
2844 }
2845
2846 SAL_WARN_IF( ImplGetWindow(), "vcl", "Win?!" );
2847 rRect.SetPos(pParentWin->OutputToScreenPixel(rRect.TopLeft()));
2848
2850 if (bRealExecute)
2851 nPopupModeFlags |= FloatWinPopupFlags::NewLevel;
2852
2853 bInCallback = true; // set it here, if Activate overridden
2854 Activate();
2855 bInCallback = false;
2856
2857 if (pParentWin->isDisposed())
2858 return false;
2859
2860 if ( bCanceled || bKilled )
2861 return false;
2862
2863 if (!nItemCount)
2864 return false;
2865
2866 // The flag MenuFlags::HideDisabledEntries is inherited.
2867 if ( pSFrom )
2868 {
2871 else
2873 }
2874 else
2875 // #102790# context menus shall never show disabled entries
2877
2878 sal_uInt16 nVisibleEntries = ImplGetVisibleItemCount();
2879 if ( !nVisibleEntries )
2880 {
2881 OUString aTmpEntryText(VclResId(SV_RESID_STRING_NOSELECTIONPOSSIBLE));
2882
2883 MenuItemData* pData = NbcInsertItem(0xFFFF, MenuItemBits::NONE, aTmpEntryText, nullptr, 0xFFFF, {});
2884 size_t nPos = 0;
2885 pData = pItemList->GetData( pData->nId, nPos );
2886 assert(pData);
2887 if (pData)
2888 {
2889 pData->bIsTemporary = true;
2890 }
2892 }
2893
2895 if (comphelper::LibreOfficeKit::isActive() && get_id() == "editviewspellmenu")
2896 {
2897 VclPtr<vcl::Window> xNotifierParent = pParentWin->GetParentWithLOKNotifier();
2898 assert(xNotifierParent && xNotifierParent->GetLOKNotifier() && "editview menu without LOKNotifier");
2899 pWin->SetLOKNotifier(xNotifierParent->GetLOKNotifier());
2900 }
2901
2902 if( pSVData->maNWFData.mbFlatMenu )
2903 pWin->SetBorderStyle( WindowBorderStyle::NOBORDER );
2904 else
2905 pWin->SetBorderStyle( pWin->GetBorderStyle() | WindowBorderStyle::MENU );
2906 pWindow = pWin;
2907
2908 Size aSz = ImplCalcSize( pWin );
2909
2910 tools::Rectangle aDesktopRect(pWin->GetDesktopRectPixel());
2911 if( Application::GetScreenCount() > 1 )
2912 {
2914 if( ! pDeskW )
2915 pDeskW = pWindow;
2916 Point aDesktopTL(pDeskW->OutputToAbsoluteScreenPixel(rRect.TopLeft()));
2919 }
2920
2921 tools::Long nMaxHeight = aDesktopRect.GetHeight();
2922
2923 //rhbz#1021915. If a menu won't fit in the desired location the default
2924 //mode is to place it somewhere it will fit. e.g. above, left, right. For
2925 //some cases, e.g. menubars, it's desirable to limit the options to
2926 //above/below and force the menu to scroll if it won't fit
2927 if (nPopupModeFlags & FloatWinPopupFlags::NoHorzPlacement)
2928 {
2929 vcl::Window* pRef = pWin;
2930 if ( pRef->GetParent() )
2931 pRef = pRef->GetParent();
2932
2935
2936 tools::Long nHeightAbove = devRect.Top() - aDesktopRect.Top();
2937 tools::Long nHeightBelow = aDesktopRect.Bottom() - devRect.Bottom();
2938 nMaxHeight = std::min(nMaxHeight, std::max(nHeightAbove, nHeightBelow));
2939 }
2940
2941 // In certain cases this might be misdetected with a height of 0, leading to menus not being displayed.
2942 // So assume that the available screen size matches at least the system requirements
2943 SAL_WARN_IF(nMaxHeight < 768, "vcl",
2944 "Available height misdetected as " << nMaxHeight
2945 << "px. Setting to 768px instead.");
2946 nMaxHeight = std::max(nMaxHeight, tools::Long(768));
2947
2949 nMaxHeight -= pParentWin->GetSizePixel().Height();
2950 sal_Int32 nLeft, nTop, nRight, nBottom;
2951 pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
2952 nMaxHeight -= nTop+nBottom;
2953 if ( aSz.Height() > nMaxHeight )
2954 {
2955 pWin->EnableScrollMenu( true );
2956 sal_uInt16 nStart = ImplGetFirstVisible();
2957 sal_uInt16 nEntries = ImplCalcVisEntries( nMaxHeight, nStart );
2958 aSz.setHeight( ImplCalcHeight( nEntries ) );
2959 }
2960
2961 pWin->SetFocusId( xFocusId );
2962 pWin->SetOutputSizePixel( aSz );
2963 return true;
2964}
2965
2966bool PopupMenu::Run(const VclPtr<MenuFloatingWindow>& pWin, const bool bRealExecute, const bool bPreSelectFirst,
2967 const FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect)
2968{
2969 SalMenu* pMenu = ImplGetSalMenu();
2970 if (pMenu && bRealExecute && pMenu->ShowNativePopupMenu(pWin, rRect, nPopupModeFlags))
2971 return true;
2972
2973 pWin->StartPopupMode(rRect, nPopupModeFlags);
2974 if (pSFrom)
2975 {
2976 sal_uInt16 aPos;
2977 if (pSFrom->IsMenuBar())
2978 aPos = static_cast<MenuBarWindow *>(pSFrom->pWindow.get())->GetHighlightedItem();
2979 else
2980 aPos = static_cast<MenuFloatingWindow *>(pSFrom->pWindow.get())->GetHighlightedItem();
2981
2982 pWin->SetPosInParent(aPos); // store position to be sent in SUBMENUDEACTIVATE
2984 }
2985
2986 if ( bPreSelectFirst )
2987 {
2988 for (size_t n = 0; n < static_cast<size_t>(GetItemCount()); n++)
2989 {
2990 MenuItemData* pData = pItemList->GetDataFromPos( n );
2991 if ( ( pData->bEnabled
2993 )
2994 && ( pData->eType != MenuItemType::SEPARATOR )
2995 && ImplIsVisible( n )
2996 && ImplIsSelectable( n )
2997 )
2998 {
2999 pWin->ChangeHighlightItem(n, false);
3000 break;
3001 }
3002 }
3003 }
3004
3005 if (bRealExecute)
3006 pWin->Execute();
3007
3008 return false;
3009}
3010
3011void PopupMenu::FinishRun(const VclPtr<MenuFloatingWindow>& pWin, const VclPtr<vcl::Window>& pParentWin, const bool bRealExecute, const bool bIsNativeMenu)
3012{
3013 if (!bRealExecute || pWin->isDisposed())
3014 return;
3015
3016 if (!bIsNativeMenu)
3017 {
3018 VclPtr<vcl::Window> xFocusId = pWin->GetFocusId();
3019 assert(xFocusId == nullptr && "Focus should already be restored by MenuFloatingWindow::End");
3020 pWin->ImplEndPopupMode(FloatWinPopupEndFlags::NONE, xFocusId);
3021
3022 if (nSelectedId) // then clean up .. ( otherwise done by TH )
3023 {
3024 PopupMenu* pSub = pWin->GetActivePopup();
3025 while ( pSub )
3026 {
3028 pSub = pSub->ImplGetFloatingWindow()->GetActivePopup();
3029 }
3030 }
3031 }
3032 else
3033 pWin->StopExecute();
3034
3035 pWin->doShutdown();
3037 ImplClosePopupToolBox(pParentWin);
3039}
3040
3041sal_uInt16 PopupMenu::ImplExecute(const VclPtr<vcl::Window>& pParentWin, const tools::Rectangle& rRect,
3042 FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst)
3043{
3044 // tdf#126054 hold this until after function completes
3045 VclPtr<PopupMenu> xThis(this);
3046 bool bRealExecute = false;
3047 tools::Rectangle aRect(rRect);
3049 if (!PrepareRun(pParentWin, aRect, nPopupModeFlags, pSFrom, bRealExecute, pWin))
3050 return 0;
3051 const bool bNative = Run(pWin, bRealExecute, bPreSelectFirst, nPopupModeFlags, pSFrom, aRect);
3052 FinishRun(pWin, pParentWin, bRealExecute, bNative);
3053 return nSelectedId;
3054}
3055
3056sal_uInt16 PopupMenu::ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible ) const
3057{
3058 nMaxHeight -= 2 * ImplGetFloatingWindow()->GetScrollerHeight();
3059
3060 tools::Long nHeight = 0;
3061 size_t nEntries = pItemList->size();
3062 sal_uInt16 nVisEntries = 0;
3063
3064 if ( pLastVisible )
3065 *pLastVisible = 0;
3066
3067 for ( size_t n = nStartEntry; n < nEntries; n++ )
3068 {
3069 if ( ImplIsVisible( n ) )
3070 {
3071 MenuItemData* pData = pItemList->GetDataFromPos( n );
3072 nHeight += pData->aSz.Height();
3073 if ( nHeight > nMaxHeight )
3074 break;
3075
3076 if ( pLastVisible )
3077 *pLastVisible = n;
3078 nVisEntries++;
3079 }
3080 }
3081 return nVisEntries;
3082}
3083
3084tools::Long PopupMenu::ImplCalcHeight( sal_uInt16 nEntries ) const
3085{
3086 tools::Long nHeight = 0;
3087
3088 sal_uInt16 nFound = 0;
3089 for ( size_t n = 0; ( nFound < nEntries ) && ( n < pItemList->size() ); n++ )
3090 {
3091 if ( ImplIsVisible( static_cast<sal_uInt16>(n) ) )
3092 {
3093 MenuItemData* pData = pItemList->GetDataFromPos( n );
3094 nHeight += pData->aSz.Height();
3095 nFound++;
3096 }
3097 }
3098
3099 nHeight += 2*ImplGetFloatingWindow()->GetScrollerHeight();
3100
3101 return nHeight;
3102}
3103
3104css::uno::Reference<css::awt::XPopupMenu> PopupMenu::CreateMenuInterface()
3105{
3107 if ( pWrapper )
3108 return pWrapper->CreateMenuInterface(this);
3109 return nullptr;
3110}
3111
3113: mpNext( nullptr )
3114, mpMenu( nullptr )
3115{
3116 if( pMenu )
3117 const_cast< Menu* >( pMenu )->ImplAddDel( *this );
3118}
3119
3121{
3122 if( mpMenu )
3123 const_cast< Menu* >( mpMenu.get() )->ImplRemoveDel( *this );
3124}
3125
3126/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
DrawImageFlags
DrawTextFlags
AnyEventRef aEvent
EdgeEntry * mpNext
const StyleSettings & GetStyleSettings() const
static void ImplCallEventListeners(VclSimpleEvent &rEvent)
Send event to all VCL application event listeners.
Definition: svapp.cxx:692
static SAL_DLLPRIVATE unsigned int GetBestScreen(const tools::Rectangle &)
Get the "best" screen.
Definition: svapp.cxx:1280
static unsigned int GetScreenCount()
Get the number of screens available for the display.
Definition: svapp.cxx:1219
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:638
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
Post a user event to the default window.
Definition: svapp.cxx:999
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
Remove user event based on event ID.
Definition: svapp.cxx:1023
static Help * GetHelp()
Gets the application's help.
Definition: svapp.cxx:1352
static tools::Rectangle GetScreenPosSizePixel(unsigned int nScreen)
Get a screen's rectangular area.
Definition: svapp.cxx:1254
bool IsDark() const
void DrawSymbol(const tools::Rectangle &rRect, SymbolType eType, const Color &rColor, DrawSymbolFlags nStyle=DrawSymbolFlags::NONE)
Definition: decoview.cxx:768
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:811
SystemWindow * GetFloatingWindow(const vcl::Window *pWin)
Definition: dockmgr.cxx:371
void EndPopupMode(FloatWinPopupEndFlags nFlags=FloatWinPopupEndFlags::NONE)
Definition: floatwin.cxx:964
Definition: help.hxx:61
virtual OUString GetHelpText(const OUString &aHelpURL, const weld::Widget *pWidget)
Definition: help.cxx:72
Definition: image.hxx:40
Size GetSizePixel() const
Definition: Image.cxx:88
void setTristateVal(ButtonValue nTristate)
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
Class that implements the actual window of the menu bar.
void ChangeHighlightItem(sal_uInt16 n, bool bSelectPopupEntry, bool bAllowRestoreFocus=true, bool bDefaultToDocument=true)
void RemoveMenuBarButton(sal_uInt16 nId)
void PopupClosed(Menu const *pMenu)
sal_uInt16 GetHighlightedItem() const
bool HandleMenuButtonEvent(sal_uInt16 i_nButtonId)
sal_uInt16 AddMenuBarButton(const Image &, const Link< MenuBarButtonCallbackArg &, bool > &, const OUString &)
Add an arbitrary button to the menubar that will appear next to the close button.
void ShowButtons(bool bClose, bool bFloat, bool bHide)
void SetMenuBarButtonHighlightHdl(sal_uInt16 nId, const Link< MenuBarButtonCallbackArg &, bool > &)
tools::Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId)
void KillActivePopup()
bool HandleKeyEvent(const KeyEvent &rKEvent, bool bFromMenu=true)
void SetAutoPopup(bool bAuto)
bool mbDisplayable
Definition: menu.hxx:418
virtual ~MenuBar() override
Definition: menu.cxx:2406
sal_uInt16 AddMenuBarButton(const Image &, const Link< MenuBarButtonCallbackArg &, bool > &, const OUString &)
Definition: menu.cxx:2635
void LayoutChanged()
Definition: menu.cxx:2450
void ShowButtons(bool bClose, bool bFloat, bool bHide)
Definition: menu.cxx:2435
virtual void ClosePopup(Menu *pMenu) override
Close the 'pStartedFrom' menu window.
Definition: menu.cxx:2417
bool HandleMenuButtonEvent(sal_uInt16 nEventId)
Definition: menu.cxx:2663
SAL_DLLPRIVATE bool ImplHandleKeyEvent(const KeyEvent &rKEvent)
Definition: menu.cxx:2509
tools::Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId)
Definition: menu.cxx:2657
int GetMenuBarHeight() const
Definition: menu.cxx:2669
bool mbFloatBtnVisible
Definition: menu.hxx:416
bool mbHideBtnVisible
Definition: menu.hxx:417
void SetDisplayable(bool bDisplayable)
Definition: menu.cxx:2457
MenuBarWindow * getMenuBarWindow()
Return the MenuBarWindow.
Definition: menu.cxx:2377
MenuBar()
Definition: menu.cxx:2387
virtual void MenuBarKeyInput(const KeyEvent &rEvent) override
Forward the KeyInput call to the MenuBar.
Definition: menu.cxx:2425
bool IsDisplayable() const
Definition: menu.hxx:467
void SetMenuBarButtonHighlightHdl(sal_uInt16 nId, const Link< MenuBarButtonCallbackArg &, bool > &)
Definition: menu.cxx:2641
virtual void dispose() override
Definition: menu.cxx:2411
virtual void SelectItem(sal_uInt16 nId) override
Definition: menu.cxx:2539
static SAL_DLLPRIVATE VclPtr< vcl::Window > ImplCreate(vcl::Window *pParent, vcl::Window *pWindow, MenuBar *pMenu)
Definition: menu.cxx:2469
bool HandleMenuHighlightEvent(Menu *pMenu, sal_uInt16 nEventId) const
Definition: menu.cxx:2594
void ShowCloseButton(bool bShow)
Definition: menu.cxx:2430
bool mbCloseBtnVisible
Definition: menu.hxx:415
static SAL_DLLPRIVATE void ImplDestroy(MenuBar *pMenu, bool bDelete)
Definition: menu.cxx:2493
void RemoveMenuBarButton(sal_uInt16 nId)
Definition: menu.cxx:2649
Class that implements the actual window of the floating menu.
PopupMenu * GetActivePopup() const
sal_uInt16 GetScrollerHeight() const
void ChangeHighlightItem(sal_uInt16 n, bool bStartPopupTimer)
void KillActivePopup(PopupMenu *pThisOnly=nullptr)
tools::Long ImplGetStartY() const
Get a negative pixel offset for an offset menu.
size_t size() const
MenuItemData * GetData(sal_uInt16 nSVId, size_t &rPos) const
MenuItemData * GetDataFromPos(size_t nPos) const
Definition: menu.hxx:116
bool IsHighlighted(sal_uInt16 nItemPos) const
Definition: menu.cxx:2345
SAL_DLLPRIVATE Menu * ImplFindSelectMenu()
Definition: menu.cxx:2138
Menu & operator=(const Menu &rMenu)
Definition: menu.cxx:1173
SAL_DLLPRIVATE void ImplCallEventListeners(VclEventId nEvent, sal_uInt16 nPos)
Definition: menu.cxx:383
bool IsItemChecked(sal_uInt16 nItemId) const
Definition: menu.cxx:908
void SetAccessible(const css::uno::Reference< css::accessibility::XAccessible > &rxAccessible)
Definition: menu.cxx:1339
void SetItemImage(sal_uInt16 nItemId, const Image &rImage)
Definition: menu.cxx:1028
virtual void MenuBarKeyInput(const KeyEvent &rEvent)
Forward the KeyInput call to the MenuBar.
Definition: menu.cxx:2211
bool bKilled
Killed.
Definition: menu.hxx:153
SAL_DLLPRIVATE SalMenu * ImplGetSalMenu()
Definition: menu.hxx:184
void Activate()
Definition: menu.cxx:256
void ShowItem(sal_uInt16 nItemId, bool bVisible=true)
Definition: menu.cxx:964
css::uno::Reference< css::accessibility::XAccessible > mxAccessible
Definition: menu.hxx:155
const OUString & get_id() const
Get the ID of the window.
Definition: menu.hxx:403
sal_uInt16 nImgOrChkPos
Definition: menu.hxx:148
SAL_DLLPRIVATE OUString ImplGetHelpText(sal_uInt16 nItemId) const
Definition: menu.cxx:1099
bool HandleMenuActivateEvent(Menu *pMenu) const
Definition: menu.cxx:2563
Link< Menu *, bool > aActivateHdl
Definition: menu.hxx:130
void AddEventListener(const Link< VclMenuEvent &, void > &rEventListener)
Definition: menu.cxx:407
std::unique_ptr< SalMenu > mpSalMenu
Definition: menu.hxx:157
void InsertSeparator(const OUString &rIdent={}, sal_uInt16 nPos=MENU_APPEND)
Definition: menu.cxx:472
void SetItemText(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:986
OUString GetItemText(sal_uInt16 nItemId) const
Definition: menu.cxx:1017
SAL_DLLPRIVATE sal_uInt16 ImplGetFirstVisible() const
Definition: menu.cxx:611
sal_uInt16 nTextPos
Definition: menu.hxx:149
virtual bool IsMenuBar() const =0
MenuItemBits GetItemBits(sal_uInt16 nItemId) const
Definition: menu.cxx:711
MenuItemType GetItemType(sal_uInt16 nPos) const
Definition: menu.cxx:673
SAL_DLLPRIVATE Menu * ImplFindMenu(sal_uInt16 nId)
Definition: menu.cxx:2153
SAL_DLLPRIVATE bool ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const
Definition: menu.cxx:1197
css::uno::Reference< css::accessibility::XAccessible > GetAccessible()
Definition: menu.cxx:1307
void HighlightItem(sal_uInt16 nItemPos)
Definition: menu.cxx:2360
void Select()
Definition: menu.cxx:351
VclPtr< Menu > pStartedFrom
Definition: menu.hxx:127
SAL_DLLPRIVATE void ImplAddDel(ImplMenuDelData &rDel)
Definition: menu.cxx:1401
bool HandleMenuDeActivateEvent(Menu *pMenu) const
Definition: menu.cxx:2579
OUString GetItemCommand(sal_uInt16 nItemId) const
Definition: menu.cxx:1063
sal_uInt16 GetCurItemId() const
Definition: menu.hxx:262
void SetHelpId(sal_uInt16 nItemId, const OUString &rHelpId)
Definition: menu.cxx:1148
SAL_DLLPRIVATE void ImplPaintMenuTitle(vcl::RenderContext &, const tools::Rectangle &rRect) const
Definition: menu.cxx:1693
OUString GetAccessibleName(sal_uInt16 nItemId) const
Definition: menu.cxx:2308
OUString sSelectedIdent
Definition: menu.hxx:145
OUString aTitleText
Definition: menu.hxx:138
bool bCanceled
Terminated during a callback.
Definition: menu.hxx:151
tools::Long GetIndexForPoint(const Point &rPoint, sal_uInt16 &rItemID) const
Definition: menu.cxx:2257
SAL_DLLPRIVATE Menu * ImplGetStartMenu()
Definition: menu.cxx:2103
void SetAccessibleName(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:2296
bool IsItemPosVisible(sal_uInt16 nItemPos) const
Definition: menu.cxx:1285
OUString GetAccessibleDescription(sal_uInt16 nItemId) const
Definition: menu.cxx:2326
ImplSVEvent * nEventId
Definition: menu.hxx:141
KeyEvent GetActivationKey(sal_uInt16 nItemId) const
Definition: menu.cxx:813
SAL_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const
Definition: menu.cxx:600
void Clear()
Definition: menu.cxx:571
void RemoveEventListener(const Link< VclMenuEvent &, void > &rEventListener)
Definition: menu.cxx:412
vcl::KeyCode GetAccelKey(sal_uInt16 nItemId) const
Definition: menu.cxx:803
void RemoveDisabledEntries(bool bRemoveEmptyPopups=false)
Definition: menu.cxx:2170
SAL_DLLPRIVATE void ImplFillLayoutData() const
Definition: menu.cxx:2220
SAL_DLLPRIVATE void ImplKillLayoutData() const
Definition: menu.cxx:2215
SAL_DLLPRIVATE Size ImplCalcSize(vcl::Window *pWin)
Definition: menu.cxx:1431
void CheckItem(sal_uInt16 nItemId, bool bCheck=true)
Definition: menu.cxx:838
static SAL_DLLPRIVATE bool ImplGetNativeSubmenuArrowSize(vcl::RenderContext const &rRenderContext, Size &rArrowSize, tools::Long &rArrowSpacing)
Definition: menu.cxx:1380
SAL_DLLPRIVATE Size ImplGetNativeCheckAndRadioSize(vcl::RenderContext const &rRenderContext, tools::Long &rCheckHeight, tools::Long &rRadioHeight) const
Definition: menu.cxx:1344
void UpdateNativeMenu()
Definition: menu.cxx:2205
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: menu.cxx:641
vcl::Window * GetWindow() const
Definition: menu.hxx:377
void SetAccessibleDescription(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:2318
void SetUserValue(sal_uInt16 nItemId, void *nUserValue, MenuUserDataReleaseFunction aFunc=nullptr)
Definition: menu.cxx:720
void SetAccelKey(sal_uInt16 nItemId, const vcl::KeyCode &rKeyCode)
Definition: menu.cxx:785
SAL_DLLPRIVATE sal_uInt16 ImplGetNextVisible(sal_uInt16 nPos) const
Definition: menu.cxx:631
tools::Rectangle GetCharacterBounds(sal_uInt16 nItemId, tools::Long nIndex) const
Definition: menu.cxx:2238
SAL_DLLPRIVATE void ImplPaint(vcl::RenderContext &rRenderContext, Size const &rSize, sal_uInt16 nBorder, tools::Long nOffY=0, MenuItemData const *pThisDataOnly=nullptr, bool bHighlighted=false, bool bLayout=false, bool bRollover=false) const
Definition: menu.cxx:1728
SAL_DLLPRIVATE bool ImplIsSelectable(sal_uInt16 nPos) const
Definition: menu.cxx:1295
SAL_DLLPRIVATE MenuItemData * NbcInsertItem(sal_uInt16 nId, MenuItemBits nBits, const OUString &rStr, Menu *pMenu, size_t nPos, const OUString &rIdent)
Definition: menu.cxx:417
bool IsMenuVisible() const
Definition: menu.cxx:1290
void Deactivate()
Definition: menu.cxx:287
Link< Menu *, bool > aDeactivateHdl
Definition: menu.hxx:131
Image GetItemImage(sal_uInt16 nItemId) const
Definition: menu.cxx:1044
void SetTipHelpText(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1130
void SetItemCommand(sal_uInt16 nItemId, const OUString &rCommand)
Definition: menu.cxx:1054
bool HandleMenuCommandEvent(Menu *pMenu, sal_uInt16 nEventId) const
Definition: menu.cxx:2619
PopupMenu * GetPopupMenu(sal_uInt16 nItemId) const
Definition: menu.cxx:775
bool HasValidEntries(bool bCheckPopups) const
Definition: menu.cxx:582
tools::Rectangle GetBoundingRectangle(sal_uInt16 nItemPos) const
Definition: menu.cxx:2281
void GetSystemMenuData(SystemMenuData *pData) const
Definition: menu.cxx:2336
bool IsItemEnabled(sal_uInt16 nItemId) const
Definition: menu.cxx:953
SAL_DLLPRIVATE sal_uInt16 ImplGetPrevVisible(sal_uInt16 nPos) const
Definition: menu.cxx:621
OUString GetItemIdent(sal_uInt16 nItemId) const
Definition: menu.cxx:683
SAL_DLLPRIVATE bool ImplIsVisible(sal_uInt16 nPos) const
Definition: menu.cxx:1211
VclPtr< vcl::Window > pWindow
Definition: menu.hxx:128
virtual ~Menu() override
Definition: menu.cxx:176
void EnableItem(sal_uInt16 nItemId, bool bEnable=true)
Definition: menu.cxx:919
SAL_DLLPRIVATE void ImplCallHighlight(sal_uInt16 nHighlightItem)
Definition: menu.cxx:2111
MenuFlags nMenuFlags
Definition: menu.hxx:143
sal_uInt16 nTitleHeight
Definition: menu.hxx:139
SAL_DLLPRIVATE void ImplRemoveDel(ImplMenuDelData &rDel)
Definition: menu.cxx:1412
void RemoveItem(sal_uInt16 nPos)
Definition: menu.cxx:496
void SetPopupMenu(sal_uInt16 nItemId, PopupMenu *pMenu)
Definition: menu.cxx:738
Menu()
The Menu constructor is protected.
Definition: menu.cxx:158
OUString GetHelpId() const
Definition: menu.hxx:322
void * GetUserValue(sal_uInt16 nItemId) const
Definition: menu.cxx:732
void SetItemBits(sal_uInt16 nItemId, MenuItemBits nBits)
Definition: menu.cxx:689
sal_uInt16 nSelectedId
Definition: menu.hxx:144
void SetHelpCommand(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1073
void SetHelpText(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1091
void CreateAutoMnemonics()
Definition: menu.cxx:238
bool bInCallback
In Activate/Deactivate.
Definition: menu.hxx:152
SAL_DLLPRIVATE void ImplSelect()
Definition: menu.cxx:330
ImplMenuDelData * mpFirstDel
Definition: menu.hxx:125
void InsertItem(sal_uInt16 nItemId, const OUString &rStr, MenuItemBits nItemBits=MenuItemBits::NONE, const OUString &rIdent={}, sal_uInt16 nPos=MENU_APPEND)
Definition: menu.cxx:432
std::unique_ptr< vcl::MenuLayoutData > mpLayoutData
Definition: menu.hxx:156
Link< Menu *, bool > aSelectHdl
Definition: menu.hxx:132
OUString GetHelpText(sal_uInt16 nItemId) const
Definition: menu.cxx:1125
MenuItemList * GetItemList() const
Definition: menu.hxx:350
OUString GetTipHelpText(sal_uInt16 nItemId) const
Definition: menu.cxx:1138
OUString GetHelpCommand(sal_uInt16 nItemId) const
Definition: menu.cxx:1081
sal_uInt16 GetItemPos(sal_uInt16 nItemId) const
Definition: menu.cxx:662
sal_uInt16 GetItemCount() const
Definition: menu.cxx:577
SAL_DLLPRIVATE vcl::Window * ImplGetWindow() const
Definition: menu.hxx:211
std::unique_ptr< MenuItemList > pItemList
Definition: menu.hxx:126
sal_uInt16 mnHighlightedItemPos
Definition: menu.hxx:142
virtual void dispose() override
Definition: menu.cxx:181
std::list< Link< VclMenuEvent &, void > > maEventListeners
Definition: menu.hxx:134
void RegisterMnemonic(const OUString &rKey)
OUString CreateMnemonic(const OUString &rKey)
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:170
tools::Long GetCtrlTextWidth(const OUString &rStr, const SalLayoutGlyphs *pLayoutCache=nullptr) const
Definition: text.cxx:2290
void DrawCtrlText(const Point &rPos, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, DrawTextFlags nStyle=DrawTextFlags::Mnemonic, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr)
Definition: text.cxx:2149
const vcl::Font & GetFont() const
Definition: outdev.hxx:529
float GetDPIScaleFactor() const
Definition: outdev.hxx:396
void SetFont(const vcl::Font &rNewFont)
Definition: outdev/font.cxx:56
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:50
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:161
const Wallpaper & GetBackground() const
Definition: outdev.hxx:523
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, KernArraySpan aDXArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}, const SalLayoutGlyphs *pGlyphs=nullptr) const
Return the exact bounding rectangle of rStr.
Definition: text.cxx:2307
void SetLineColor()
Definition: line.cxx:37
OUString GetEllipsisString(const OUString &rStr, tools::Long nMaxWidth, DrawTextFlags nStyle=DrawTextFlags::EndEllipsis) const
Definition: text.cxx:2017
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
Width of the text.
Definition: text.cxx:886
void SetTextColor(const Color &rColor)
Definition: text.cxx:716
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void SetFillColor()
Definition: fill.cxx:29
const Color & GetTextColor() const
Definition: outdev.hxx:1003
bool IsBackground() const
Definition: outdev.hxx:526
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:32
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: text.cxx:897
void SetBackground()
Definition: background.cxx:27
void Pop()
Definition: stack.cxx:91
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion) const
Query the native control's actual drawing region (including adornment)
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const Color &rBackgroundColor=COL_AUTO)
Request rendering of a particular control and/or part.
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
Definition: text.cxx:797
const AllSettings & GetSettings() const
Definition: outdev.hxx:288
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
SAL_DLLPRIVATE sal_uInt16 ImplExecute(const VclPtr< vcl::Window > &pParentWin, const tools::Rectangle &rRect, FloatWinPopupFlags nPopupModeFlags, Menu *pSFrom, bool bPreSelectFirst)
Definition: menu.cxx:3041
void SetSelectedEntry(sal_uInt16 nId)
Definition: menu.cxx:2765
virtual void SelectItem(sal_uInt16 nId) override
Definition: menu.cxx:2734
virtual ~PopupMenu() override
Definition: menu.cxx:2701
sal_uInt16 Execute(vcl::Window *pWindow, const Point &rPopupPos)
Definition: menu.cxx:2771
css::uno::Reference< css::awt::XPopupMenu > CreateMenuInterface()
Definition: menu.cxx:3104
SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries(tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16 *pLastVisible=nullptr) const
Definition: menu.cxx:3056
static PopupMenu * GetActivePopupMenu()
Definition: menu.cxx:2722
PopupMenu()
Definition: menu.cxx:2690
virtual void ClosePopup(Menu *pMenu) override
Close the 'pStartedFrom' menu window.
Definition: menu.cxx:2706
void EndExecute()
Definition: menu.cxx:2728
SAL_DLLPRIVATE void FinishRun(const VclPtr< MenuFloatingWindow > &, const VclPtr< vcl::Window > &pParentWin, bool bRealExecute, bool bIsNativeMenu)
Definition: menu.cxx:3011
SAL_DLLPRIVATE void ImplFlushPendingSelect()
Definition: menu.cxx:2800
SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const
Definition: menu.cxx:2686
SAL_DLLPRIVATE bool Run(const VclPtr< MenuFloatingWindow > &, bool bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu *pSFrom, const tools::Rectangle &rRect)
Definition: menu.cxx:2966
SAL_DLLPRIVATE tools::Long ImplCalcHeight(sal_uInt16 nEntries) const
Definition: menu.cxx:3084
SAL_DLLPRIVATE bool PrepareRun(const VclPtr< vcl::Window > &pParentWin, tools::Rectangle &rRect, FloatWinPopupFlags &nPopupModeFlags, Menu *pSFrom, bool &bRealExecute, VclPtr< MenuFloatingWindow > &)
Definition: menu.cxx:2813
unsigned int screen() const
Definition: salgeom.hxx:65
SalFrameGeometry maGeometry
absolute, unmirrored values
Definition: salframe.hxx:127
virtual std::unique_ptr< SalMenu > CreateMenu(bool bMenuBar, Menu *pMenu)
Definition: salvtables.cxx:157
virtual void SetAccelerator(unsigned nPos, SalMenuItem *pSalMenuItem, const vcl::KeyCode &rKeyCode, const OUString &rKeyName)=0
virtual void GetSystemMenuData(SystemMenuData *pData)=0
virtual int GetMenuBarHeight() const
Definition: salvtables.cxx:234
virtual void SetSubMenu(SalMenuItem *pSalMenuItem, SalMenu *pSubMenu, unsigned nPos)=0
virtual void SetItemBits(unsigned, MenuItemBits)
Definition: salmenu.hxx:70
virtual bool CanGetFocus() const
Definition: salmenu.hxx:83
virtual bool ShowNativePopupMenu(FloatingWindow *pWin, const tools::Rectangle &rRect, FloatWinPopupFlags nFlags)
Definition: salvtables.cxx:218
virtual void ShowMenuBar(bool)
Definition: salmenu.hxx:65
virtual void EnableItem(unsigned nPos, bool bEnable)=0
virtual void RemoveItem(unsigned nPos)=0
virtual void ShowItem(unsigned nPos, bool bShow)
Definition: salmenu.hxx:87
virtual void InsertItem(SalMenuItem *pSalMenuItem, unsigned nPos)=0
virtual void Update()
Definition: salmenu.hxx:81
virtual void SetItemText(unsigned nPos, SalMenuItem *pSalMenuItem, const OUString &rText)=0
virtual void SetItemImage(unsigned nPos, SalMenuItem *pSalMenuItem, const Image &rImage)=0
virtual void CheckItem(unsigned nPos, bool bCheck)=0
virtual bool VisibleMenuBar()=0
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
void setWidth(tools::Long nWidth)
tools::Long AdjustWidth(tools::Long n)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
const Color & GetMenuHighlightTextColor() const
const Color & GetShadowColor() const
const Color & GetMenuColor() const
const Color & GetMenuBarTextColor() const
const Color & GetMenuBarRolloverTextColor() const
const Color & GetLightColor() const
bool GetSkipDisabledInMenus() const
const Color & GetMenuBarColor() const
bool GetUseImagesInMenus() const
const Color & GetHighlightColor() const
const Color & GetFaceColor() const
const Color & GetMenuBarHighlightTextColor() const
const Color & GetMenuTextColor() const
static bool IsCycleKey(const vcl::KeyCode &rKeyCode)
virtual css::uno::Reference< css::awt::XPopupMenu > CreateMenuInterface(PopupMenu *pPopupMenu)=0
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible(Menu *pMenu, bool bIsMenuBar)=0
static UnoWrapperBase * GetUnoWrapper(bool bCreateIfNotExists=true)
Get the application's UNO wrapper object.
Definition: svapp.cxx:1473
A construction helper for a temporary VclPtr.
Definition: vclptr.hxx:277
void disposeAndClear()
Definition: vclptr.hxx:200
void clear()
Definition: vclptr.hxx:190
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
static VclPtr< reference_type > Create(Arg &&... arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
bool isDisposed() const
virtual void dispose()
SalFrame * mpFrame
Definition: window.h:229
constexpr tools::Long GetWidth() const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
tools::Long getOpenHeight() const
void SetPos(const Point &rPoint)
void setWidth(tools::Long n)
constexpr Size GetSize() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
constexpr Point BottomRight() const
constexpr tools::Long GetHeight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
void setHeight(tools::Long n)
tools::Long getOpenWidth() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
void SetWeight(FontWeight)
Definition: font/font.cxx:236
OUString GetName() const
Definition: keycod.cxx:66
static SettingsConfigItem * get()
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2806
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
Width of the text.
Definition: window3.cxx:66
void SetFont(const vcl::Font &rNewFont)
Definition: window3.cxx:59
bool IsReallyVisible() const
Definition: window2.cxx:1133
vcl::Window * GetParent() const
Definition: window2.cxx:1123
bool IsInputEnabled() const
Definition: window2.cxx:1153
WindowType GetType() const
Definition: window2.cxx:1000
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: window.cxx:2424
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1036
void SetAccessible(const css::uno::Reference< css::accessibility::XAccessible > &)
void GrabFocus()
Definition: window.cxx:2976
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion) const
Query the native control's actual drawing region (including adornment)
Definition: window3.cxx:79
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: window3.cxx:65
const AllSettings & GetSettings() const
Definition: window3.cxx:129
virtual void KeyInput(const KeyEvent &rKEvt)
Definition: window.cxx:1805
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
Definition: window3.cxx:74
VclPtr< vcl::Window > GetParentWithLOKNotifier()
Find the nearest parent with LOK Notifier; can be itself if this Window has LOK notifier set.
Definition: window.cxx:3256
::OutputDevice const * GetOutDev() const
Definition: window.cxx:567
const vcl::Font & GetFont() const
Definition: window3.cxx:58
const vcl::ILibreOfficeKitNotifier * GetLOKNotifier() const
Definition: window.cxx:3246
bool IsInModalMode() const
A window is in modal mode if one of its children or subchildren is a running modal window (a modal di...
Definition: window.cxx:3597
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:528
virtual Size GetSizePixel() const
Definition: window.cxx:2402
Size GetOutputSizePixel() const
Definition: window3.cxx:89
bool IsVisible() const
Definition: window2.cxx:1128
void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1143
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
Definition: window.cxx:2855
bool IsEnabled() const
Definition: window2.cxx:1148
int nCount
DrawSymbolFlags
Definition: decoview.hxx:35
#define ENSURE_OR_RETURN(c, m, r)
ItemID nItemID
float y
float x
sal_Int32 nState
DocumentType eType
WEIGHT_BOLD
sal_Int32 nIndex
OUString aName
void * p
sal_Int64 n
constexpr sal_uInt16 KEY_0
Definition: keycodes.hxx:45
constexpr sal_uInt16 KEY_MOD2
Definition: keycodes.hxx:32
constexpr sal_uInt16 KEY_A
Definition: keycodes.hxx:56
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
static void ImplSetMenuItemData(MenuItemData *pData)
Definition: menu.cxx:91
#define EXTRAITEMHEIGHT
Definition: menu.cxx:73
IMPL_LINK_NOARG(Menu, ImplCallSelect, void *, void)
Definition: menu.cxx:2132
static FloatWinPopupFlags lcl_TranslateFlags(PopupMenuFlags nFlags)
Definition: menu.cxx:2776
static bool ImplAccelDisabled()
Definition: menu.cxx:76
static void ImplCopyItem(Menu *pThis, const Menu &rMenu, sal_uInt16 nPos, sal_uInt16 nNewPos)
Definition: menu.cxx:523
static OUString getShortenedString(const OUString &i_rLong, vcl::RenderContext const &rRenderContext, tools::Long i_nMaxWidth)
Definition: menu.cxx:1676
static void ImplPaintCheckBackground(vcl::RenderContext &rRenderContext, vcl::Window const &rWindow, const tools::Rectangle &i_rRect, bool i_bHighlight)
Definition: menu.cxx:1651
#define SPACE_AROUND_TITLE
Definition: menu.cxx:74
MenuFlags
Definition: menu.hxx:86
@ HideDisabledEntries
@ AlwaysShowDisabledEntries
constexpr auto ITEMPOS_INVALID
Invalid menu item id.
Definition: menu.hxx:100
PopupMenuFlags
Definition: menu.hxx:72
void(* MenuUserDataReleaseFunction)(void *)
Definition: menu.hxx:113
constexpr sal_uInt16 MENU_APPEND
Definition: menu.hxx:67
constexpr sal_uInt16 MENU_ITEM_NOTFOUND
Definition: menu.hxx:68
#define GUTTERBORDER
aStr
std::unique_ptr< sal_Int32[]> pData
NONE
tools::Long const nBorder
size
int i
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
@ eSymbol
Definition: ppdparser.hxx:44
long Long
bool IsInPopupMenuExecute()
Definition: menu.cxx:2716
sal_Int16 nId
VclPtr< const Menu > mpMenu
Definition: menu.hxx:105
ImplMenuDelData(const Menu *)
Definition: menu.cxx:3112
ImplMenuDelData * mpNext
Definition: menu.hxx:104
bool isDeleted() const
Definition: menu.hxx:110
VclPtr< PopupMenu > mpActivePopupMenu
Definition: svdata.hxx:156
SalInstance * mpDefInst
Definition: svdata.hxx:389
ImplSVNWFData maNWFData
Definition: svdata.hxx:403
ImplSVWinData * mpWinData
Definition: svdata.hxx:400
ImplSVAppData maAppData
Definition: svdata.hxx:397
bool mbFlatMenu
Definition: svdata.hxx:324
int mnMenuFormatBorderY
Definition: svdata.hxx:317
int mnMenuFormatBorderX
Definition: svdata.hxx:316
VclPtr< FloatingWindow > mpFirstFloat
Definition: svdata.hxx:254
bool mbNoDeactivate
Definition: svdata.hxx:266
VclPtr< Menu > pSubMenu
sal_uInt16 nId
MenuItemBits nBits
MenuItemType eType
std::vector< sal_uInt16 > m_aLineItemIds
Definition: menu.cxx:65
std::map< sal_uInt16, tools::Rectangle > m_aVisibleItemBoundRects
Definition: menu.cxx:66
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:77
DockingManager * ImplGetDockingManager()
Definition: svdata.cxx:316
OUString VclResId(TranslateId aId)
Definition: svdata.cxx:261
OUString removeMnemonicFromString(OUString const &rStr)
bool bVisible
sal_uInt16 sal_Unicode
MenuItemType
Definition: vclenum.hxx:30
MenuItemBits
Definition: vclenum.hxx:33
SymbolType
Definition: vclenum.hxx:74
FloatWinPopupFlags
Definition: vclenum.hxx:323
VclEventId
Definition: vclevent.hxx:38
@ MenuSubmenuChanged
@ MenuItemRoleChanged
@ MenuItemTextChanged
@ MenuAccessibleNameChanged
@ MenuSubmenuActivate
WinBits const WB_SYSTEMWINDOW
Definition: wintypes.hxx:126
WinBits const WB_BORDER
Definition: wintypes.hxx:115