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 OString &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 OString &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 OString &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 OString &rIdent, sal_uInt16 nPos)
467{
468 InsertItem(nItemId, rStr, nItemBits, rIdent, nPos);
469 SetItemImage( nItemId, rImage );
470}
471
472void Menu::InsertSeparator(const OString &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( OString(), 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
583{
584 sal_uInt16 nItems = 0;
585 for ( size_t n = pItemList->size(); n; )
586 {
587 if ( ImplIsVisible( --n ) )
588 nItems++;
589 }
590 return nItems;
591}
592
594{
595 for ( size_t n = 0; n < pItemList->size(); n++ )
596 {
597 if ( ImplIsVisible( n ) )
598 return n;
599 }
600 return ITEMPOS_INVALID;
601}
602
603sal_uInt16 Menu::ImplGetPrevVisible( sal_uInt16 nPos ) const
604{
605 for ( size_t n = nPos; n; )
606 {
607 if (ImplIsVisible(--n))
608 return n;
609 }
610 return ITEMPOS_INVALID;
611}
612
613sal_uInt16 Menu::ImplGetNextVisible( sal_uInt16 nPos ) const
614{
615 for ( size_t n = nPos+1; n < pItemList->size(); n++ )
616 {
617 if ( ImplIsVisible( n ) )
618 return n;
619 }
620 return ITEMPOS_INVALID;
621}
622
623sal_uInt16 Menu::GetItemId(sal_uInt16 nPos) const
624{
625 MenuItemData* pData = pItemList->GetDataFromPos( nPos );
626
627 if ( pData )
628 return pData->nId;
629 else
630 return 0;
631}
632
633sal_uInt16 Menu::GetItemId(std::string_view rIdent) const
634{
635 for (size_t n = 0; n < pItemList->size(); ++n)
636 {
637 MenuItemData* pData = pItemList->GetDataFromPos(n);
638 if (pData && pData->sIdent == rIdent)
639 return pData->nId;
640 }
641 return MENU_ITEM_NOTFOUND;
642}
643
644sal_uInt16 Menu::GetItemPos( sal_uInt16 nItemId ) const
645{
646 size_t nPos;
647 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
648
649 if ( pData )
650 return static_cast<sal_uInt16>(nPos);
651 else
652 return MENU_ITEM_NOTFOUND;
653}
654
655MenuItemType Menu::GetItemType( sal_uInt16 nPos ) const
656{
657 MenuItemData* pData = pItemList->GetDataFromPos( nPos );
658
659 if ( pData )
660 return pData->eType;
661 else
663}
664
665OString Menu::GetItemIdent(sal_uInt16 nId) const
666{
667 const MenuItemData* pData = pItemList->GetData(nId);
668 return pData ? pData->sIdent : OString();
669}
670
671void Menu::SetItemBits( sal_uInt16 nItemId, MenuItemBits nBits )
672{
673 size_t nPos;
674 MenuItemData* pData = pItemList->GetData(nItemId, nPos);
675
676 if (pData && (pData->nBits != nBits))
677 {
678 pData->nBits = nBits;
679
680 // update native menu
681 if (ImplGetSalMenu())
683 }
684}
685
686MenuItemBits Menu::GetItemBits( sal_uInt16 nItemId ) const
687{
689 MenuItemData* pData = pItemList->GetData( nItemId );
690 if ( pData )
691 nBits = pData->nBits;
692 return nBits;
693}
694
695void Menu::SetUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc)
696{
697 MenuItemData* pData = pItemList->GetData(nItemId);
698 if (pData)
699 {
700 if (pData->aUserValueReleaseFunc)
701 pData->aUserValueReleaseFunc(pData->nUserValue);
702 pData->aUserValueReleaseFunc = aFunc;
703 pData->nUserValue = nUserValue;
704 }
705}
706
707void* Menu::GetUserValue( sal_uInt16 nItemId ) const
708{
709 MenuItemData* pData = pItemList->GetData( nItemId );
710 return pData ? pData->nUserValue : nullptr;
711}
712
713void Menu::SetPopupMenu( sal_uInt16 nItemId, PopupMenu* pMenu )
714{
715 size_t nPos;
716 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
717
718 // Item does not exist -> return NULL
719 if ( !pData )
720 return;
721
722 // same menu, nothing to do
723 if ( static_cast<PopupMenu*>(pData->pSubMenu.get()) == pMenu )
724 return;
725
726 // remove old menu
727 auto oldSubMenu = pData->pSubMenu;
728
729 // data exchange
730 pData->pSubMenu = pMenu;
731
732 // #112023# Make sure pStartedFrom does not point to invalid (old) data
733 if ( pData->pSubMenu )
734 pData->pSubMenu->pStartedFrom = nullptr;
735
736 // set native submenu
737 if( ImplGetSalMenu() && pData->pSalMenuItem )
738 {
739 if( pMenu )
740 ImplGetSalMenu()->SetSubMenu( pData->pSalMenuItem.get(), pMenu->ImplGetSalMenu(), nPos );
741 else
742 ImplGetSalMenu()->SetSubMenu( pData->pSalMenuItem.get(), nullptr, nPos );
743 }
744
745 oldSubMenu.disposeAndClear();
746
748}
749
750PopupMenu* Menu::GetPopupMenu( sal_uInt16 nItemId ) const
751{
752 MenuItemData* pData = pItemList->GetData( nItemId );
753
754 if ( pData )
755 return static_cast<PopupMenu*>(pData->pSubMenu.get());
756 else
757 return nullptr;
758}
759
760void Menu::SetAccelKey( sal_uInt16 nItemId, const KeyCode& rKeyCode )
761{
762 size_t nPos;
763 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
764
765 if ( !pData )
766 return;
767
768 if ( pData->aAccelKey == rKeyCode )
769 return;
770
771 pData->aAccelKey = rKeyCode;
772
773 // update native menu
774 if( ImplGetSalMenu() && pData->pSalMenuItem )
775 ImplGetSalMenu()->SetAccelerator( nPos, pData->pSalMenuItem.get(), rKeyCode, rKeyCode.GetName() );
776}
777
778KeyCode Menu::GetAccelKey( sal_uInt16 nItemId ) const
779{
780 MenuItemData* pData = pItemList->GetData( nItemId );
781
782 if ( pData )
783 return pData->aAccelKey;
784 else
785 return KeyCode();
786}
787
788KeyEvent Menu::GetActivationKey( sal_uInt16 nItemId ) const
789{
790 KeyEvent aRet;
791 MenuItemData* pData = pItemList->GetData( nItemId );
792 if( pData )
793 {
794 sal_Int32 nPos = pData->aText.indexOf( '~' );
795 if( nPos != -1 && nPos < pData->aText.getLength()-1 )
796 {
797 sal_uInt16 nCode = 0;
798 sal_Unicode cAccel = pData->aText[nPos+1];
799 if( cAccel >= 'a' && cAccel <= 'z' )
800 nCode = KEY_A + (cAccel-'a');
801 else if( cAccel >= 'A' && cAccel <= 'Z' )
802 nCode = KEY_A + (cAccel-'A');
803 else if( cAccel >= '0' && cAccel <= '9' )
804 nCode = KEY_0 + (cAccel-'0');
805
806 aRet = KeyEvent( cAccel, KeyCode( nCode, KEY_MOD2 ) );
807 }
808
809 }
810 return aRet;
811}
812
813void Menu::CheckItem( sal_uInt16 nItemId, bool bCheck )
814{
815 size_t nPos;
816 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
817
818 if ( !pData || pData->bChecked == bCheck )
819 return;
820
821 // if radio-check, then uncheck previous
822 if ( bCheck && (pData->nBits & MenuItemBits::AUTOCHECK) &&
824 {
825 MenuItemData* pGroupData;
826 sal_uInt16 nGroupPos;
827 sal_uInt16 nItemCount = GetItemCount();
828 bool bFound = false;
829
830 nGroupPos = nPos;
831 while ( nGroupPos )
832 {
833 pGroupData = pItemList->GetDataFromPos( nGroupPos-1 );
834 if ( pGroupData->nBits & MenuItemBits::RADIOCHECK )
835 {
836 if ( IsItemChecked( pGroupData->nId ) )
837 {
838 CheckItem( pGroupData->nId, false );
839 bFound = true;
840 break;
841 }
842 }
843 else
844 break;
845 nGroupPos--;
846 }
847
848 if ( !bFound )
849 {
850 nGroupPos = nPos+1;
851 while ( nGroupPos < nItemCount )
852 {
853 pGroupData = pItemList->GetDataFromPos( nGroupPos );
854 if ( pGroupData->nBits & MenuItemBits::RADIOCHECK )
855 {
856 if ( IsItemChecked( pGroupData->nId ) )
857 {
858 CheckItem( pGroupData->nId, false );
859 break;
860 }
861 }
862 else
863 break;
864 nGroupPos++;
865 }
866 }
867 }
868
869 pData->bChecked = bCheck;
870
871 // update native menu
872 if( ImplGetSalMenu() )
873 ImplGetSalMenu()->CheckItem( nPos, bCheck );
874
876}
877
878void Menu::CheckItem( std::string_view rIdent , bool bCheck )
879{
880 CheckItem( GetItemId( rIdent ), bCheck );
881}
882
883bool Menu::IsItemChecked( sal_uInt16 nItemId ) const
884{
885 size_t nPos;
886 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
887
888 if ( !pData )
889 return false;
890
891 return pData->bChecked;
892}
893
894void Menu::EnableItem( sal_uInt16 nItemId, bool bEnable )
895{
896 size_t nPos;
897 MenuItemData* pItemData = pItemList->GetData( nItemId, nPos );
898
899 if ( !(pItemData && ( pItemData->bEnabled != bEnable )) )
900 return;
901
902 pItemData->bEnabled = bEnable;
903
904 vcl::Window* pWin = ImplGetWindow();
905 if ( pWin && pWin->IsVisible() )
906 {
907 SAL_WARN_IF(!IsMenuBar(), "vcl", "Menu::EnableItem - Popup visible!" );
908 tools::Long nX = 0;
909 size_t nCount = pItemList->size();
910 for ( size_t n = 0; n < nCount; n++ )
911 {
912 MenuItemData* pData = pItemList->GetDataFromPos( n );
913 if ( n == nPos )
914 {
915 pWin->Invalidate( tools::Rectangle( Point( nX, 0 ), Size( pData->aSz.Width(), pData->aSz.Height() ) ) );
916 break;
917 }
918 nX += pData->aSz.Width();
919 }
920 }
921 // update native menu
922 if( ImplGetSalMenu() )
923 ImplGetSalMenu()->EnableItem( nPos, bEnable );
924
926}
927
928bool Menu::IsItemEnabled( sal_uInt16 nItemId ) const
929{
930 size_t nPos;
931 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
932
933 if ( !pData )
934 return false;
935
936 return pData->bEnabled;
937}
938
939void Menu::ShowItem( sal_uInt16 nItemId, bool bVisible )
940{
941 size_t nPos;
942 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
943
944 SAL_WARN_IF(IsMenuBar() && !bVisible , "vcl", "Menu::ShowItem - ignored for menu bar entries!");
945 if (IsMenuBar() || !pData || (pData->bVisible == bVisible))
946 return;
947
948 vcl::Window* pWin = ImplGetWindow();
949 if ( pWin && pWin->IsVisible() )
950 {
951 SAL_WARN( "vcl", "Menu::ShowItem - ignored for visible popups!" );
952 return;
953 }
954 pData->bVisible = bVisible;
955
956 // update native menu
957 if( ImplGetSalMenu() )
959}
960
961void Menu::SetItemText( sal_uInt16 nItemId, const OUString& rStr )
962{
963 size_t nPos;
964 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
965
966 if ( !pData )
967 return;
968
969 if ( rStr == pData->aText )
970 return;
971
972 pData->aText = rStr;
973 // Clear layout for aText.
974 pData->aTextGlyphs.Invalidate();
976 // update native menu
977 if( ImplGetSalMenu() && pData->pSalMenuItem )
978 ImplGetSalMenu()->SetItemText( nPos, pData->pSalMenuItem.get(), rStr );
979
980 vcl::Window* pWin = ImplGetWindow();
981 mpLayoutData.reset();
982 if (pWin && IsMenuBar())
983 {
984 ImplCalcSize( pWin );
985 if ( pWin->IsVisible() )
986 pWin->Invalidate();
987 }
988
990}
991
992OUString Menu::GetItemText( sal_uInt16 nItemId ) const
993{
994 size_t nPos;
995 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
996
997 if ( pData )
998 return pData->aText;
999
1000 return OUString();
1001}
1002
1003void Menu::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
1004{
1005 size_t nPos;
1006 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
1007
1008 if ( !pData )
1009 return;
1010
1011 pData->aImage = rImage;
1013
1014 // update native menu
1015 if( ImplGetSalMenu() && pData->pSalMenuItem )
1016 ImplGetSalMenu()->SetItemImage( nPos, pData->pSalMenuItem.get(), rImage );
1017}
1018
1019Image Menu::GetItemImage( sal_uInt16 nItemId ) const
1020{
1021 MenuItemData* pData = pItemList->GetData( nItemId );
1022
1023 if ( pData )
1024 return pData->aImage;
1025 else
1026 return Image();
1027}
1028
1029void Menu::SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand )
1030{
1031 size_t nPos;
1032 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
1033
1034 if ( pData )
1035 pData->aCommandStr = rCommand;
1036}
1037
1038OUString Menu::GetItemCommand( sal_uInt16 nItemId ) const
1039{
1040 MenuItemData* pData = pItemList->GetData( nItemId );
1041
1042 if (pData)
1043 return pData->aCommandStr;
1044
1045 return OUString();
1046}
1047
1048void Menu::SetHelpCommand( sal_uInt16 nItemId, const OUString& rStr )
1049{
1050 MenuItemData* pData = pItemList->GetData( nItemId );
1051
1052 if ( pData )
1053 pData->aHelpCommandStr = rStr;
1054}
1055
1056OUString Menu::GetHelpCommand( sal_uInt16 nItemId ) const
1057{
1058 MenuItemData* pData = pItemList->GetData( nItemId );
1059
1060 if ( pData )
1061 return pData->aHelpCommandStr;
1062
1063 return OUString();
1064}
1065
1066void Menu::SetHelpText( sal_uInt16 nItemId, const OUString& rStr )
1067{
1068 MenuItemData* pData = pItemList->GetData( nItemId );
1069
1070 if ( pData )
1071 pData->aHelpText = rStr;
1072}
1073
1074OUString Menu::ImplGetHelpText( sal_uInt16 nItemId ) const
1075{
1076 MenuItemData* pData = pItemList->GetData( nItemId );
1077
1078 if (!pData)
1079 return OUString();
1080
1081 if ( pData->aHelpText.isEmpty() &&
1082 (( !pData->aHelpId.isEmpty() ) || ( !pData->aCommandStr.isEmpty() )))
1083 {
1084 Help* pHelp = Application::GetHelp();
1085 if ( pHelp )
1086 {
1087 if (!pData->aCommandStr.isEmpty())
1088 pData->aHelpText = pHelp->GetHelpText( pData->aCommandStr, static_cast<weld::Widget*>(nullptr) );
1089 if (pData->aHelpText.isEmpty() && !pData->aHelpId.isEmpty())
1090 pData->aHelpText = pHelp->GetHelpText( OStringToOUString( pData->aHelpId, RTL_TEXTENCODING_UTF8 ), static_cast<weld::Widget*>(nullptr) );
1091 }
1092 }
1093
1094 return pData->aHelpText;
1095}
1096
1097OUString Menu::GetHelpText( sal_uInt16 nItemId ) const
1098{
1099 return ImplGetHelpText( nItemId );
1100}
1101
1102void Menu::SetTipHelpText( sal_uInt16 nItemId, const OUString& rStr )
1103{
1104 MenuItemData* pData = pItemList->GetData( nItemId );
1105
1106 if ( pData )
1107 pData->aTipHelpText = rStr;
1108}
1109
1110OUString Menu::GetTipHelpText( sal_uInt16 nItemId ) const
1111{
1112 MenuItemData* pData = pItemList->GetData( nItemId );
1113
1114 if ( pData )
1115 return pData->aTipHelpText;
1116
1117 return OUString();
1118}
1119
1120void Menu::SetHelpId( sal_uInt16 nItemId, const OString& rHelpId )
1121{
1122 MenuItemData* pData = pItemList->GetData( nItemId );
1123
1124 if ( pData )
1125 pData->aHelpId = rHelpId;
1126}
1127
1128OString Menu::GetHelpId( sal_uInt16 nItemId ) const
1129{
1130 OString aRet;
1131
1132 MenuItemData* pData = pItemList->GetData( nItemId );
1133
1134 if ( pData )
1135 {
1136 if ( !pData->aHelpId.isEmpty() )
1137 aRet = pData->aHelpId;
1138 else
1139 aRet = OUStringToOString( pData->aCommandStr, RTL_TEXTENCODING_UTF8 );
1140 }
1141
1142 return aRet;
1143}
1144
1145Menu& Menu::operator=( const Menu& rMenu )
1146{
1147 if(this == &rMenu)
1148 return *this;
1149
1150 // clean up
1151 Clear();
1152
1153 // copy items
1154 sal_uInt16 nCount = rMenu.GetItemCount();
1155 for ( sal_uInt16 i = 0; i < nCount; i++ )
1156 ImplCopyItem( this, rMenu, i, MENU_APPEND );
1157
1158 aActivateHdl = rMenu.aActivateHdl;
1160 aSelectHdl = rMenu.aSelectHdl;
1161 aTitleText = rMenu.aTitleText;
1162 nTitleHeight = rMenu.nTitleHeight;
1163
1164 return *this;
1165}
1166
1167// Returns true if the item is completely hidden on the GUI and shouldn't
1168// be possible to interact with
1169bool Menu::ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const
1170{
1171 MenuItemData* pData = pItemList->GetDataFromPos(nPos);
1172 if (pData)
1173 {
1174 MenuItemData* pPreviousData = pItemList->GetDataFromPos( nPos - 1 );
1175 if (pPreviousData && pPreviousData->bHiddenOnGUI)
1176 {
1177 return true;
1178 }
1179 }
1180 return false;
1181}
1182
1183bool Menu::ImplIsVisible( sal_uInt16 nPos ) const
1184{
1185 bool bVisible = true;
1186
1187 MenuItemData* pData = pItemList->GetDataFromPos( nPos );
1188 // check general visibility first
1189 if( pData && !pData->bVisible )
1190 bVisible = false;
1191
1192 if ( bVisible && pData && pData->eType == MenuItemType::SEPARATOR )
1193 {
1194 if( nPos == 0 ) // no separator should be shown at the very beginning
1195 bVisible = false;
1196 else
1197 {
1198 // always avoid adjacent separators
1199 size_t nCount = pItemList->size();
1200 size_t n;
1201 MenuItemData* pNextData = nullptr;
1202 // search next visible item
1203 for( n = nPos + 1; n < nCount; n++ )
1204 {
1205 pNextData = pItemList->GetDataFromPos( n );
1206 if( pNextData && pNextData->bVisible )
1207 {
1208 if( pNextData->eType == MenuItemType::SEPARATOR || ImplIsVisible(n) )
1209 break;
1210 }
1211 }
1212 if( n == nCount ) // no next visible item
1213 bVisible = false;
1214 // check for separator
1215 if( pNextData && pNextData->bVisible && pNextData->eType == MenuItemType::SEPARATOR )
1216 bVisible = false;
1217
1218 if( bVisible )
1219 {
1220 for( n = nPos; n > 0; n-- )
1221 {
1222 pNextData = pItemList->GetDataFromPos( n-1 );
1223 if( pNextData && pNextData->bVisible )
1224 {
1225 if( pNextData->eType != MenuItemType::SEPARATOR && ImplIsVisible(n-1) )
1226 break;
1227 }
1228 }
1229 if( n == 0 ) // no previous visible item
1230 bVisible = false;
1231 }
1232 }
1233 }
1234
1235 // not allowed for menubar, as I do not know
1236 // whether a menu-entry will disappear or will appear
1239 {
1240 if( !pData ) // e.g. nPos == ITEMPOS_INVALID
1241 bVisible = false;
1242 else if ( pData->eType != MenuItemType::SEPARATOR ) // separators handled above
1243 {
1244 // tdf#86850 Always display clipboard functions
1245 if ( pData->aCommandStr == ".uno:Cut" || pData->aCommandStr == ".uno:Copy" || pData->aCommandStr == ".uno:Paste" ||
1246 pData->sIdent == ".uno:Cut" || pData->sIdent == ".uno:Copy" || pData->sIdent == ".uno:Paste" )
1247 bVisible = true;
1248 else
1249 // bVisible = pData->bEnabled && ( !pData->pSubMenu || pData->pSubMenu->HasValidEntries( true ) );
1250 bVisible = pData->bEnabled; // do not check submenus as they might be filled at Activate().
1251 }
1252 }
1253
1254 return bVisible;
1255}
1256
1257bool Menu::IsItemPosVisible( sal_uInt16 nItemPos ) const
1258{
1259 return IsMenuVisible() && ImplIsVisible( nItemPos );
1260}
1261
1263{
1264 return pWindow && pWindow->IsReallyVisible();
1265}
1266
1267bool Menu::ImplIsSelectable( sal_uInt16 nPos ) const
1268{
1269 bool bSelectable = true;
1270
1271 MenuItemData* pData = pItemList->GetDataFromPos( nPos );
1272 // check general visibility first
1273 if ( pData && ( pData->nBits & MenuItemBits::NOSELECT ) )
1274 bSelectable = false;
1275
1276 return bSelectable;
1277}
1278
1279css::uno::Reference<css::accessibility::XAccessible> Menu::GetAccessible()
1280{
1281 // Since PopupMenu are sometimes shared by different instances of MenuBar, the mxAccessible member gets
1282 // overwritten and may contain a disposed object when the initial menubar gets set again. So use the
1283 // mxAccessible member only for sub menus.
1284 if (pStartedFrom && pStartedFrom != this)
1285 {
1286 for ( sal_uInt16 i = 0, nCount = pStartedFrom->GetItemCount(); i < nCount; ++i )
1287 {
1288 sal_uInt16 nItemId = pStartedFrom->GetItemId( i );
1289 if ( static_cast< Menu* >( pStartedFrom->GetPopupMenu( nItemId ) ) == this )
1290 {
1291 css::uno::Reference<css::accessibility::XAccessible> xParent = pStartedFrom->GetAccessible();
1292 if ( xParent.is() )
1293 {
1294 css::uno::Reference<css::accessibility::XAccessibleContext> xParentContext( xParent->getAccessibleContext() );
1295 if (xParentContext.is())
1296 return xParentContext->getAccessibleChild( i );
1297 }
1298 }
1299 }
1300 }
1301 else if ( !mxAccessible.is() )
1302 {
1304 if ( pWrapper )
1305 mxAccessible = pWrapper->CreateAccessible(this, IsMenuBar());
1306 }
1307
1308 return mxAccessible;
1309}
1310
1311void Menu::SetAccessible(const css::uno::Reference<css::accessibility::XAccessible>& rxAccessible )
1312{
1313 mxAccessible = rxAccessible;
1314}
1315
1316Size Menu::ImplGetNativeCheckAndRadioSize(vcl::RenderContext const & rRenderContext, tools::Long& rCheckHeight, tools::Long& rRadioHeight ) const
1317{
1318 tools::Long nCheckWidth = 0, nRadioWidth = 0;
1319 rCheckHeight = rRadioHeight = 0;
1320
1321 if (!IsMenuBar())
1322 {
1323 ImplControlValue aVal;
1324 tools::Rectangle aNativeBounds;
1325 tools::Rectangle aNativeContent;
1326
1327 tools::Rectangle aCtrlRegion(tools::Rectangle(Point(), Size(100, 15)));
1329 {
1331 aCtrlRegion, ControlState::ENABLED, aVal,
1332 aNativeBounds, aNativeContent))
1333 {
1334 rCheckHeight = aNativeBounds.GetHeight() - 1;
1335 nCheckWidth = aNativeContent.GetWidth() - 1;
1336 }
1337 }
1339 {
1341 aCtrlRegion, ControlState::ENABLED, aVal,
1342 aNativeBounds, aNativeContent))
1343 {
1344 rRadioHeight = aNativeBounds.GetHeight() - 1;
1345 nRadioWidth = aNativeContent.GetWidth() - 1;
1346 }
1347 }
1348 }
1349 return Size(std::max(nCheckWidth, nRadioWidth), std::max(rCheckHeight, rRadioHeight));
1350}
1351
1352bool Menu::ImplGetNativeSubmenuArrowSize(vcl::RenderContext const & rRenderContext, Size& rArrowSize, tools::Long& rArrowSpacing)
1353{
1354 ImplControlValue aVal;
1355 tools::Rectangle aCtrlRegion(tools::Rectangle(Point(), Size(100, 15)));
1357 {
1358 tools::Rectangle aNativeContent;
1359 tools::Rectangle aNativeBounds;
1361 aCtrlRegion, ControlState::ENABLED,
1362 aVal, aNativeBounds, aNativeContent))
1363 {
1364 Size aSize(aNativeContent.GetWidth(), aNativeContent.GetHeight());
1365 rArrowSize = aSize;
1366 rArrowSpacing = aNativeBounds.GetWidth() - aNativeContent.GetWidth();
1367 return true;
1368 }
1369 }
1370 return false;
1371}
1372
1374{
1375 SAL_WARN_IF( rDel.mpMenu, "vcl", "Menu::ImplAddDel(): cannot add ImplMenuDelData twice !" );
1376 if( !rDel.mpMenu )
1377 {
1378 rDel.mpMenu = this;
1379 rDel.mpNext = mpFirstDel;
1380 mpFirstDel = &rDel;
1381 }
1382}
1383
1385{
1386 rDel.mpMenu = nullptr;
1387 if ( mpFirstDel == &rDel )
1388 {
1389 mpFirstDel = rDel.mpNext;
1390 }
1391 else
1392 {
1394 while ( pData && (pData->mpNext != &rDel) )
1395 pData = pData->mpNext;
1396
1397 SAL_WARN_IF( !pData, "vcl", "Menu::ImplRemoveDel(): ImplMenuDelData not registered !" );
1398 if( pData )
1399 pData->mpNext = rDel.mpNext;
1400 }
1401}
1402
1404{
1405 // | Check/Radio/Image| Text| Accel/Popup|
1406
1407 // for symbols: nFontHeight x nFontHeight
1408 tools::Long nFontHeight = pWin->GetTextHeight();
1409 tools::Long nExtra = nFontHeight/4;
1410
1411 tools::Long nMinMenuItemHeight = nFontHeight;
1412 tools::Long nCheckHeight = 0, nRadioHeight = 0;
1413 Size aMarkSize = ImplGetNativeCheckAndRadioSize(*pWin->GetOutDev(), nCheckHeight, nRadioHeight);
1414 if( aMarkSize.Height() > nMinMenuItemHeight )
1415 nMinMenuItemHeight = aMarkSize.Height();
1416
1417 tools::Long aMaxImgWidth = 0;
1418
1419 const StyleSettings& rSettings = pWin->GetSettings().GetStyleSettings();
1420 if ( rSettings.GetUseImagesInMenus() )
1421 {
1422 if ( 16 > nMinMenuItemHeight )
1423 nMinMenuItemHeight = 16;
1424 for ( size_t i = pItemList->size(); i; )
1425 {
1426 MenuItemData* pData = pItemList->GetDataFromPos( --i );
1427 if ( ImplIsVisible( i )
1428 && ( ( pData->eType == MenuItemType::IMAGE )
1429 || ( pData->eType == MenuItemType::STRINGIMAGE )
1430 )
1431 )
1432 {
1433 Size aImgSz = pData->aImage.GetSizePixel();
1434 if ( aImgSz.Width() > aMaxImgWidth )
1435 aMaxImgWidth = aImgSz.Width();
1436 if ( aImgSz.Height() > nMinMenuItemHeight )
1437 nMinMenuItemHeight = aImgSz.Height();
1438 break;
1439 }
1440 }
1441 }
1442
1443 Size aSz;
1444 tools::Long nMaxWidth = 0;
1445
1446 for ( size_t n = pItemList->size(); n; )
1447 {
1448 MenuItemData* pData = pItemList->GetDataFromPos( --n );
1449
1450 pData->aSz.setHeight( 0 );
1451 pData->aSz.setWidth( 0 );
1452
1453 if ( ImplIsVisible( n ) )
1454 {
1455 tools::Long nWidth = 0;
1456
1457 // Separator
1458 if (!IsMenuBar()&& (pData->eType == MenuItemType::SEPARATOR))
1459 {
1460 pData->aSz.setHeight( 4 );
1461 }
1462
1463 // Image:
1464 if (!IsMenuBar() && ((pData->eType == MenuItemType::IMAGE) || (pData->eType == MenuItemType::STRINGIMAGE)))
1465 {
1466 tools::Long aImgHeight = pData->aImage.GetSizePixel().Height();
1467
1468 aImgHeight += 4; // add a border for native marks
1469 if (aImgHeight > pData->aSz.Height())
1470 pData->aSz.setHeight(aImgHeight);
1471 }
1472
1473 // Check Buttons:
1474 if (!IsMenuBar() && pData->HasCheck())
1475 {
1476 // checks / images take the same place
1477 if( ( pData->eType != MenuItemType::IMAGE ) && ( pData->eType != MenuItemType::STRINGIMAGE ) )
1478 {
1479 nWidth += aMarkSize.Width() + nExtra * 2;
1480 if (aMarkSize.Height() > pData->aSz.Height())
1481 pData->aSz.setHeight(aMarkSize.Height());
1482 }
1483 }
1484
1485 // Text:
1486 if ( (pData->eType == MenuItemType::STRING) || (pData->eType == MenuItemType::STRINGIMAGE) )
1487 {
1488 const SalLayoutGlyphs* pGlyphs = pData->GetTextGlyphs(pWin->GetOutDev());
1489 tools::Long nTextWidth = pWin->GetOutDev()->GetCtrlTextWidth(pData->aText, pGlyphs);
1490 tools::Long nTextHeight = pWin->GetTextHeight() + EXTRAITEMHEIGHT;
1491
1492 if (IsMenuBar())
1493 {
1494 if ( nTextHeight > pData->aSz.Height() )
1495 pData->aSz.setHeight( nTextHeight );
1496
1497 pData->aSz.setWidth( nTextWidth + 4*nExtra );
1498 aSz.AdjustWidth(pData->aSz.Width() );
1499 }
1500 else
1501 pData->aSz.setHeight( std::max( std::max( nTextHeight, pData->aSz.Height() ), nMinMenuItemHeight ) );
1502
1503 nWidth += nTextWidth;
1504 }
1505
1506 // Accel
1507 if (!IsMenuBar()&& pData->aAccelKey.GetCode() && !ImplAccelDisabled())
1508 {
1509 OUString aName = pData->aAccelKey.GetName();
1510 tools::Long nAccWidth = pWin->GetTextWidth( aName );
1511 nAccWidth += nExtra;
1512 nWidth += nAccWidth;
1513 }
1514
1515 // SubMenu?
1516 if (!IsMenuBar() && pData->pSubMenu)
1517 {
1518 if ( nFontHeight > nWidth )
1519 nWidth += nFontHeight;
1520
1521 pData->aSz.setHeight( std::max( std::max( nFontHeight, pData->aSz.Height() ), nMinMenuItemHeight ) );
1522 }
1523
1524 if (!IsMenuBar())
1525 aSz.AdjustHeight(pData->aSz.Height() );
1526
1527 if ( nWidth > nMaxWidth )
1528 nMaxWidth = nWidth;
1529
1530 }
1531 }
1532
1533 // Additional space for title
1534 nTitleHeight = 0;
1535 if (!IsMenuBar() && aTitleText.getLength() > 0) {
1536 // Set expected font
1537 pWin->GetOutDev()->Push(PushFlags::FONT);
1538 vcl::Font aFont = pWin->GetFont();
1539 aFont.SetWeight(WEIGHT_BOLD);
1540 pWin->SetFont(aFont);
1541
1542 // Compute text bounding box
1543 tools::Rectangle aTextBoundRect;
1544 pWin->GetOutDev()->GetTextBoundRect(aTextBoundRect, aTitleText);
1545
1546 // Vertically, one height of char + extra space for decoration
1547 nTitleHeight = aTextBoundRect.GetSize().Height() + 4 * SPACE_AROUND_TITLE ;
1549
1550 tools::Long nWidth = aTextBoundRect.GetSize().Width() + 4 * SPACE_AROUND_TITLE;
1551 pWin->GetOutDev()->Pop();
1552 if ( nWidth > nMaxWidth )
1553 nMaxWidth = nWidth;
1554 }
1555
1556 if (!IsMenuBar())
1557 {
1558 // popup menus should not be wider than half the screen
1559 // except on rather small screens
1560 // TODO: move GetScreenNumber from SystemWindow to Window ?
1561 // currently we rely on internal privileges
1562 unsigned int nDisplayScreen = pWin->ImplGetWindowImpl()->mpFrame->maGeometry.screen();
1563 tools::Rectangle aDispRect( Application::GetScreenPosSizePixel( nDisplayScreen ) );
1564 tools::Long nScreenWidth = aDispRect.GetWidth() >= 800 ? aDispRect.GetWidth() : 800;
1565 if( nMaxWidth > nScreenWidth/2 )
1566 nMaxWidth = nScreenWidth/2;
1567
1568 sal_uInt16 gfxExtra = static_cast<sal_uInt16>(std::max( nExtra, tools::Long(7) )); // #107710# increase space between checkmarks/images/text
1569 nImgOrChkPos = static_cast<sal_uInt16>(nExtra);
1570 tools::Long nImgOrChkWidth = 0;
1571 if( aMarkSize.Height() > 0 ) // NWF case
1572 nImgOrChkWidth = aMarkSize.Height() + nExtra;
1573 else // non NWF case
1574 nImgOrChkWidth = nFontHeight/2 + gfxExtra;
1575 nImgOrChkWidth = std::max( nImgOrChkWidth, aMaxImgWidth + gfxExtra );
1576 nTextPos = static_cast<sal_uInt16>(nImgOrChkPos + nImgOrChkWidth);
1577 nTextPos = nTextPos + gfxExtra;
1578
1579 aSz.setWidth( nTextPos + nMaxWidth + nExtra );
1580 aSz.AdjustWidth(4*nExtra ); // a _little_ more ...
1581
1584 }
1585 else
1586 {
1587 nTextPos = static_cast<sal_uInt16>(2*nExtra);
1588 aSz.setHeight( nFontHeight+6 );
1589
1590 // get menubar height from native methods if supported
1592 {
1593 ImplControlValue aVal;
1594 tools::Rectangle aNativeBounds;
1595 tools::Rectangle aNativeContent;
1596 Point tmp( 0, 0 );
1597 tools::Rectangle aCtrlRegion( tmp, Size( 100, 15 ) );
1600 aCtrlRegion,
1602 aVal,
1603 aNativeBounds,
1604 aNativeContent )
1605 )
1606 {
1607 int nNativeHeight = aNativeBounds.GetHeight();
1608 if( nNativeHeight > aSz.Height() )
1609 aSz.setHeight( nNativeHeight );
1610 }
1611 }
1612
1613 // account for the size of the close button, which actually is a toolbox
1614 // due to NWF this is variable
1615 tools::Long nCloseButtonHeight = static_cast<MenuBarWindow*>(pWindow.get())->MinCloseButtonSize().Height();
1616 if (aSz.Height() < nCloseButtonHeight)
1617 aSz.setHeight( nCloseButtonHeight );
1618 }
1619
1620 return aSz;
1621}
1622
1623static void ImplPaintCheckBackground(vcl::RenderContext & rRenderContext, vcl::Window const & rWindow, const tools::Rectangle& i_rRect, bool i_bHighlight)
1624{
1625 bool bNativeOk = false;
1627 {
1628 ImplControlValue aControlValue;
1629 aControlValue.setTristateVal(ButtonValue::On);
1630 tools::Rectangle r = i_rRect;
1631 r.AdjustBottom(1);
1632
1634 r,
1636 aControlValue,
1637 OUString());
1638 }
1639
1640 if (!bNativeOk)
1641 {
1642 const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
1643 Color aColor( i_bHighlight ? rSettings.GetMenuHighlightTextColor() : rSettings.GetHighlightColor() );
1644 RenderTools::DrawSelectionBackground(rRenderContext, rWindow, i_rRect, 0, i_bHighlight, true, false, nullptr, 2, &aColor);
1645 }
1646}
1647
1648static OUString getShortenedString( const OUString& i_rLong, vcl::RenderContext const & rRenderContext, tools::Long i_nMaxWidth )
1649{
1650 sal_Int32 nPos = -1;
1651 OUString aNonMnem(removeMnemonicFromString(i_rLong, nPos));
1652 aNonMnem = rRenderContext.GetEllipsisString( aNonMnem, i_nMaxWidth, DrawTextFlags::CenterEllipsis);
1653 // re-insert mnemonic
1654 if (nPos != -1)
1655 {
1656 if (nPos < aNonMnem.getLength() && i_rLong[nPos+1] == aNonMnem[nPos])
1657 {
1658 OUString aTmp = OUString::Concat(aNonMnem.subView(0, nPos)) + "~" + aNonMnem.subView(nPos);
1659 aNonMnem = aTmp;
1660 }
1661 }
1662 return aNonMnem;
1663}
1664
1665void Menu::ImplPaintMenuTitle(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) const
1666{
1667 // Save previous graphical settings, set new one
1668 rRenderContext.Push(PushFlags::FONT | PushFlags::FILLCOLOR);
1669 Wallpaper aOldBackground = rRenderContext.GetBackground();
1670
1671 Color aBackgroundColor = rRenderContext.GetSettings().GetStyleSettings().GetMenuBarColor();
1672 rRenderContext.SetBackground(Wallpaper(aBackgroundColor));
1673 rRenderContext.SetFillColor(aBackgroundColor);
1674 vcl::Font aFont = rRenderContext.GetFont();
1675 aFont.SetWeight(WEIGHT_BOLD);
1676 rRenderContext.SetFont(aFont);
1677
1678 // Draw background rectangle
1679 tools::Rectangle aBgRect(rRect);
1680 int nOuterSpaceX = ImplGetSVData()->maNWFData.mnMenuFormatBorderX;
1682 aBgRect.setWidth(aBgRect.getOpenWidth() - 2 * SPACE_AROUND_TITLE - 2 * nOuterSpaceX);
1684 rRenderContext.DrawRect(aBgRect);
1685
1686 // Draw the text centered
1687 Point aTextTopLeft(aBgRect.TopLeft());
1688 tools::Rectangle aTextBoundRect;
1689 rRenderContext.GetTextBoundRect( aTextBoundRect, aTitleText );
1690 aTextTopLeft.AdjustX((aBgRect.getOpenWidth() - aTextBoundRect.GetSize().Width()) / 2 );
1691 aTextTopLeft.AdjustY((aBgRect.GetHeight() - aTextBoundRect.GetSize().Height()) / 2
1692 - aTextBoundRect.Top() );
1693 rRenderContext.DrawText(aTextTopLeft, aTitleText, 0, aTitleText.getLength());
1694
1695 // Restore
1696 rRenderContext.Pop();
1697 rRenderContext.SetBackground(aOldBackground);
1698}
1699
1700void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize,
1701 sal_uInt16 nBorder, tools::Long nStartY, MenuItemData const * pThisItemOnly,
1702 bool bHighlighted, bool bLayout, bool bRollover) const
1703{
1704 // for symbols: nFontHeight x nFontHeight
1705 tools::Long nFontHeight = rRenderContext.GetTextHeight();
1706 tools::Long nExtra = nFontHeight / 4;
1707
1708 tools::Long nCheckHeight = 0, nRadioHeight = 0;
1709 ImplGetNativeCheckAndRadioSize(rRenderContext, nCheckHeight, nRadioHeight);
1710
1711 DecorationView aDecoView(&rRenderContext);
1712 const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
1713
1714 Point aTopLeft, aTmpPos;
1715
1716 int nOuterSpaceX = 0;
1717 if (!IsMenuBar())
1718 {
1720 aTopLeft.AdjustX(nOuterSpaceX );
1721 aTopLeft.AdjustY(ImplGetSVData()->maNWFData.mnMenuFormatBorderY );
1722 }
1723
1724 // for the computations, use size of the underlying window, not of RenderContext
1725 Size aOutSz(rSize);
1726
1727 size_t nCount = pItemList->size();
1728 if (bLayout)
1729 mpLayoutData->m_aVisibleItemBoundRects.clear();
1730
1731 // Paint title
1732 if (!pThisItemOnly && !IsMenuBar() && nTitleHeight > 0)
1733 ImplPaintMenuTitle(rRenderContext, tools::Rectangle(aTopLeft, aOutSz));
1734
1735 bool bHiddenItems = false; // are any items on the GUI hidden
1736
1737 for (size_t n = 0; n < nCount; n++)
1738 {
1739 MenuItemData* pData = pItemList->GetDataFromPos( n );
1740 if (ImplIsVisible(n) && (!pThisItemOnly || (pData == pThisItemOnly)))
1741 {
1742 if (pThisItemOnly)
1743 {
1744 if (IsMenuBar())
1745 {
1746 if (!ImplGetSVData()->maNWFData.mbRolloverMenubar)
1747 {
1748 if (bRollover)
1749 rRenderContext.SetTextColor(rSettings.GetMenuBarRolloverTextColor());
1750 else if (bHighlighted)
1751 rRenderContext.SetTextColor(rSettings.GetMenuBarHighlightTextColor());
1752 }
1753 else
1754 {
1755 if (bHighlighted)
1756 rRenderContext.SetTextColor(rSettings.GetMenuBarHighlightTextColor());
1757 else if (bRollover)
1758 rRenderContext.SetTextColor(rSettings.GetMenuBarRolloverTextColor());
1759 }
1760 if (!bRollover && !bHighlighted)
1761 rRenderContext.SetTextColor(rSettings.GetMenuBarTextColor());
1762 }
1763 else if (bHighlighted)
1764 rRenderContext.SetTextColor(rSettings.GetMenuHighlightTextColor());
1765 }
1766
1767 Point aPos(aTopLeft);
1768 aPos.AdjustY(nBorder );
1769 aPos.AdjustY(nStartY );
1770
1771 if (aPos.Y() >= 0)
1772 {
1773 tools::Long nTextOffsetY = (pData->aSz.Height() - nFontHeight) / 2;
1774 if (IsMenuBar())
1775 nTextOffsetY += (aOutSz.Height()-pData->aSz.Height()) / 2;
1779
1780 // submenus without items are not disabled when no items are
1781 // contained. The application itself should check for this!
1782 // Otherwise it could happen entries are disabled due to
1783 // asynchronous loading
1784 if (!pData->bEnabled || !pWindow->IsEnabled())
1785 {
1786 nTextStyle |= DrawTextFlags::Disable;
1787 nSymbolStyle |= DrawSymbolFlags::Disable;
1788 nImageStyle |= DrawImageFlags::Disable;
1789 }
1790
1791 // Separator
1792 if (!bLayout && !IsMenuBar() && (pData->eType == MenuItemType::SEPARATOR))
1793 {
1794 bool bNativeOk = false;
1796 {
1798 if (pData->bEnabled && pWindow->IsEnabled())
1800 if (bHighlighted)
1802 Size aSz(pData->aSz);
1803 aSz.setWidth( aOutSz.Width() - 2*nOuterSpaceX );
1804 tools::Rectangle aItemRect(aPos, aSz);
1805 MenupopupValue aVal(nTextPos - GUTTERBORDER, aItemRect);
1807 aItemRect, nState, aVal, OUString());
1808 }
1809 if (!bNativeOk)
1810 {
1811 aTmpPos.setY( aPos.Y() + ((pData->aSz.Height() - 2) / 2) );
1812 aTmpPos.setX( aPos.X() + 2 + nOuterSpaceX );
1813 rRenderContext.SetLineColor(rSettings.GetShadowColor());
1814 rRenderContext.DrawLine(aTmpPos, Point(aOutSz.Width() - 3 - 2 * nOuterSpaceX, aTmpPos.Y()));
1815 aTmpPos.AdjustY( 1 );
1816 rRenderContext.SetLineColor(rSettings.GetLightColor());
1817 rRenderContext.DrawLine(aTmpPos, Point(aOutSz.Width() - 3 - 2 * nOuterSpaceX, aTmpPos.Y()));
1818 rRenderContext.SetLineColor();
1819 }
1820 }
1821
1822 tools::Rectangle aOuterCheckRect(Point(aPos.X()+nImgOrChkPos, aPos.Y()),
1823 Size(pData->aSz.Height(), pData->aSz.Height()));
1824
1825 // CheckMark
1826 if (!bLayout && !IsMenuBar() && pData->HasCheck())
1827 {
1828 // draw selection transparent marker if checked
1829 // onto that either a checkmark or the item image
1830 // will be painted
1831 // however do not do this if native checks will be painted since
1832 // the selection color too often does not fit the theme's check and/or radio
1833
1834 if( (pData->eType != MenuItemType::IMAGE) && (pData->eType != MenuItemType::STRINGIMAGE))
1835 {
1840 {
1841 ControlPart nPart = ((pData->nBits & MenuItemBits::RADIOCHECK)
1844
1846
1847 if (pData->bChecked)
1849
1850 if (pData->bEnabled && pWindow->IsEnabled())
1852
1853 if (bHighlighted)
1855
1856 tools::Long nCtrlHeight = (pData->nBits & MenuItemBits::RADIOCHECK) ? nCheckHeight : nRadioHeight;
1857 aTmpPos.setX( aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - nCtrlHeight) / 2 );
1858 aTmpPos.setY( aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight) / 2 );
1859
1860 tools::Rectangle aCheckRect(aTmpPos, Size(nCtrlHeight, nCtrlHeight));
1861 Size aSz(pData->aSz);
1862 aSz.setWidth( aOutSz.Width() - 2 * nOuterSpaceX );
1863 tools::Rectangle aItemRect(aPos, aSz);
1864 MenupopupValue aVal(nTextPos - GUTTERBORDER, aItemRect);
1865 rRenderContext.DrawNativeControl(ControlType::MenuPopup, nPart, aCheckRect,
1866 nState, aVal, OUString());
1867 }
1868 else if (pData->bChecked) // by default do nothing for unchecked items
1869 {
1870 ImplPaintCheckBackground(rRenderContext, *pWindow, aOuterCheckRect, pThisItemOnly && bHighlighted);
1871
1873 Size aSymbolSize;
1874 if (pData->nBits & MenuItemBits::RADIOCHECK)
1875 {
1877 aSymbolSize = Size(nFontHeight / 2, nFontHeight / 2);
1878 }
1879 else
1880 {
1882 aSymbolSize = Size((nFontHeight * 25) / 40, nFontHeight / 2);
1883 }
1884 aTmpPos.setX( aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - aSymbolSize.Width()) / 2 );
1885 aTmpPos.setY( aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - aSymbolSize.Height()) / 2 );
1886 tools::Rectangle aRect(aTmpPos, aSymbolSize);
1887 aDecoView.DrawSymbol(aRect, eSymbol, rRenderContext.GetTextColor(), nSymbolStyle);
1888 }
1889 }
1890 }
1891
1892 // Image:
1893 if (!bLayout && !IsMenuBar() && ((pData->eType == MenuItemType::IMAGE) || (pData->eType == MenuItemType::STRINGIMAGE)))
1894 {
1895 // Don't render an image for a check thing
1896 if (pData->bChecked)
1897 ImplPaintCheckBackground(rRenderContext, *pWindow, aOuterCheckRect, pThisItemOnly && bHighlighted);
1898
1899 Image aImage = pData->aImage;
1900
1901 aTmpPos = aOuterCheckRect.TopLeft();
1902 aTmpPos.AdjustX((aOuterCheckRect.GetWidth() - aImage.GetSizePixel().Width()) / 2 );
1903 aTmpPos.AdjustY((aOuterCheckRect.GetHeight() - aImage.GetSizePixel().Height()) / 2 );
1904 rRenderContext.DrawImage(aTmpPos, aImage, nImageStyle);
1905 }
1906
1907 // Text:
1908 if ((pData->eType == MenuItemType::STRING ) || (pData->eType == MenuItemType::STRINGIMAGE))
1909 {
1910 aTmpPos.setX( aPos.X() + nTextPos );
1911 aTmpPos.setY( aPos.Y() );
1912 aTmpPos.AdjustY(nTextOffsetY );
1913 DrawTextFlags nStyle = nTextStyle | DrawTextFlags::Mnemonic;
1914
1915 if (pData->bIsTemporary)
1916 nStyle |= DrawTextFlags::Disable;
1917 std::vector< tools::Rectangle >* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : nullptr;
1918 OUString* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : nullptr;
1919 if (bLayout)
1920 {
1921 mpLayoutData->m_aLineIndices.push_back(mpLayoutData->m_aDisplayText.getLength());
1922 mpLayoutData->m_aLineItemIds.push_back(pData->nId);
1923 }
1924 // #i47946# with NWF painted menus the background is transparent
1925 // since DrawCtrlText can depend on the background (e.g. for
1926 // DrawTextFlags::Disable), temporarily set a background which
1927 // hopefully matches the NWF background since it is read
1928 // from the system style settings
1929 bool bSetTmpBackground = !rRenderContext.IsBackground()
1931 if (bSetTmpBackground)
1932 {
1933 Color aBg = IsMenuBar() ? rRenderContext.GetSettings().GetStyleSettings().GetMenuBarColor()
1934 : rRenderContext.GetSettings().GetStyleSettings().GetMenuColor();
1935 rRenderContext.SetBackground(Wallpaper(aBg));
1936 }
1937 // how much space is there for the text?
1938 tools::Long nMaxItemTextWidth = aOutSz.Width() - aTmpPos.X() - nExtra - nOuterSpaceX;
1939 if (!IsMenuBar() && pData->aAccelKey.GetCode() && !ImplAccelDisabled())
1940 {
1941 OUString aAccText = pData->aAccelKey.GetName();
1942 nMaxItemTextWidth -= rRenderContext.GetTextWidth(aAccText) + 3 * nExtra;
1943 }
1944 if (!IsMenuBar() && pData->pSubMenu)
1945 {
1946 nMaxItemTextWidth -= nFontHeight - nExtra;
1947 }
1948
1949 OUString aItemText(pData->aText);
1950 pData->bHiddenOnGUI = false;
1951
1952 if (IsMenuBar()) // In case of menubar if we are out of bounds we shouldn't paint the item
1953 {
1954 if (nMaxItemTextWidth < rRenderContext.GetTextWidth(aItemText))
1955 {
1956 aItemText = "";
1957 pData->bHiddenOnGUI = true;
1958 bHiddenItems = true;
1959 }
1960 }
1961 else
1962 {
1963 aItemText = getShortenedString(aItemText, rRenderContext, nMaxItemTextWidth);
1964 pData->bHiddenOnGUI = false;
1965 }
1966
1967 const SalLayoutGlyphs* pGlyphs = pData->GetTextGlyphs(&rRenderContext);
1968 if (aItemText != pData->aText)
1969 // Can't use pre-computed glyphs, item text was
1970 // changed.
1971 pGlyphs = nullptr;
1972 rRenderContext.DrawCtrlText(aTmpPos, aItemText, 0, aItemText.getLength(),
1973 nStyle, pVector, pDisplayText, pGlyphs);
1974 if (bSetTmpBackground)
1975 rRenderContext.SetBackground();
1976 }
1977
1978 // Accel
1979 if (!bLayout && !IsMenuBar() && pData->aAccelKey.GetCode() && !ImplAccelDisabled())
1980 {
1981 OUString aAccText = pData->aAccelKey.GetName();
1982 aTmpPos.setX( aOutSz.Width() - rRenderContext.GetTextWidth(aAccText) );
1983 aTmpPos.AdjustX( -(4 * nExtra) );
1984
1985 aTmpPos.AdjustX( -nOuterSpaceX );
1986 aTmpPos.setY( aPos.Y() );
1987 aTmpPos.AdjustY(nTextOffsetY );
1988 rRenderContext.DrawCtrlText(aTmpPos, aAccText, 0, aAccText.getLength(), nTextStyle);
1989 }
1990
1991 // SubMenu?
1992 if (!bLayout && !IsMenuBar() && pData->pSubMenu)
1993 {
1994 bool bNativeOk = false;
1996 {
1998 Size aTmpSz(0, 0);
1999 tools::Long aSpacing = 0;
2000
2001 if (!ImplGetNativeSubmenuArrowSize(rRenderContext, aTmpSz, aSpacing))
2002 {
2003 aTmpSz = Size(nFontHeight, nFontHeight);
2004 aSpacing = nOuterSpaceX;
2005 }
2006
2007 if (pData->bEnabled && pWindow->IsEnabled())
2009 if (bHighlighted)
2011
2012 aTmpPos.setX( aOutSz.Width() - aTmpSz.Width() - aSpacing - nOuterSpaceX );
2013 aTmpPos.setY( aPos.Y() + ( pData->aSz.Height() - aTmpSz.Height() ) / 2 );
2014 aTmpPos.AdjustY(nExtra / 2 );
2015
2016 tools::Rectangle aItemRect(aTmpPos, aTmpSz);
2017 MenupopupValue aVal(nTextPos - GUTTERBORDER, aItemRect);
2019 aItemRect, nState, aVal, OUString());
2020 }
2021 if (!bNativeOk)
2022 {
2023 aTmpPos.setX( aOutSz.Width() - nFontHeight + nExtra - nOuterSpaceX );
2024 aTmpPos.setY( aPos.Y() );
2025 aTmpPos.AdjustY(nExtra/2 );
2026 aTmpPos.AdjustY((pData->aSz.Height() / 2) - (nFontHeight / 4) );
2027 if (pData->nBits & MenuItemBits::POPUPSELECT)
2028 {
2029 rRenderContext.SetTextColor(rSettings.GetMenuTextColor());
2030 Point aTmpPos2(aPos);
2031 aTmpPos2.setX( aOutSz.Width() - nFontHeight - nFontHeight/4 );
2032 aDecoView.DrawFrame(tools::Rectangle(aTmpPos2, Size(nFontHeight + nFontHeight / 4,
2033 pData->aSz.Height())),
2035 }
2036 aDecoView.DrawSymbol(tools::Rectangle(aTmpPos, Size(nFontHeight / 2, nFontHeight / 2)),
2037 SymbolType::SPIN_RIGHT, rRenderContext.GetTextColor(), nSymbolStyle);
2038 }
2039 }
2040
2041 if (pThisItemOnly && bHighlighted)
2042 {
2043 // This restores the normal menu or menu bar text
2044 // color for when it is no longer highlighted.
2045 if (IsMenuBar())
2046 rRenderContext.SetTextColor(rSettings.GetMenuBarTextColor());
2047 else
2048 rRenderContext.SetTextColor(rSettings.GetMenuTextColor());
2049 }
2050 }
2051 if( bLayout )
2052 {
2053 if (!IsMenuBar())
2054 mpLayoutData->m_aVisibleItemBoundRects[ n ] = tools::Rectangle(aTopLeft, Size(aOutSz.Width(), pData->aSz.Height()));
2055 else
2056 mpLayoutData->m_aVisibleItemBoundRects[ n ] = tools::Rectangle(aTopLeft, pData->aSz);
2057 }
2058 }
2059
2060 if (!IsMenuBar())
2061 aTopLeft.AdjustY(pData->aSz.Height() );
2062 else
2063 aTopLeft.AdjustX(pData->aSz.Width() );
2064 }
2065
2066 // draw "more" (">>") indicator if some items have been hidden as they go out of visible area
2067 if (bHiddenItems)
2068 {
2069 sal_Int32 nSize = nFontHeight;
2070 tools::Rectangle aRectangle(Point(aOutSz.Width() - nSize, (aOutSz.Height() / 2) - (nSize / 2)), Size(nSize, nSize));
2071 lclDrawMoreIndicator(rRenderContext, aRectangle);
2072 }
2073}
2074
2076{
2077 Menu* pStart = this;
2078 while ( pStart && pStart->pStartedFrom && ( pStart->pStartedFrom != pStart ) )
2079 pStart = pStart->pStartedFrom;
2080 return pStart;
2081}
2082
2083void Menu::ImplCallHighlight(sal_uInt16 nItem)
2084{
2085 ImplMenuDelData aDelData( this );
2086
2087 nSelectedId = 0;
2088 sSelectedIdent.clear();
2089 MenuItemData* pData = pItemList->GetDataFromPos(nItem);
2090 if (pData)
2091 {
2092 nSelectedId = pData->nId;
2093 sSelectedIdent = pData->sIdent;
2094 }
2096
2097 if( !aDelData.isDeleted() )
2098 {
2099 nSelectedId = 0;
2100 sSelectedIdent.clear();
2101 }
2102}
2103
2104IMPL_LINK_NOARG(Menu, ImplCallSelect, void*, void)
2105{
2106 nEventId = nullptr;
2107 Select();
2108}
2109
2111{
2112 Menu* pSelMenu = nEventId ? this : nullptr;
2113
2114 for ( size_t n = GetItemList()->size(); n && !pSelMenu; )
2115 {
2117
2118 if ( pData->pSubMenu )
2119 pSelMenu = pData->pSubMenu->ImplFindSelectMenu();
2120 }
2121
2122 return pSelMenu;
2123}
2124
2125Menu* Menu::ImplFindMenu( sal_uInt16 nItemId )
2126{
2127 Menu* pSelMenu = nullptr;
2128
2129 for ( size_t n = GetItemList()->size(); n && !pSelMenu; )
2130 {
2132
2133 if( pData->nId == nItemId )
2134 pSelMenu = this;
2135 else if ( pData->pSubMenu )
2136 pSelMenu = pData->pSubMenu->ImplFindMenu( nItemId );
2137 }
2138
2139 return pSelMenu;
2140}
2141
2142void Menu::RemoveDisabledEntries( bool bRemoveEmptyPopups )
2143{
2144 for ( sal_uInt16 n = 0; n < GetItemCount(); n++ )
2145 {
2146 bool bRemove = false;
2147 MenuItemData* pItem = pItemList->GetDataFromPos( n );
2148 if ( pItem->eType == MenuItemType::SEPARATOR )
2149 {
2150 if ( !n || ( GetItemType( n-1 ) == MenuItemType::SEPARATOR ) )
2151 bRemove = true;
2152 }
2153 else
2154 bRemove = !pItem->bEnabled;
2155
2156 if ( pItem->pSubMenu )
2157 {
2159 if ( bRemoveEmptyPopups && !pItem->pSubMenu->GetItemCount() )
2160 bRemove = true;
2161 }
2162
2163 if ( bRemove )
2164 RemoveItem( n-- );
2165 }
2166
2167 if ( GetItemCount() )
2168 {
2169 sal_uInt16 nLast = GetItemCount() - 1;
2170 MenuItemData* pItem = pItemList->GetDataFromPos( nLast );
2171 if ( pItem->eType == MenuItemType::SEPARATOR )
2172 RemoveItem( nLast );
2173 }
2174 mpLayoutData.reset();
2175}
2176
2178{
2179 if ( ImplGetSalMenu() )
2181}
2182
2184{
2185}
2186
2188{
2189 mpLayoutData.reset();
2190}
2191
2193{
2194 if (!(pWindow && pWindow->IsReallyVisible()))
2195 return;
2196
2197 mpLayoutData.reset(new MenuLayoutData);
2198 if (IsMenuBar())
2199 {
2200 ImplPaint(*pWindow->GetOutDev(), pWindow->GetOutputSizePixel(), 0, 0, nullptr, false, true); // FIXME
2201 }
2202 else
2203 {
2204 MenuFloatingWindow* pFloat = static_cast<MenuFloatingWindow*>(pWindow.get());
2206 nullptr, false, true); //FIXME
2207 }
2208}
2209
2211{
2212 return mpSalMenu && mpSalMenu->HasNativeMenuBar() ? mpSalMenu.get() : nullptr;
2213}
2214
2215tools::Rectangle Menu::GetCharacterBounds( sal_uInt16 nItemID, tools::Long nIndex ) const
2216{
2217 tools::Long nItemIndex = -1;
2218 if( ! mpLayoutData )
2220 if( mpLayoutData )
2221 {
2222 for( size_t i = 0; i < mpLayoutData->m_aLineItemIds.size(); i++ )
2223 {
2224 if( mpLayoutData->m_aLineItemIds[i] == nItemID )
2225 {
2226 nItemIndex = mpLayoutData->m_aLineIndices[i];
2227 break;
2228 }
2229 }
2230 }
2231 return (mpLayoutData && nItemIndex != -1) ? mpLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : tools::Rectangle();
2232}
2233
2234tools::Long Menu::GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const
2235{
2236 tools::Long nIndex = -1;
2237 rItemID = 0;
2238 if( ! mpLayoutData )
2240 if( mpLayoutData )
2241 {
2242 nIndex = mpLayoutData->GetIndexForPoint( rPoint );
2243 for( size_t i = 0; i < mpLayoutData->m_aLineIndices.size(); i++ )
2244 {
2245 if( mpLayoutData->m_aLineIndices[i] <= nIndex &&
2246 (i == mpLayoutData->m_aLineIndices.size()-1 || mpLayoutData->m_aLineIndices[i+1] > nIndex) )
2247 {
2248 // make index relative to item
2249 nIndex -= mpLayoutData->m_aLineIndices[i];
2250 rItemID = mpLayoutData->m_aLineItemIds[i];
2251 break;
2252 }
2253 }
2254 }
2255 return nIndex;
2256}
2257
2259{
2260 tools::Rectangle aRet;
2261
2262 if (!mpLayoutData )
2264 if (mpLayoutData)
2265 {
2266 std::map< sal_uInt16, tools::Rectangle >::const_iterator it = mpLayoutData->m_aVisibleItemBoundRects.find( nPos );
2267 if( it != mpLayoutData->m_aVisibleItemBoundRects.end() )
2268 aRet = it->second;
2269 }
2270 return aRet;
2271}
2272
2273void Menu::SetAccessibleName( sal_uInt16 nItemId, const OUString& rStr )
2274{
2275 size_t nPos;
2276 MenuItemData* pData = pItemList->GetData( nItemId, nPos );
2277
2278 if (pData && !rStr.equals(pData->aAccessibleName))
2279 {
2280 pData->aAccessibleName = rStr;
2282 }
2283}
2284
2285OUString Menu::GetAccessibleName( sal_uInt16 nItemId ) const
2286{
2287 MenuItemData* pData = pItemList->GetData( nItemId );
2288
2289 if ( pData )
2290 return pData->aAccessibleName;
2291
2292 return OUString();
2293}
2294
2295void Menu::SetAccessibleDescription( sal_uInt16 nItemId, const OUString& rStr )
2296{
2297 MenuItemData* pData = pItemList->GetData( nItemId );
2298
2299 if ( pData )
2300 pData->aAccessibleDescription = rStr;
2301}
2302
2303OUString Menu::GetAccessibleDescription( sal_uInt16 nItemId ) const
2304{
2305 MenuItemData* pData = pItemList->GetData( nItemId );
2306
2307 if (pData && !pData->aAccessibleDescription.isEmpty())
2308 return pData->aAccessibleDescription;
2309
2310 return GetHelpText(nItemId);
2311}
2312
2314{
2315 Menu* pMenu = const_cast<Menu*>(this);
2316 if( pData && pMenu->ImplGetSalMenu() )
2317 {
2319 }
2320}
2321
2322bool Menu::IsHighlighted( sal_uInt16 nItemPos ) const
2323{
2324 bool bRet = false;
2325
2326 if( pWindow )
2327 {
2328 if (IsMenuBar())
2329 bRet = ( nItemPos == static_cast< MenuBarWindow * > (pWindow.get())->GetHighlightedItem() );
2330 else
2331 bRet = ( nItemPos == static_cast< MenuFloatingWindow * > (pWindow.get())->GetHighlightedItem() );
2332 }
2333
2334 return bRet;
2335}
2336
2337void Menu::HighlightItem( sal_uInt16 nItemPos )
2338{
2339 if ( !pWindow )
2340 return;
2341
2342 if (IsMenuBar())
2343 {
2344 MenuBarWindow* pMenuWin = static_cast< MenuBarWindow* >( pWindow.get() );
2345 pMenuWin->SetAutoPopup( false );
2346 pMenuWin->ChangeHighlightItem( nItemPos, false );
2347 }
2348 else
2349 {
2350 static_cast< MenuFloatingWindow* >( pWindow.get() )->ChangeHighlightItem( nItemPos, false );
2351 }
2352}
2353
2355{
2356 // so far just a dynamic_cast, hopefully to be turned into something saner
2357 // at some stage
2358 MenuBarWindow *pWin = dynamic_cast<MenuBarWindow*>(pWindow.get());
2359 //either there is no window (fdo#87663) or it is a MenuBarWindow
2360 assert(!pWindow || pWin);
2361 return pWin;
2362}
2363
2365 : mbCloseBtnVisible(false),
2366 mbFloatBtnVisible(false),
2367 mbHideBtnVisible(false),
2368 mbDisplayable(true)
2369{
2370 mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(true, this);
2371}
2372
2374 : mbCloseBtnVisible(false),
2375 mbFloatBtnVisible(false),
2376 mbHideBtnVisible(false),
2377 mbDisplayable(true)
2378{
2379 mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(true, this);
2380 *this = rMenu;
2381}
2382
2384{
2385 disposeOnce();
2386}
2387
2389{
2390 ImplDestroy( this, true );
2391 Menu::dispose();
2392}
2393
2395{
2396 MenuBarWindow* pMenuWin = getMenuBarWindow();
2397 if (!pMenuWin)
2398 return;
2399 pMenuWin->PopupClosed(pMenu);
2400}
2401
2403{
2404 pWindow->KeyInput(rEvent);
2405}
2406
2408{
2410}
2411
2412void MenuBar::ShowButtons( bool bClose, bool bFloat, bool bHide )
2413{
2414 if ((bClose != mbCloseBtnVisible) ||
2415 (bFloat != mbFloatBtnVisible) ||
2416 (bHide != mbHideBtnVisible))
2417 {
2418 mbCloseBtnVisible = bClose;
2419 mbFloatBtnVisible = bFloat;
2420 mbHideBtnVisible = bHide;
2421 MenuBarWindow* pMenuWin = getMenuBarWindow();
2422 if (pMenuWin)
2423 pMenuWin->ShowButtons(bClose, bFloat, bHide);
2424 }
2425}
2426
2428{
2429 MenuBarWindow* pMenuWin = getMenuBarWindow();
2430 if (pMenuWin)
2431 pMenuWin->LayoutChanged();
2432}
2433
2434void MenuBar::SetDisplayable( bool bDisplayable )
2435{
2436 if( bDisplayable != mbDisplayable )
2437 {
2438 if ( ImplGetSalMenu() )
2439 ImplGetSalMenu()->ShowMenuBar( bDisplayable );
2440
2441 mbDisplayable = bDisplayable;
2442 LayoutChanged();
2443 }
2444}
2445
2447{
2448 // can't this be a static_cast? is there a real possibility, the pWindow is not the MenuBarWindow or nullptr?
2449 VclPtr<MenuBarWindow> pMenuBarWindow = dynamic_cast<MenuBarWindow*>(pWindow);
2450 if (!pMenuBarWindow)
2451 pMenuBarWindow = VclPtr<MenuBarWindow>::Create(pParent);
2452
2453 pMenu->pStartedFrom = nullptr;
2454 pMenu->pWindow = pMenuBarWindow;
2455 pMenuBarWindow->SetMenu(pMenu);
2456 if (pMenuBarWindow) {
2457 // This is needed at least on macOS to make the JunitTest_toolkit_unoapi_1
2458 // toolkit.AccessibleMenu test pass:
2459 pMenu->ImplCalcSize(pMenuBarWindow);
2460 }
2461
2462 return pMenuBarWindow;
2463}
2464
2465void MenuBar::ImplDestroy( MenuBar* pMenu, bool bDelete )
2466{
2467 vcl::Window *pWindow = pMenu->ImplGetWindow();
2468 if (pWindow && bDelete)
2469 {
2470 MenuBarWindow* pMenuWin = pMenu->getMenuBarWindow();
2471 if (pMenuWin)
2472 pMenuWin->KillActivePopup();
2474 }
2475 pMenu->pWindow = nullptr;
2476 if (pMenu->mpSalMenu) {
2477 pMenu->mpSalMenu->ShowMenuBar(false);
2478 }
2479}
2480
2482{
2483 // No keyboard processing when our menubar is invisible
2484 if (!IsDisplayable())
2485 return false;
2486
2487 // No keyboard processing when system handles the menu.
2488 SalMenu *pNativeMenu = ImplGetSalMenu();
2489 if (pNativeMenu && pNativeMenu->HasNativeMenuBar())
2490 {
2491 // Except when the event is the F6 cycle pane event and we can put our
2492 // focus into it (i.e. the gtk3 menubar case but not the mac/unity case
2493 // where it's not part of the application window)
2494 if (!TaskPaneList::IsCycleKey(rKEvent.GetKeyCode()))
2495 return false;
2496 if (!pNativeMenu->CanGetFocus())
2497 return false;
2498 }
2499
2500 bool bDone = false;
2501 // check for enabled, if this method is called from another window...
2502 vcl::Window* pWin = ImplGetWindow();
2503 if (pWin && pWin->IsEnabled() && pWin->IsInputEnabled() && !pWin->IsInModalMode())
2504 {
2505 MenuBarWindow* pMenuWin = getMenuBarWindow();
2506 bDone = pMenuWin && pMenuWin->HandleKeyEvent(rKEvent, false/*bFromMenu*/);
2507 }
2508 return bDone;
2509}
2510
2511void MenuBar::SelectItem(sal_uInt16 nId)
2512{
2513 if (!pWindow)
2514 return;
2515
2516 pWindow->GrabFocus();
2517 nId = GetItemPos( nId );
2518
2519 MenuBarWindow* pMenuWin = getMenuBarWindow();
2520 if (pMenuWin)
2521 {
2522 // #99705# popup the selected menu
2523 pMenuWin->SetAutoPopup( true );
2524 if (ITEMPOS_INVALID != pMenuWin->GetHighlightedItem())
2525 {
2526 pMenuWin->KillActivePopup();
2527 pMenuWin->ChangeHighlightItem( ITEMPOS_INVALID, false );
2528 }
2529 if (nId != ITEMPOS_INVALID)
2530 pMenuWin->ChangeHighlightItem( nId, false );
2531 }
2532}
2533
2534// handler for native menu selection and command events
2536{
2537 if( pMenu )
2538 {
2539 ImplMenuDelData aDelData( this );
2540
2541 pMenu->pStartedFrom = const_cast<Menu*>(this);
2542 pMenu->bInCallback = true;
2543 pMenu->Activate();
2544
2545 if( !aDelData.isDeleted() )
2546 pMenu->bInCallback = false;
2547 }
2548 return true;
2549}
2550
2552{
2553 if( pMenu )
2554 {
2555 ImplMenuDelData aDelData( this );
2556
2557 pMenu->pStartedFrom = const_cast<Menu*>(this);
2558 pMenu->bInCallback = true;
2559 pMenu->Deactivate();
2560 if( !aDelData.isDeleted() )
2561 pMenu->bInCallback = false;
2562 }
2563 return true;
2564}
2565
2566bool MenuBar::HandleMenuHighlightEvent( Menu *pMenu, sal_uInt16 nHighlightEventId ) const
2567{
2568 if( !pMenu )
2569 pMenu = const_cast<MenuBar*>(this)->ImplFindMenu(nHighlightEventId);
2570 if( pMenu )
2571 {
2572 ImplMenuDelData aDelData( pMenu );
2573
2576
2577 if( !aDelData.isDeleted() )
2578 {
2579 pMenu->mnHighlightedItemPos = pMenu->GetItemPos( nHighlightEventId );
2580 pMenu->nSelectedId = nHighlightEventId;
2581 pMenu->sSelectedIdent = pMenu->GetItemIdent( nHighlightEventId );
2582 pMenu->pStartedFrom = const_cast<MenuBar*>(this);
2583 pMenu->ImplCallHighlight( pMenu->mnHighlightedItemPos );
2584 }
2585 return true;
2586 }
2587 else
2588 return false;
2589}
2590
2591bool Menu::HandleMenuCommandEvent( Menu *pMenu, sal_uInt16 nCommandEventId ) const
2592{
2593 if( !pMenu )
2594 pMenu = const_cast<Menu*>(this)->ImplFindMenu(nCommandEventId);
2595 if( pMenu )
2596 {
2597 pMenu->nSelectedId = nCommandEventId;
2598 pMenu->sSelectedIdent = pMenu->GetItemIdent(nCommandEventId);
2599 pMenu->pStartedFrom = const_cast<Menu*>(this);
2600 pMenu->ImplSelect();
2601 return true;
2602 }
2603 else
2604 return false;
2605}
2606
2607sal_uInt16 MenuBar::AddMenuBarButton( const Image& i_rImage, const Link<MenuBarButtonCallbackArg&,bool>& i_rLink, const OUString& i_rToolTip )
2608{
2609 MenuBarWindow* pMenuWin = getMenuBarWindow();
2610 return pMenuWin ? pMenuWin->AddMenuBarButton(i_rImage, i_rLink, i_rToolTip) : 0;
2611}
2612
2614{
2615 MenuBarWindow* pMenuWin = getMenuBarWindow();
2616 if (!pMenuWin)
2617 return;
2618 pMenuWin->SetMenuBarButtonHighlightHdl(nId, rLink);
2619}
2620
2621void MenuBar::RemoveMenuBarButton( sal_uInt16 nId )
2622{
2623 MenuBarWindow* pMenuWin = getMenuBarWindow();
2624 if (!pMenuWin)
2625 return;
2626 pMenuWin->RemoveMenuBarButton(nId);
2627}
2628
2630{
2631 MenuBarWindow* pMenuWin = getMenuBarWindow();
2632 return pMenuWin ? pMenuWin->GetMenuBarButtonRectPixel(nId) : tools::Rectangle();
2633}
2634
2635bool MenuBar::HandleMenuButtonEvent( sal_uInt16 i_nButtonId )
2636{
2637 MenuBarWindow* pMenuWin = getMenuBarWindow();
2638 return pMenuWin && pMenuWin->HandleMenuButtonEvent(i_nButtonId);
2639}
2640
2642{
2643 MenuBar* pMenuBar = const_cast<MenuBar*>(this);
2644 const SalMenu *pNativeMenu = pMenuBar->ImplGetSalMenu();
2645 int nMenubarHeight;
2646 if (pNativeMenu)
2647 nMenubarHeight = pNativeMenu->GetMenuBarHeight();
2648 else
2649 {
2650 vcl::Window* pMenubarWin = GetWindow();
2651 nMenubarHeight = pMenubarWin ? pMenubarWin->GetOutputSizePixel().Height() : 0;
2652 }
2653 return nMenubarHeight;
2654}
2655
2656// bool PopupMenu::bAnyPopupInExecute = false;
2657
2659 return static_cast<MenuFloatingWindow *>(Menu::ImplGetWindow());
2660}
2661
2663{
2664 mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(false, this);
2665}
2666
2668{
2669 mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(false, this);
2670 *this = rMenu;
2671}
2672
2674{
2675 disposeOnce();
2676}
2677
2679{
2681 PopupMenu *pPopup = dynamic_cast<PopupMenu*>(pMenu);
2682 if (p && pPopup)
2683 p->KillActivePopup(pPopup);
2684}
2685
2686namespace vcl
2687{
2689 {
2690 return PopupMenu::GetActivePopupMenu() != nullptr;
2691 }
2692}
2693
2695{
2696 ImplSVData* pSVData = ImplGetSVData();
2697 return pSVData->maAppData.mpActivePopupMenu;
2698}
2699
2701{
2702 if ( ImplGetWindow() )
2704}
2705
2706void PopupMenu::SelectItem(sal_uInt16 nId)
2707{
2708 if ( !ImplGetWindow() )
2709 return;
2710
2711 if( nId != ITEMPOS_INVALID )
2712 {
2713 size_t nPos = 0;
2715 if (pData && pData->pSubMenu)
2717 else
2719 }
2720 else
2721 {
2723 pFloat->GrabFocus();
2724
2725 for( size_t nPos = 0; nPos < GetItemList()->size(); nPos++ )
2726 {
2728 if( pData->pSubMenu )
2729 {
2730 pFloat->KillActivePopup();
2731 }
2732 }
2733 pFloat->ChangeHighlightItem( ITEMPOS_INVALID, false );
2734 }
2735}
2736
2737void PopupMenu::SetSelectedEntry( sal_uInt16 nId )
2738{
2739 nSelectedId = nId;
2741}
2742
2743sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const Point& rPopupPos )
2744{
2745 return Execute( pExecWindow, tools::Rectangle( rPopupPos, rPopupPos ), PopupMenuFlags::ExecuteDown );
2746}
2747
2749{
2751 if ( nFlags & PopupMenuFlags::ExecuteDown )
2752 nPopupModeFlags = FloatWinPopupFlags::Down;
2753 else if ( nFlags & PopupMenuFlags::ExecuteUp )
2754 nPopupModeFlags = FloatWinPopupFlags::Up;
2755 else if ( nFlags & PopupMenuFlags::ExecuteRight )
2756 nPopupModeFlags = FloatWinPopupFlags::Right;
2757 else
2758 nPopupModeFlags = FloatWinPopupFlags::Down;
2759
2760 if (nFlags & PopupMenuFlags::NoMouseUpClose ) // allow popup menus to stay open on mouse button up
2761 nPopupModeFlags |= FloatWinPopupFlags::NoMouseUpClose; // useful if the menu was opened on mousebutton down (eg toolbox configuration)
2762
2763 return nPopupModeFlags;
2764}
2765
2766sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const tools::Rectangle& rRect, PopupMenuFlags nFlags )
2767{
2768 ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL window!", 0 );
2769 return ImplExecute( pExecWindow, rRect, lcl_TranslateFlags(nFlags), nullptr, false );
2770}
2771
2773{
2774 // is there still Select?
2775 Menu* pSelect = ImplFindSelectMenu();
2776 if (pSelect)
2777 {
2778 // Select should be called prior to leaving execute in a popup menu!
2780 pSelect->nEventId = nullptr;
2781 pSelect->Select();
2782 }
2783}
2784
2786 FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom,
2787 bool& bRealExecute, VclPtr<MenuFloatingWindow>& pWin)
2788{
2789 bRealExecute = false;
2790 const sal_uInt16 nItemCount = GetItemCount();
2791 if (!pSFrom && (vcl::IsInPopupMenuExecute() || !nItemCount))
2792 return false;
2793
2794 mpLayoutData.reset();
2795
2796 ImplSVData* pSVData = ImplGetSVData();
2797
2798 pStartedFrom = pSFrom;
2799 nSelectedId = 0;
2800 sSelectedIdent.clear();
2801 bCanceled = false;
2802
2803 VclPtr<vcl::Window> xFocusId;
2804 if ( !pStartedFrom )
2805 {
2806 pSVData->mpWinData->mbNoDeactivate = true;
2807 xFocusId = Window::SaveFocus();
2808 bRealExecute = true;
2809 }
2810 else
2811 {
2812 // assure that only one menu is open at a time
2813 if (pStartedFrom->IsMenuBar() && pSVData->mpWinData->mpFirstFloat)
2816 }
2817
2818 SAL_WARN_IF( ImplGetWindow(), "vcl", "Win?!" );
2819 rRect.SetPos(pParentWin->OutputToScreenPixel(rRect.TopLeft()));
2820
2822 if (bRealExecute)
2823 nPopupModeFlags |= FloatWinPopupFlags::NewLevel;
2824
2825 bInCallback = true; // set it here, if Activate overridden
2826 Activate();
2827 bInCallback = false;
2828
2829 if (pParentWin->isDisposed())
2830 return false;
2831
2832 if ( bCanceled || bKilled )
2833 return false;
2834
2835 if (!nItemCount)
2836 return false;
2837
2838 // The flag MenuFlags::HideDisabledEntries is inherited.
2839 if ( pSFrom )
2840 {
2843 else
2845 }
2846 else
2847 // #102790# context menus shall never show disabled entries
2849
2850 sal_uInt16 nVisibleEntries = ImplGetVisibleItemCount();
2851 if ( !nVisibleEntries )
2852 {
2853 OUString aTmpEntryText(VclResId(SV_RESID_STRING_NOSELECTIONPOSSIBLE));
2854
2855 MenuItemData* pData = NbcInsertItem(0xFFFF, MenuItemBits::NONE, aTmpEntryText, nullptr, 0xFFFF, OString());
2856 size_t nPos = 0;
2857 pData = pItemList->GetData( pData->nId, nPos );
2858 assert(pData);
2859 if (pData)
2860 {
2861 pData->bIsTemporary = true;
2862 }
2864 }
2865
2867 if (comphelper::LibreOfficeKit::isActive() && get_id() == "editviewspellmenu")
2868 {
2869 VclPtr<vcl::Window> xNotifierParent = pParentWin->GetParentWithLOKNotifier();
2870 assert(xNotifierParent && xNotifierParent->GetLOKNotifier() && "editview menu without LOKNotifier");
2871 pWin->SetLOKNotifier(xNotifierParent->GetLOKNotifier());
2872 }
2873
2874 if( pSVData->maNWFData.mbFlatMenu )
2875 pWin->SetBorderStyle( WindowBorderStyle::NOBORDER );
2876 else
2877 pWin->SetBorderStyle( pWin->GetBorderStyle() | WindowBorderStyle::MENU );
2878 pWindow = pWin;
2879
2880 Size aSz = ImplCalcSize( pWin );
2881
2882 tools::Rectangle aDesktopRect(pWin->GetDesktopRectPixel());
2884 {
2886 if( ! pDeskW )
2887 pDeskW = pWindow;
2888 Point aDesktopTL(pDeskW->OutputToAbsoluteScreenPixel(rRect.TopLeft()));
2891 }
2892
2893 tools::Long nMaxHeight = aDesktopRect.GetHeight();
2894
2895 //rhbz#1021915. If a menu won't fit in the desired location the default
2896 //mode is to place it somewhere it will fit. e.g. above, left, right. For
2897 //some cases, e.g. menubars, it's desirable to limit the options to
2898 //above/below and force the menu to scroll if it won't fit
2899 if (nPopupModeFlags & FloatWinPopupFlags::NoHorzPlacement)
2900 {
2901 vcl::Window* pRef = pWin;
2902 if ( pRef->GetParent() )
2903 pRef = pRef->GetParent();
2904
2907
2908 tools::Long nHeightAbove = devRect.Top() - aDesktopRect.Top();
2909 tools::Long nHeightBelow = aDesktopRect.Bottom() - devRect.Bottom();
2910 nMaxHeight = std::min(nMaxHeight, std::max(nHeightAbove, nHeightBelow));
2911 }
2912
2913 // In certain cases this might be misdetected with a height of 0, leading to menus not being displayed.
2914 // So assume that the available screen size matches at least the system requirements
2915 SAL_WARN_IF(nMaxHeight < 768, "vcl",
2916 "Available height misdetected as " << nMaxHeight
2917 << "px. Setting to 768px instead.");
2918 nMaxHeight = std::max(nMaxHeight, tools::Long(768));
2919
2921 nMaxHeight -= pParentWin->GetSizePixel().Height();
2922 sal_Int32 nLeft, nTop, nRight, nBottom;
2923 pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
2924 nMaxHeight -= nTop+nBottom;
2925 if ( aSz.Height() > nMaxHeight )
2926 {
2927 pWin->EnableScrollMenu( true );
2928 sal_uInt16 nStart = ImplGetFirstVisible();
2929 sal_uInt16 nEntries = ImplCalcVisEntries( nMaxHeight, nStart );
2930 aSz.setHeight( ImplCalcHeight( nEntries ) );
2931 }
2932
2933 pWin->SetFocusId( xFocusId );
2934 pWin->SetOutputSizePixel( aSz );
2935 return true;
2936}
2937
2938bool PopupMenu::Run(const VclPtr<MenuFloatingWindow>& pWin, const bool bRealExecute, const bool bPreSelectFirst,
2939 const FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect)
2940{
2941 SalMenu* pMenu = ImplGetSalMenu();
2942 if (pMenu && bRealExecute && pMenu->ShowNativePopupMenu(pWin, rRect, nPopupModeFlags))
2943 return true;
2944
2945 pWin->StartPopupMode(rRect, nPopupModeFlags);
2946 if (pSFrom)
2947 {
2948 sal_uInt16 aPos;
2949 if (pSFrom->IsMenuBar())
2950 aPos = static_cast<MenuBarWindow *>(pSFrom->pWindow.get())->GetHighlightedItem();
2951 else
2952 aPos = static_cast<MenuFloatingWindow *>(pSFrom->pWindow.get())->GetHighlightedItem();
2953
2954 pWin->SetPosInParent(aPos); // store position to be sent in SUBMENUDEACTIVATE
2956 }
2957
2958 if ( bPreSelectFirst )
2959 {
2960 for (size_t n = 0; n < static_cast<size_t>(GetItemCount()); n++)
2961 {
2962 MenuItemData* pData = pItemList->GetDataFromPos( n );
2963 if ( ( pData->bEnabled
2965 )
2966 && ( pData->eType != MenuItemType::SEPARATOR )
2967 && ImplIsVisible( n )
2968 && ImplIsSelectable( n )
2969 )
2970 {
2971 pWin->ChangeHighlightItem(n, false);
2972 break;
2973 }
2974 }
2975 }
2976
2977 if (bRealExecute)
2978 pWin->Execute();
2979
2980 return false;
2981}
2982
2983void PopupMenu::FinishRun(const VclPtr<MenuFloatingWindow>& pWin, const VclPtr<vcl::Window>& pParentWin, const bool bRealExecute, const bool bIsNativeMenu)
2984{
2985 if (!bRealExecute || pWin->isDisposed())
2986 return;
2987
2988 if (!bIsNativeMenu)
2989 {
2990 VclPtr<vcl::Window> xFocusId = pWin->GetFocusId();
2991 assert(xFocusId == nullptr && "Focus should already be restored by MenuFloatingWindow::End");
2992 pWin->ImplEndPopupMode(FloatWinPopupEndFlags::NONE, xFocusId);
2993
2994 if (nSelectedId) // then clean up .. ( otherwise done by TH )
2995 {
2996 PopupMenu* pSub = pWin->GetActivePopup();
2997 while ( pSub )
2998 {
3000 pSub = pSub->ImplGetFloatingWindow()->GetActivePopup();
3001 }
3002 }
3003 }
3004 else
3005 pWin->StopExecute();
3006
3007 pWin->doShutdown();
3009 ImplClosePopupToolBox(pParentWin);
3011}
3012
3013sal_uInt16 PopupMenu::ImplExecute(const VclPtr<vcl::Window>& pParentWin, const tools::Rectangle& rRect,
3014 FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst)
3015{
3016 // tdf#126054 hold this until after function completes
3017 VclPtr<PopupMenu> xThis(this);
3018 bool bRealExecute = false;
3019 tools::Rectangle aRect(rRect);
3021 if (!PrepareRun(pParentWin, aRect, nPopupModeFlags, pSFrom, bRealExecute, pWin))
3022 return 0;
3023 const bool bNative = Run(pWin, bRealExecute, bPreSelectFirst, nPopupModeFlags, pSFrom, aRect);
3024 FinishRun(pWin, pParentWin, bRealExecute, bNative);
3025 return nSelectedId;
3026}
3027
3028sal_uInt16 PopupMenu::ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible ) const
3029{
3030 nMaxHeight -= 2 * ImplGetFloatingWindow()->GetScrollerHeight();
3031
3032 tools::Long nHeight = 0;
3033 size_t nEntries = pItemList->size();
3034 sal_uInt16 nVisEntries = 0;
3035
3036 if ( pLastVisible )
3037 *pLastVisible = 0;
3038
3039 for ( size_t n = nStartEntry; n < nEntries; n++ )
3040 {
3041 if ( ImplIsVisible( n ) )
3042 {
3043 MenuItemData* pData = pItemList->GetDataFromPos( n );
3044 nHeight += pData->aSz.Height();
3045 if ( nHeight > nMaxHeight )
3046 break;
3047
3048 if ( pLastVisible )
3049 *pLastVisible = n;
3050 nVisEntries++;
3051 }
3052 }
3053 return nVisEntries;
3054}
3055
3056tools::Long PopupMenu::ImplCalcHeight( sal_uInt16 nEntries ) const
3057{
3058 tools::Long nHeight = 0;
3059
3060 sal_uInt16 nFound = 0;
3061 for ( size_t n = 0; ( nFound < nEntries ) && ( n < pItemList->size() ); n++ )
3062 {
3063 if ( ImplIsVisible( static_cast<sal_uInt16>(n) ) )
3064 {
3065 MenuItemData* pData = pItemList->GetDataFromPos( n );
3066 nHeight += pData->aSz.Height();
3067 nFound++;
3068 }
3069 }
3070
3071 nHeight += 2*ImplGetFloatingWindow()->GetScrollerHeight();
3072
3073 return nHeight;
3074}
3075
3076css::uno::Reference<css::awt::XPopupMenu> PopupMenu::CreateMenuInterface()
3077{
3079 if ( pWrapper )
3080 return pWrapper->CreateMenuInterface(this);
3081 return nullptr;
3082}
3083
3085: mpNext( nullptr )
3086, mpMenu( nullptr )
3087{
3088 if( pMenu )
3089 const_cast< Menu* >( pMenu )->ImplAddDel( *this );
3090}
3091
3093{
3094 if( mpMenu )
3095 const_cast< Menu* >( mpMenu.get() )->ImplRemoveDel( *this );
3096}
3097
3098/* 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:815
static SAL_DLLPRIVATE unsigned int GetBestScreen(const tools::Rectangle &)
Get the "best" screen.
Definition: svapp.cxx:1396
static unsigned int GetScreenCount()
Get the number of screens available for the display.
Definition: svapp.cxx:1329
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:761
static bool IsUnifiedDisplay()
Determines if the screens that make up a display are separate or form one large display area.
Definition: svapp.cxx:1335
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:1122
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
Remove user event based on event ID.
Definition: svapp.cxx:1146
static Help * GetHelp()
Gets the application's help.
Definition: svapp.cxx:1471
static tools::Rectangle GetScreenPosSizePixel(unsigned int nScreen)
Get a screen's rectangular area.
Definition: svapp.cxx:1370
bool IsDark() const
void DrawSymbol(const tools::Rectangle &rRect, SymbolType eType, const Color &rColor, DrawSymbolFlags nStyle=DrawSymbolFlags::NONE)
Definition: decoview.cxx:761
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:804
SystemWindow * GetFloatingWindow(const vcl::Window *pWin)
Definition: dockmgr.cxx:371
void EndPopupMode(FloatWinPopupEndFlags nFlags=FloatWinPopupEndFlags::NONE)
Definition: floatwin.cxx:949
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:86
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:413
virtual ~MenuBar() override
Definition: menu.cxx:2383
sal_uInt16 AddMenuBarButton(const Image &, const Link< MenuBarButtonCallbackArg &, bool > &, const OUString &)
Definition: menu.cxx:2607
void LayoutChanged()
Definition: menu.cxx:2427
void ShowButtons(bool bClose, bool bFloat, bool bHide)
Definition: menu.cxx:2412
virtual void ClosePopup(Menu *pMenu) override
Close the 'pStartedFrom' menu window.
Definition: menu.cxx:2394
bool HandleMenuButtonEvent(sal_uInt16 nEventId)
Definition: menu.cxx:2635
SAL_DLLPRIVATE bool ImplHandleKeyEvent(const KeyEvent &rKEvent)
Definition: menu.cxx:2481
tools::Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId)
Definition: menu.cxx:2629
int GetMenuBarHeight() const
Definition: menu.cxx:2641
bool mbFloatBtnVisible
Definition: menu.hxx:411
bool mbHideBtnVisible
Definition: menu.hxx:412
void SetDisplayable(bool bDisplayable)
Definition: menu.cxx:2434
MenuBarWindow * getMenuBarWindow()
Return the MenuBarWindow.
Definition: menu.cxx:2354
MenuBar()
Definition: menu.cxx:2364
virtual void MenuBarKeyInput(const KeyEvent &rEvent) override
Forward the KeyInput call to the MenuBar.
Definition: menu.cxx:2402
bool IsDisplayable() const
Definition: menu.hxx:462
void SetMenuBarButtonHighlightHdl(sal_uInt16 nId, const Link< MenuBarButtonCallbackArg &, bool > &)
Definition: menu.cxx:2613
virtual void dispose() override
Definition: menu.cxx:2388
virtual void SelectItem(sal_uInt16 nId) override
Definition: menu.cxx:2511
static SAL_DLLPRIVATE VclPtr< vcl::Window > ImplCreate(vcl::Window *pParent, vcl::Window *pWindow, MenuBar *pMenu)
Definition: menu.cxx:2446
bool HandleMenuHighlightEvent(Menu *pMenu, sal_uInt16 nEventId) const
Definition: menu.cxx:2566
void ShowCloseButton(bool bShow)
Definition: menu.cxx:2407
bool mbCloseBtnVisible
Definition: menu.hxx:410
static SAL_DLLPRIVATE void ImplDestroy(MenuBar *pMenu, bool bDelete)
Definition: menu.cxx:2465
void RemoveMenuBarButton(sal_uInt16 nId)
Definition: menu.cxx:2621
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:2322
OString GetItemIdent(sal_uInt16 nItemId) const
Definition: menu.cxx:665
SAL_DLLPRIVATE Menu * ImplFindSelectMenu()
Definition: menu.cxx:2110
Menu & operator=(const Menu &rMenu)
Definition: menu.cxx:1145
SAL_DLLPRIVATE void ImplCallEventListeners(VclEventId nEvent, sal_uInt16 nPos)
Definition: menu.cxx:383
bool IsItemChecked(sal_uInt16 nItemId) const
Definition: menu.cxx:883
void SetAccessible(const css::uno::Reference< css::accessibility::XAccessible > &rxAccessible)
Definition: menu.cxx:1311
void SetItemImage(sal_uInt16 nItemId, const Image &rImage)
Definition: menu.cxx:1003
virtual void MenuBarKeyInput(const KeyEvent &rEvent)
Forward the KeyInput call to the MenuBar.
Definition: menu.cxx:2183
bool bKilled
Killed.
Definition: menu.hxx:153
SAL_DLLPRIVATE SalMenu * ImplGetSalMenu()
Definition: menu.hxx:181
void Activate()
Definition: menu.cxx:256
void ShowItem(sal_uInt16 nItemId, bool bVisible=true)
Definition: menu.cxx:939
OString GetHelpId(sal_uInt16 nItemId) const
Definition: menu.cxx:1128
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:398
void InsertSeparator(const OString &rIdent=OString(), sal_uInt16 nPos=MENU_APPEND)
Definition: menu.cxx:472
sal_uInt16 nImgOrChkPos
Definition: menu.hxx:148
SAL_DLLPRIVATE OUString ImplGetHelpText(sal_uInt16 nItemId) const
Definition: menu.cxx:1074
bool HandleMenuActivateEvent(Menu *pMenu) const
Definition: menu.cxx:2535
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 SetItemText(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:961
OUString GetItemText(sal_uInt16 nItemId) const
Definition: menu.cxx:992
SAL_DLLPRIVATE sal_uInt16 ImplGetFirstVisible() const
Definition: menu.cxx:593
sal_uInt16 nTextPos
Definition: menu.hxx:149
virtual bool IsMenuBar() const =0
MenuItemBits GetItemBits(sal_uInt16 nItemId) const
Definition: menu.cxx:686
MenuItemType GetItemType(sal_uInt16 nPos) const
Definition: menu.cxx:655
void InsertItem(sal_uInt16 nItemId, const OUString &rStr, MenuItemBits nItemBits=MenuItemBits::NONE, const OString &rIdent=OString(), sal_uInt16 nPos=MENU_APPEND)
Definition: menu.cxx:432
SAL_DLLPRIVATE Menu * ImplFindMenu(sal_uInt16 nId)
Definition: menu.cxx:2125
SAL_DLLPRIVATE bool ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const
Definition: menu.cxx:1169
css::uno::Reference< css::accessibility::XAccessible > GetAccessible()
Definition: menu.cxx:1279
void HighlightItem(sal_uInt16 nItemPos)
Definition: menu.cxx:2337
void Select()
Definition: menu.cxx:351
VclPtr< Menu > pStartedFrom
Definition: menu.hxx:127
SAL_DLLPRIVATE void ImplAddDel(ImplMenuDelData &rDel)
Definition: menu.cxx:1373
bool HandleMenuDeActivateEvent(Menu *pMenu) const
Definition: menu.cxx:2551
OUString GetItemCommand(sal_uInt16 nItemId) const
Definition: menu.cxx:1038
sal_uInt16 GetCurItemId() const
Definition: menu.hxx:260
OString sSelectedIdent
Definition: menu.hxx:145
SAL_DLLPRIVATE void ImplPaintMenuTitle(vcl::RenderContext &, const tools::Rectangle &rRect) const
Definition: menu.cxx:1665
OUString GetAccessibleName(sal_uInt16 nItemId) const
Definition: menu.cxx:2285
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:2234
SAL_DLLPRIVATE Menu * ImplGetStartMenu()
Definition: menu.cxx:2075
void SetAccessibleName(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:2273
bool IsItemPosVisible(sal_uInt16 nItemPos) const
Definition: menu.cxx:1257
OUString GetAccessibleDescription(sal_uInt16 nItemId) const
Definition: menu.cxx:2303
ImplSVEvent * nEventId
Definition: menu.hxx:141
KeyEvent GetActivationKey(sal_uInt16 nItemId) const
Definition: menu.cxx:788
SAL_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const
Definition: menu.cxx:582
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:778
void RemoveDisabledEntries(bool bRemoveEmptyPopups=false)
Definition: menu.cxx:2142
SAL_DLLPRIVATE void ImplFillLayoutData() const
Definition: menu.cxx:2192
SAL_DLLPRIVATE void ImplKillLayoutData() const
Definition: menu.cxx:2187
SAL_DLLPRIVATE Size ImplCalcSize(vcl::Window *pWin)
Definition: menu.cxx:1403
void CheckItem(sal_uInt16 nItemId, bool bCheck=true)
Definition: menu.cxx:813
static SAL_DLLPRIVATE bool ImplGetNativeSubmenuArrowSize(vcl::RenderContext const &rRenderContext, Size &rArrowSize, tools::Long &rArrowSpacing)
Definition: menu.cxx:1352
SAL_DLLPRIVATE Size ImplGetNativeCheckAndRadioSize(vcl::RenderContext const &rRenderContext, tools::Long &rCheckHeight, tools::Long &rRadioHeight) const
Definition: menu.cxx:1316
void UpdateNativeMenu()
Definition: menu.cxx:2177
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: menu.cxx:623
vcl::Window * GetWindow() const
Definition: menu.hxx:372
void SetAccessibleDescription(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:2295
void SetUserValue(sal_uInt16 nItemId, void *nUserValue, MenuUserDataReleaseFunction aFunc=nullptr)
Definition: menu.cxx:695
void SetAccelKey(sal_uInt16 nItemId, const vcl::KeyCode &rKeyCode)
Definition: menu.cxx:760
SAL_DLLPRIVATE sal_uInt16 ImplGetNextVisible(sal_uInt16 nPos) const
Definition: menu.cxx:613
tools::Rectangle GetCharacterBounds(sal_uInt16 nItemId, tools::Long nIndex) const
Definition: menu.cxx:2215
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:1700
SAL_DLLPRIVATE bool ImplIsSelectable(sal_uInt16 nPos) const
Definition: menu.cxx:1267
SAL_DLLPRIVATE MenuItemData * NbcInsertItem(sal_uInt16 nId, MenuItemBits nBits, const OUString &rStr, Menu *pMenu, size_t nPos, const OString &rIdent)
Definition: menu.cxx:417
bool IsMenuVisible() const
Definition: menu.cxx:1262
void Deactivate()
Definition: menu.cxx:287
Link< Menu *, bool > aDeactivateHdl
Definition: menu.hxx:131
Image GetItemImage(sal_uInt16 nItemId) const
Definition: menu.cxx:1019
void SetTipHelpText(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1102
void SetItemCommand(sal_uInt16 nItemId, const OUString &rCommand)
Definition: menu.cxx:1029
bool HandleMenuCommandEvent(Menu *pMenu, sal_uInt16 nEventId) const
Definition: menu.cxx:2591
PopupMenu * GetPopupMenu(sal_uInt16 nItemId) const
Definition: menu.cxx:750
tools::Rectangle GetBoundingRectangle(sal_uInt16 nItemPos) const
Definition: menu.cxx:2258
void GetSystemMenuData(SystemMenuData *pData) const
Definition: menu.cxx:2313
bool IsItemEnabled(sal_uInt16 nItemId) const
Definition: menu.cxx:928
SAL_DLLPRIVATE sal_uInt16 ImplGetPrevVisible(sal_uInt16 nPos) const
Definition: menu.cxx:603
SAL_DLLPRIVATE bool ImplIsVisible(sal_uInt16 nPos) const
Definition: menu.cxx:1183
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:894
SAL_DLLPRIVATE void ImplCallHighlight(sal_uInt16 nHighlightItem)
Definition: menu.cxx:2083
MenuFlags nMenuFlags
Definition: menu.hxx:143
sal_uInt16 nTitleHeight
Definition: menu.hxx:139
SAL_DLLPRIVATE void ImplRemoveDel(ImplMenuDelData &rDel)
Definition: menu.cxx:1384
void RemoveItem(sal_uInt16 nPos)
Definition: menu.cxx:496
void SetPopupMenu(sal_uInt16 nItemId, PopupMenu *pMenu)
Definition: menu.cxx:713
Menu()
The Menu constructor is protected.
Definition: menu.cxx:158
void * GetUserValue(sal_uInt16 nItemId) const
Definition: menu.cxx:707
void SetItemBits(sal_uInt16 nItemId, MenuItemBits nBits)
Definition: menu.cxx:671
sal_uInt16 nSelectedId
Definition: menu.hxx:144
void SetHelpCommand(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1048
void SetHelpText(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1066
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
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:1097
MenuItemList * GetItemList() const
Definition: menu.hxx:345
OUString GetTipHelpText(sal_uInt16 nItemId) const
Definition: menu.cxx:1110
SAL_DLLPRIVATE SalMenu * GetNativeMenuBar()
Definition: menu.cxx:2210
OUString GetHelpCommand(sal_uInt16 nItemId) const
Definition: menu.cxx:1056
sal_uInt16 GetItemPos(sal_uInt16 nItemId) const
Definition: menu.cxx:644
sal_uInt16 GetItemCount() const
Definition: menu.cxx:577
SAL_DLLPRIVATE vcl::Window * ImplGetWindow() const
Definition: menu.hxx:210
std::unique_ptr< MenuItemList > pItemList
Definition: menu.hxx:126
void SetHelpId(sal_uInt16 nItemId, const OString &rHelpId)
Definition: menu.cxx:1120
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:171
tools::Long GetCtrlTextWidth(const OUString &rStr, const SalLayoutGlyphs *pLayoutCache=nullptr) const
Definition: text.cxx:2325
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:2181
const vcl::Font & GetFont() const
Definition: outdev.hxx:530
float GetDPIScaleFactor() const
Definition: outdev.hxx:397
void SetFont(const vcl::Font &rNewFont)
Definition: outdev/font.cxx:56
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, o3tl::span< const sal_Int32 > pDXArray={}, o3tl::span< const sal_Bool > pKashidaArray={}, const SalLayoutGlyphs *pGlyphs=nullptr) const
Return the exact bounding rectangle of rStr.
Definition: text.cxx:2342
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:161
const Wallpaper & GetBackground() const
Definition: outdev.hxx:524
void SetLineColor()
Definition: line.cxx:37
OUString GetEllipsisString(const OUString &rStr, tools::Long nMaxWidth, DrawTextFlags nStyle=DrawTextFlags::EndEllipsis) const
Definition: text.cxx:2049
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:1004
bool IsBackground() const
Definition: outdev.hxx:527
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:33
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:92
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:289
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
SAL_DLLPRIVATE sal_uInt16 ImplExecute(const VclPtr< vcl::Window > &pParentWin, const tools::Rectangle &rRect, FloatWinPopupFlags nPopupModeFlags, Menu *pSFrom, bool bPreSelectFirst)
Definition: menu.cxx:3013
void SetSelectedEntry(sal_uInt16 nId)
Definition: menu.cxx:2737
virtual void SelectItem(sal_uInt16 nId) override
Definition: menu.cxx:2706
virtual ~PopupMenu() override
Definition: menu.cxx:2673
sal_uInt16 Execute(vcl::Window *pWindow, const Point &rPopupPos)
Definition: menu.cxx:2743
css::uno::Reference< css::awt::XPopupMenu > CreateMenuInterface()
Definition: menu.cxx:3076
SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries(tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16 *pLastVisible=nullptr) const
Definition: menu.cxx:3028
static PopupMenu * GetActivePopupMenu()
Definition: menu.cxx:2694
PopupMenu()
Definition: menu.cxx:2662
virtual void ClosePopup(Menu *pMenu) override
Close the 'pStartedFrom' menu window.
Definition: menu.cxx:2678
void EndExecute()
Definition: menu.cxx:2700
SAL_DLLPRIVATE void FinishRun(const VclPtr< MenuFloatingWindow > &, const VclPtr< vcl::Window > &pParentWin, bool bRealExecute, bool bIsNativeMenu)
Definition: menu.cxx:2983
SAL_DLLPRIVATE void ImplFlushPendingSelect()
Definition: menu.cxx:2772
SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const
Definition: menu.cxx:2658
SAL_DLLPRIVATE bool Run(const VclPtr< MenuFloatingWindow > &, bool bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu *pSFrom, const tools::Rectangle &rRect)
Definition: menu.cxx:2938
SAL_DLLPRIVATE tools::Long ImplCalcHeight(sal_uInt16 nEntries) const
Definition: menu.cxx:3056
SAL_DLLPRIVATE bool PrepareRun(const VclPtr< vcl::Window > &pParentWin, tools::Rectangle &rRect, FloatWinPopupFlags &nPopupModeFlags, Menu *pSFrom, bool &bRealExecute, VclPtr< MenuFloatingWindow > &)
Definition: menu.cxx:2785
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:159
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
Return the height of the native menu bar.
Definition: salvtables.cxx:236
virtual void SetSubMenu(SalMenuItem *pSalMenuItem, SalMenu *pSubMenu, unsigned nPos)=0
virtual void SetItemBits(unsigned, MenuItemBits)
Definition: salmenu.hxx:79
virtual bool CanGetFocus() const
Definition: salmenu.hxx:92
virtual bool ShowNativePopupMenu(FloatingWindow *pWin, const tools::Rectangle &rRect, FloatWinPopupFlags nFlags)
Definition: salvtables.cxx:220
virtual void EnableItem(unsigned nPos, bool bEnable)=0
virtual void RemoveItem(unsigned nPos)=0
virtual void ShowMenuBar(bool)
Change visibility of the native menu bar.
Definition: salvtables.cxx:238
virtual void ShowItem(unsigned nPos, bool bShow)
Definition: salmenu.hxx:96
virtual void InsertItem(SalMenuItem *pSalMenuItem, unsigned nPos)=0
virtual void Update()
Definition: salmenu.hxx:90
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 HasNativeMenuBar()=0
Return true, if the implementation supports a native menu bar (or wants to suppress LO's menu bar,...
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:1592
A construction helper for a temporary VclPtr.
Definition: vclptr.hxx:276
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:266
OUString GetName() const
Definition: keycod.cxx:66
static SettingsConfigItem * get()
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2808
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:1131
vcl::Window * GetParent() const
Definition: window2.cxx:1121
bool IsInputEnabled() const
Definition: window2.cxx:1151
WindowType GetType() const
Definition: window2.cxx:998
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: window.cxx:2426
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
void SetAccessible(const css::uno::Reference< css::accessibility::XAccessible > &)
void GrabFocus()
Definition: window.cxx:2981
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:1807
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:3263
::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:3253
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:3596
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:528
virtual Size GetSizePixel() const
Definition: window.cxx:2404
Size GetOutputSizePixel() const
Definition: window3.cxx:89
bool IsVisible() const
Definition: window2.cxx:1126
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1143
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
Definition: window.cxx:2857
bool IsEnabled() const
Definition: window2.cxx:1146
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:2104
static FloatWinPopupFlags lcl_TranslateFlags(PopupMenuFlags nFlags)
Definition: menu.cxx:2748
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:1648
static void ImplPaintCheckBackground(vcl::RenderContext &rRenderContext, vcl::Window const &rWindow, const tools::Rectangle &i_rRect, bool i_bHighlight)
Definition: menu.cxx:1623
#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
sal_uInt16 nCode
NONE
tools::Long const nBorder
size
int i
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
@ eSymbol
Definition: ppdparser.hxx:42
long Long
bool IsInPopupMenuExecute()
Definition: menu.cxx:2688
sal_Int16 nId
VclPtr< const Menu > mpMenu
Definition: menu.hxx:105
ImplMenuDelData(const Menu *)
Definition: menu.cxx:3084
ImplMenuDelData * mpNext
Definition: menu.hxx:104
bool isDeleted() const
Definition: menu.hxx:110
VclPtr< PopupMenu > mpActivePopupMenu
Definition: svdata.hxx:151
SalInstance * mpDefInst
Definition: svdata.hxx:392
ImplSVNWFData maNWFData
Definition: svdata.hxx:406
ImplSVWinData * mpWinData
Definition: svdata.hxx:403
ImplSVAppData maAppData
Definition: svdata.hxx:400
bool mbFlatMenu
Definition: svdata.hxx:327
int mnMenuFormatBorderY
Definition: svdata.hxx:320
int mnMenuFormatBorderX
Definition: svdata.hxx:319
VclPtr< FloatingWindow > mpFirstFloat
Definition: svdata.hxx:258
bool mbNoDeactivate
Definition: svdata.hxx:270
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:76
DockingManager * ImplGetDockingManager()
Definition: svdata.cxx:315
OUString VclResId(TranslateId aId)
Definition: svdata.cxx:260
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:330
VclEventId
Definition: vclevent.hxx:38
@ MenuSubmenuChanged
@ MenuItemTextChanged
@ MenuAccessibleNameChanged
@ MenuSubmenuActivate
WinBits const WB_SYSTEMWINDOW
Definition: wintypes.hxx:126
WinBits const WB_BORDER
Definition: wintypes.hxx:115