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 
20 #include <tools/diagnose_ex.h>
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>
30 #include <vcl/toolkit/floatwin.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"
45 #include "menufloatingwindow.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>
51 #include <vcl/toolkit/unowrap.hxx>
52 #include <rtl/ustrbuf.hxx>
53 
54 #include <configsettings.hxx>
55 
56 #include <map>
57 #include <string_view>
58 #include <vector>
59 
60 namespace vcl
61 {
62 
64 {
65  std::vector< sal_uInt16 > m_aLineItemIds;
66  std::map< sal_uInt16, tools::Rectangle > m_aVisibleItemBoundRects;
67 };
68 
69 }
70 
71 using namespace vcl;
72 
73 #define EXTRAITEMHEIGHT 4
74 #define SPACE_AROUND_TITLE 4
75 
76 static 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 
91 static void ImplSetMenuItemData( MenuItemData* pData )
92 {
93  // convert data
94  if ( !pData->aImage )
95  pData->eType = MenuItemType::STRING;
96  else if ( pData->aText.isEmpty() )
97  pData->eType = MenuItemType::IMAGE;
98  else
100 }
101 
102 namespace {
103 
104 void 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
116 void lclDrawMoreIndicator(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
117 {
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.getWidth() - width)/2 + 1;
140  tools::Long y = rRect.Top() + (rRect.getHeight() - 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)
371 void 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 
383 void 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 
432 void 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() )
441  nPos = MENU_APPEND;
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 
457 void 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 
464 void 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 
472 void 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() )
480  nPos = MENU_APPEND;
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 
496 void Menu::RemoveItem( sal_uInt16 nPos )
497 {
498  bool bRemove = false;
499 
500  if ( nPos < GetItemCount() )
501  {
502  // update native menu
503  if( ImplGetSalMenu() )
504  ImplGetSalMenu()->RemoveItem( nPos );
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 
523 static void ImplCopyItem( Menu* pThis, const Menu& rMenu, sal_uInt16 nPos, sal_uInt16 nNewPos )
524 {
525  MenuItemType eType = rMenu.GetItemType( nPos );
526 
527  if ( eType == MenuItemType::DONTKNOW )
528  return;
529 
530  if ( eType == MenuItemType::SEPARATOR )
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 
539  MenuItemData* pData = rMenu.GetItemList()->GetData( nId );
540 
541  if (!pData)
542  return;
543 
544  if ( eType == MenuItemType::STRINGIMAGE )
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 
577 sal_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 
593 sal_uInt16 Menu::ImplGetFirstVisible() const
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 
603 sal_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 
613 sal_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 
623 sal_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 
633 sal_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 
644 sal_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 
655 MenuItemType Menu::GetItemType( sal_uInt16 nPos ) const
656 {
657  MenuItemData* pData = pItemList->GetDataFromPos( nPos );
658 
659  if ( pData )
660  return pData->eType;
661  else
662  return MenuItemType::DONTKNOW;
663 }
664 
665 OString Menu::GetItemIdent(sal_uInt16 nId) const
666 {
667  const MenuItemData* pData = pItemList->GetData(nId);
668  return pData ? pData->sIdent : OString();
669 }
670 
671 void 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())
682  ImplGetSalMenu()->SetItemBits(nPos, nBits);
683  }
684 }
685 
686 MenuItemBits 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 
695 void 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 
707 void* Menu::GetUserValue( sal_uInt16 nItemId ) const
708 {
709  MenuItemData* pData = pItemList->GetData( nItemId );
710  return pData ? pData->nUserValue : nullptr;
711 }
712 
713 void 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 
750 PopupMenu* 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 
760 void 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 
778 KeyCode 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 
788 KeyEvent 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 
813 void 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) &&
823  (pData->nBits & MenuItemBits::RADIOCHECK) )
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 
878 void Menu::CheckItem( std::string_view rIdent , bool bCheck )
879 {
880  CheckItem( GetItemId( rIdent ), bCheck );
881 }
882 
883 bool 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 
894 void 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 
928 bool 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 
939 void 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() )
958  ImplGetSalMenu()->ShowItem( nPos, bVisible );
959 }
960 
961 void 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();
975  ImplSetMenuItemData( pData );
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 
992 OUString 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 
1003 void 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;
1012  ImplSetMenuItemData( pData );
1013 
1014  // update native menu
1015  if( ImplGetSalMenu() && pData->pSalMenuItem )
1016  ImplGetSalMenu()->SetItemImage( nPos, pData->pSalMenuItem.get(), rImage );
1017 }
1018 
1019 Image 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 
1029 void 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 
1038 OUString 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 
1048 void 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 
1056 OUString 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 
1066 void 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 
1074 OUString 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 
1097 OUString Menu::GetHelpText( sal_uInt16 nItemId ) const
1098 {
1099  return ImplGetHelpText( nItemId );
1100 }
1101 
1102 void 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 
1110 OUString 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 
1120 void 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 
1128 OString 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 
1145 Menu& 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
1169 bool 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 
1183 bool 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
1237  if (bVisible && !IsMenuBar() && (nMenuFlags & MenuFlags::HideDisabledEntries) &&
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 
1257 bool Menu::IsItemPosVisible( sal_uInt16 nItemPos ) const
1258 {
1259  return IsMenuVisible() && ImplIsVisible( nItemPos );
1260 }
1261 
1263 {
1264  return pWindow && pWindow->IsReallyVisible();
1265 }
1266 
1267 bool 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 
1279 css::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 
1311 void Menu::SetAccessible(const css::uno::Reference<css::accessibility::XAccessible>& rxAccessible )
1312 {
1313  mxAccessible = rxAccessible;
1314 }
1315 
1316 Size 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 
1352 bool 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 ;
1548  aSz.AdjustHeight(nTitleHeight );
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.nDisplayScreenNumber;
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 
1582  aSz.AdjustWidth(2*ImplGetSVData()->maNWFData.mnMenuFormatBorderX );
1583  aSz.AdjustHeight(2*ImplGetSVData()->maNWFData.mnMenuFormatBorderY );
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 
1623 static 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 
1633  bNativeOk = rRenderContext.DrawNativeControl(ControlType::Toolbar, ControlPart::Button,
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 
1648 static OUString getShortenedString( const OUString& i_rLong, vcl::RenderContext const & rRenderContext, tools::Long i_nMaxWidth )
1649 {
1650  sal_Int32 nPos = -1;
1651  OUString aNonMnem(OutputDevice::GetNonMnemonicString(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 
1665 void 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.getWidth() - 2 * SPACE_AROUND_TITLE - 2 * nOuterSpaceX);
1683  aBgRect.setHeight(nTitleHeight - 2 * SPACE_AROUND_TITLE);
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.getWidth() - 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 
1700 void 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  {
1719  nOuterSpaceX = ImplGetSVData()->maNWFData.mnMenuFormatBorderX;
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;
1776  DrawTextFlags nTextStyle = DrawTextFlags::NONE;
1777  DrawSymbolFlags nSymbolStyle = DrawSymbolFlags::NONE;
1778  DrawImageFlags nImageStyle = DrawImageFlags::NONE;
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())
1799  nState |= ControlState::ENABLED;
1800  if (bHighlighted)
1801  nState |= ControlState::SELECTED;
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  {
1837  (pData->nBits & MenuItemBits::RADIOCHECK)
1840  {
1841  ControlPart nPart = ((pData->nBits & MenuItemBits::RADIOCHECK)
1842  ? ControlPart::MenuItemRadioMark
1844 
1846 
1847  if (pData->bChecked)
1848  nState |= ControlState::PRESSED;
1849 
1850  if (pData->bEnabled && pWindow->IsEnabled())
1851  nState |= ControlState::ENABLED;
1852 
1853  if (bHighlighted)
1854  nState |= ControlState::SELECTED;
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  {
1876  eSymbol = SymbolType::RADIOCHECKMARK;
1877  aSymbolSize = Size(nFontHeight / 2, nFontHeight / 2);
1878  }
1879  else
1880  {
1881  eSymbol = SymbolType::CHECKMARK;
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())
2008  nState |= ControlState::ENABLED;
2009  if (bHighlighted)
2010  nState |= ControlState::SELECTED;
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 
2083 void 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 
2104 IMPL_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 
2125 Menu* 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 
2142 void 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  {
2158  pItem->pSubMenu->RemoveDisabledEntries();
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() )
2180  ImplGetSalMenu()->Update();
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 
2210 tools::Rectangle Menu::GetCharacterBounds( sal_uInt16 nItemID, tools::Long nIndex ) const
2211 {
2212  tools::Long nItemIndex = -1;
2213  if( ! mpLayoutData )
2215  if( mpLayoutData )
2216  {
2217  for( size_t i = 0; i < mpLayoutData->m_aLineItemIds.size(); i++ )
2218  {
2219  if( mpLayoutData->m_aLineItemIds[i] == nItemID )
2220  {
2221  nItemIndex = mpLayoutData->m_aLineIndices[i];
2222  break;
2223  }
2224  }
2225  }
2226  return (mpLayoutData && nItemIndex != -1) ? mpLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : tools::Rectangle();
2227 }
2228 
2229 tools::Long Menu::GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const
2230 {
2231  tools::Long nIndex = -1;
2232  rItemID = 0;
2233  if( ! mpLayoutData )
2235  if( mpLayoutData )
2236  {
2237  nIndex = mpLayoutData->GetIndexForPoint( rPoint );
2238  for( size_t i = 0; i < mpLayoutData->m_aLineIndices.size(); i++ )
2239  {
2240  if( mpLayoutData->m_aLineIndices[i] <= nIndex &&
2241  (i == mpLayoutData->m_aLineIndices.size()-1 || mpLayoutData->m_aLineIndices[i+1] > nIndex) )
2242  {
2243  // make index relative to item
2244  nIndex -= mpLayoutData->m_aLineIndices[i];
2245  rItemID = mpLayoutData->m_aLineItemIds[i];
2246  break;
2247  }
2248  }
2249  }
2250  return nIndex;
2251 }
2252 
2254 {
2255  tools::Rectangle aRet;
2256 
2257  if (!mpLayoutData )
2259  if (mpLayoutData)
2260  {
2261  std::map< sal_uInt16, tools::Rectangle >::const_iterator it = mpLayoutData->m_aVisibleItemBoundRects.find( nPos );
2262  if( it != mpLayoutData->m_aVisibleItemBoundRects.end() )
2263  aRet = it->second;
2264  }
2265  return aRet;
2266 }
2267 
2268 void Menu::SetAccessibleName( sal_uInt16 nItemId, const OUString& rStr )
2269 {
2270  size_t nPos;
2271  MenuItemData* pData = pItemList->GetData( nItemId, nPos );
2272 
2273  if (pData && !rStr.equals(pData->aAccessibleName))
2274  {
2275  pData->aAccessibleName = rStr;
2277  }
2278 }
2279 
2280 OUString Menu::GetAccessibleName( sal_uInt16 nItemId ) const
2281 {
2282  MenuItemData* pData = pItemList->GetData( nItemId );
2283 
2284  if ( pData )
2285  return pData->aAccessibleName;
2286 
2287  return OUString();
2288 }
2289 
2290 void Menu::SetAccessibleDescription( sal_uInt16 nItemId, const OUString& rStr )
2291 {
2292  MenuItemData* pData = pItemList->GetData( nItemId );
2293 
2294  if ( pData )
2295  pData->aAccessibleDescription = rStr;
2296 }
2297 
2298 OUString Menu::GetAccessibleDescription( sal_uInt16 nItemId ) const
2299 {
2300  MenuItemData* pData = pItemList->GetData( nItemId );
2301 
2302  if (pData && !pData->aAccessibleDescription.isEmpty())
2303  return pData->aAccessibleDescription;
2304 
2305  return GetHelpText(nItemId);
2306 }
2307 
2309 {
2310  Menu* pMenu = const_cast<Menu*>(this);
2311  if( pData && pMenu->ImplGetSalMenu() )
2312  {
2313  pMenu->ImplGetSalMenu()->GetSystemMenuData( pData );
2314  }
2315 }
2316 
2317 bool Menu::IsHighlighted( sal_uInt16 nItemPos ) const
2318 {
2319  bool bRet = false;
2320 
2321  if( pWindow )
2322  {
2323  if (IsMenuBar())
2324  bRet = ( nItemPos == static_cast< MenuBarWindow * > (pWindow.get())->GetHighlightedItem() );
2325  else
2326  bRet = ( nItemPos == static_cast< MenuFloatingWindow * > (pWindow.get())->GetHighlightedItem() );
2327  }
2328 
2329  return bRet;
2330 }
2331 
2332 void Menu::HighlightItem( sal_uInt16 nItemPos )
2333 {
2334  if ( !pWindow )
2335  return;
2336 
2337  if (IsMenuBar())
2338  {
2339  MenuBarWindow* pMenuWin = static_cast< MenuBarWindow* >( pWindow.get() );
2340  pMenuWin->SetAutoPopup( false );
2341  pMenuWin->ChangeHighlightItem( nItemPos, false );
2342  }
2343  else
2344  {
2345  static_cast< MenuFloatingWindow* >( pWindow.get() )->ChangeHighlightItem( nItemPos, false );
2346  }
2347 }
2348 
2350 {
2351  // so far just a dynamic_cast, hopefully to be turned into something saner
2352  // at some stage
2353  MenuBarWindow *pWin = dynamic_cast<MenuBarWindow*>(pWindow.get());
2354  //either there is no window (fdo#87663) or it is a MenuBarWindow
2355  assert(!pWindow || pWin);
2356  return pWin;
2357 }
2358 
2360  : mbCloseBtnVisible(false),
2361  mbFloatBtnVisible(false),
2362  mbHideBtnVisible(false),
2363  mbDisplayable(true)
2364 {
2365  mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(true, this);
2366 }
2367 
2368 MenuBar::MenuBar( const MenuBar& rMenu )
2369  : mbCloseBtnVisible(false),
2370  mbFloatBtnVisible(false),
2371  mbHideBtnVisible(false),
2372  mbDisplayable(true)
2373 {
2374  mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(true, this);
2375  *this = rMenu;
2376 }
2377 
2379 {
2380  disposeOnce();
2381 }
2382 
2384 {
2385  ImplDestroy( this, true );
2386  Menu::dispose();
2387 }
2388 
2390 {
2391  MenuBarWindow* pMenuWin = getMenuBarWindow();
2392  if (!pMenuWin)
2393  return;
2394  pMenuWin->PopupClosed(pMenu);
2395 }
2396 
2398 {
2399  pWindow->KeyInput(rEvent);
2400 }
2401 
2403 {
2405 }
2406 
2407 void MenuBar::ShowButtons( bool bClose, bool bFloat, bool bHide )
2408 {
2409  if ((bClose != mbCloseBtnVisible) ||
2410  (bFloat != mbFloatBtnVisible) ||
2411  (bHide != mbHideBtnVisible))
2412  {
2413  mbCloseBtnVisible = bClose;
2414  mbFloatBtnVisible = bFloat;
2415  mbHideBtnVisible = bHide;
2416  MenuBarWindow* pMenuWin = getMenuBarWindow();
2417  if (pMenuWin)
2418  pMenuWin->ShowButtons(bClose, bFloat, bHide);
2419  }
2420 }
2421 
2423 {
2424  MenuBarWindow* pMenuWin = getMenuBarWindow();
2425  if (pMenuWin)
2426  pMenuWin->LayoutChanged();
2427 }
2428 
2429 void MenuBar::SetDisplayable( bool bDisplayable )
2430 {
2431  if( bDisplayable != mbDisplayable )
2432  {
2433  if ( ImplGetSalMenu() )
2434  ImplGetSalMenu()->ShowMenuBar( bDisplayable );
2435 
2436  mbDisplayable = bDisplayable;
2437  LayoutChanged();
2438  }
2439 }
2440 
2442 {
2443  VclPtr<MenuBarWindow> pMenuBarWindow = dynamic_cast<MenuBarWindow*>(pWindow);
2444  if (!pMenuBarWindow)
2445  {
2446  pWindow = pMenuBarWindow = VclPtr<MenuBarWindow>::Create( pParent );
2447  }
2448 
2449  pMenu->pStartedFrom = nullptr;
2450  pMenu->pWindow = pWindow;
2451  pMenuBarWindow->SetMenu(pMenu);
2452  tools::Long nHeight = pWindow ? pMenu->ImplCalcSize(pWindow).Height() : 0;
2453 
2454  // depending on the native implementation or the displayable flag
2455  // the menubar windows is suppressed (ie, height=0)
2456  if (!pMenu->IsDisplayable() || (pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar()))
2457  {
2458  nHeight = 0;
2459  }
2460 
2461  pMenuBarWindow->SetHeight(nHeight);
2462  return pWindow;
2463 }
2464 
2465 void 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();
2473  pWindow->disposeOnce();
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->VisibleMenuBar())
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 
2511 void 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 
2566 bool 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 
2591 bool 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 
2607 sal_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 
2621 void 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 
2635 bool 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 
2686 namespace 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 
2706 void PopupMenu::SelectItem(sal_uInt16 nId)
2707 {
2708  if ( !ImplGetWindow() )
2709  return;
2710 
2711  if( nId != ITEMPOS_INVALID )
2712  {
2713  size_t nPos = 0;
2714  MenuItemData* pData = GetItemList()->GetData( nId, nPos );
2715  if (pData && pData->pSubMenu)
2716  ImplGetFloatingWindow()->ChangeHighlightItem( nPos, true );
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 
2737 void PopupMenu::SetSelectedEntry( sal_uInt16 nId )
2738 {
2739  nSelectedId = nId;
2741 }
2742 
2743 sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const Point& rPopupPos )
2744 {
2745  return Execute( pExecWindow, tools::Rectangle( rPopupPos, rPopupPos ), PopupMenuFlags::ExecuteDown );
2746 }
2747 
2748 sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const tools::Rectangle& rRect, PopupMenuFlags nFlags )
2749 {
2750  ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL window!", 0 );
2751 
2752  FloatWinPopupFlags nPopupModeFlags = FloatWinPopupFlags::NONE;
2753  if ( nFlags & PopupMenuFlags::ExecuteDown )
2754  nPopupModeFlags = FloatWinPopupFlags::Down;
2755  else if ( nFlags & PopupMenuFlags::ExecuteUp )
2756  nPopupModeFlags = FloatWinPopupFlags::Up;
2757  else if ( nFlags & PopupMenuFlags::ExecuteRight )
2758  nPopupModeFlags = FloatWinPopupFlags::Right;
2759  else
2760  nPopupModeFlags = FloatWinPopupFlags::Down;
2761 
2762  if (nFlags & PopupMenuFlags::NoMouseUpClose ) // allow popup menus to stay open on mouse button up
2763  nPopupModeFlags |= FloatWinPopupFlags::NoMouseUpClose; // useful if the menu was opened on mousebutton down (eg toolbox configuration)
2764 
2765  return ImplExecute( pExecWindow, rRect, nPopupModeFlags, nullptr, false );
2766 }
2767 
2769 {
2770  // is there still Select?
2771  Menu* pSelect = ImplFindSelectMenu();
2772  if (pSelect)
2773  {
2774  // Select should be called prior to leaving execute in a popup menu!
2776  pSelect->nEventId = nullptr;
2777  pSelect->Select();
2778  }
2779 }
2780 
2781 sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst )
2782 {
2783  if ( !pSFrom && ( vcl::IsInPopupMenuExecute() || !GetItemCount() ) )
2784  return 0;
2785 
2786  mpLayoutData.reset();
2787 
2788  ImplSVData* pSVData = ImplGetSVData();
2789 
2790  pStartedFrom = pSFrom;
2791  nSelectedId = 0;
2792  sSelectedIdent.clear();
2793  bCanceled = false;
2794 
2795  VclPtr<vcl::Window> xFocusId;
2796  bool bRealExecute = false;
2797  if ( !pStartedFrom )
2798  {
2799  pSVData->mpWinData->mbNoDeactivate = true;
2800  xFocusId = Window::SaveFocus();
2801  bRealExecute = true;
2802  }
2803  else
2804  {
2805  // assure that only one menu is open at a time
2806  if (pStartedFrom->IsMenuBar() && pSVData->mpWinData->mpFirstFloat)
2809  }
2810 
2811  SAL_WARN_IF( ImplGetWindow(), "vcl", "Win?!" );
2812  tools::Rectangle aRect( rRect );
2813  aRect.SetPos( pW->OutputToScreenPixel( aRect.TopLeft() ) );
2814 
2815  if (bRealExecute)
2816  nPopupModeFlags |= FloatWinPopupFlags::NewLevel;
2818 
2819  bInCallback = true; // set it here, if Activate overridden
2820  Activate();
2821  bInCallback = false;
2822 
2823  if ( pW->isDisposed() )
2824  return 0; // Error
2825 
2826  if ( bCanceled || bKilled )
2827  return 0;
2828 
2829  if ( !GetItemCount() )
2830  return 0;
2831 
2832  // The flag MenuFlags::HideDisabledEntries is inherited.
2833  if ( pSFrom )
2834  {
2837  else
2839  }
2840  else
2841  // #102790# context menus shall never show disabled entries
2843 
2844  sal_uInt16 nVisibleEntries = ImplGetVisibleItemCount();
2845  if ( !nVisibleEntries )
2846  {
2847  OUString aTmpEntryText(VclResId(SV_RESID_STRING_NOSELECTIONPOSSIBLE));
2848 
2849  MenuItemData* pData = NbcInsertItem(0xFFFF, MenuItemBits::NONE, aTmpEntryText, nullptr, 0xFFFF, OString());
2850  size_t nPos = 0;
2851  pData = pItemList->GetData( pData->nId, nPos );
2852  assert(pData);
2853  if (pData)
2854  {
2855  pData->bIsTemporary = true;
2856  }
2858  }
2859 
2861  if (comphelper::LibreOfficeKit::isActive() && get_id() == "editviewspellmenu")
2862  {
2863  VclPtr<vcl::Window> xNotifierParent = pW->GetParentWithLOKNotifier();
2864  assert(xNotifierParent && xNotifierParent->GetLOKNotifier() && "editview menu without LOKNotifier");
2865  pWin->SetLOKNotifier(xNotifierParent->GetLOKNotifier());
2866  }
2867 
2868  if( pSVData->maNWFData.mbFlatMenu )
2870  else
2872  pWindow = pWin;
2873 
2874  Size aSz = ImplCalcSize( pWin );
2875 
2876  tools::Rectangle aDesktopRect(pWin->GetDesktopRectPixel());
2878  {
2880  if( ! pDeskW )
2881  pDeskW = pWindow;
2882  Point aDesktopTL( pDeskW->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) );
2883  aDesktopRect = Application::GetScreenPosSizePixel(
2884  Application::GetBestScreen( tools::Rectangle( aDesktopTL, aRect.GetSize() ) ));
2885  }
2886 
2887  tools::Long nMaxHeight = aDesktopRect.GetHeight();
2888 
2889  //rhbz#1021915. If a menu won't fit in the desired location the default
2890  //mode is to place it somewhere it will fit. e.g. above, left, right. For
2891  //some cases, e.g. menubars, it's desirable to limit the options to
2892  //above/below and force the menu to scroll if it won't fit
2893  if (nPopupModeFlags & FloatWinPopupFlags::NoHorzPlacement)
2894  {
2895  vcl::Window* pRef = pWin;
2896  if ( pRef->GetParent() )
2897  pRef = pRef->GetParent();
2898 
2899  tools::Rectangle devRect( pRef->OutputToAbsoluteScreenPixel( aRect.TopLeft() ),
2900  pRef->OutputToAbsoluteScreenPixel( aRect.BottomRight() ) );
2901 
2902  tools::Long nHeightAbove = devRect.Top() - aDesktopRect.Top();
2903  tools::Long nHeightBelow = aDesktopRect.Bottom() - devRect.Bottom();
2904  nMaxHeight = std::min(nMaxHeight, std::max(nHeightAbove, nHeightBelow));
2905  }
2906 
2907  // In certain cases this might be misdetected with a height of 0, leading to menus not being displayed.
2908  // So assume that the available screen size matches at least the system requirements
2909  SAL_WARN_IF(nMaxHeight < 768, "vcl",
2910  "Available height misdetected as " << nMaxHeight
2911  << "px. Setting to 768px instead.");
2912  nMaxHeight = std::max(nMaxHeight, tools::Long(768));
2913 
2915  nMaxHeight -= pW->GetSizePixel().Height();
2916  sal_Int32 nLeft, nTop, nRight, nBottom;
2917  pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
2918  nMaxHeight -= nTop+nBottom;
2919  if ( aSz.Height() > nMaxHeight )
2920  {
2921  pWin->EnableScrollMenu( true );
2922  sal_uInt16 nStart = ImplGetFirstVisible();
2923  sal_uInt16 nEntries = ImplCalcVisEntries( nMaxHeight, nStart );
2924  aSz.setHeight( ImplCalcHeight( nEntries ) );
2925  }
2926 
2927  // tdf#126054 hold this until after function completes
2928  VclPtr<PopupMenu> xThis(this);
2929 
2930  pWin->SetFocusId( xFocusId );
2931  pWin->SetOutputSizePixel( aSz );
2932  if ( GetItemCount() )
2933  {
2934  SalMenu* pMenu = ImplGetSalMenu();
2935  if( pMenu && bRealExecute && pMenu->ShowNativePopupMenu( pWin, aRect, nPopupModeFlags | FloatWinPopupFlags::GrabFocus ) )
2936  {
2937  pWin->StopExecute();
2938  pWin->doShutdown();
2940  ImplClosePopupToolBox(pW);
2942  return nSelectedId;
2943  }
2944  else
2945  {
2946  pWin->StartPopupMode( aRect, nPopupModeFlags | FloatWinPopupFlags::GrabFocus );
2947  }
2948  if( pSFrom )
2949  {
2950  sal_uInt16 aPos;
2951  if (pSFrom->IsMenuBar())
2952  aPos = static_cast<MenuBarWindow *>(pSFrom->pWindow.get())->GetHighlightedItem();
2953  else
2954  aPos = static_cast<MenuFloatingWindow *>(pSFrom->pWindow.get())->GetHighlightedItem();
2955 
2956  pWin->SetPosInParent( aPos ); // store position to be sent in SUBMENUDEACTIVATE
2958  }
2959  }
2960  if ( bPreSelectFirst )
2961  {
2962  size_t nCount = pItemList->size();
2963  for ( size_t n = 0; n < nCount; n++ )
2964  {
2965  MenuItemData* pData = pItemList->GetDataFromPos( n );
2966  if ( ( pData->bEnabled
2968  )
2969  && ( pData->eType != MenuItemType::SEPARATOR )
2970  && ImplIsVisible( n )
2971  && ImplIsSelectable( n )
2972  )
2973  {
2974  pWin->ChangeHighlightItem( n, false );
2975  break;
2976  }
2977  }
2978  }
2979  if ( bRealExecute )
2980  {
2981  pWin->Execute();
2982  if (pWin->isDisposed())
2983  return 0;
2984 
2985  xFocusId = pWin->GetFocusId();
2986  assert(xFocusId == nullptr && "Focus should already be restored by MenuFloatingWindow::End");
2988 
2989  if ( nSelectedId ) // then clean up .. ( otherwise done by TH )
2990  {
2991  PopupMenu* pSub = pWin->GetActivePopup();
2992  while ( pSub )
2993  {
2995  pSub = pSub->ImplGetFloatingWindow()->GetActivePopup();
2996  }
2997  }
2998  pWin->doShutdown();
3000  ImplClosePopupToolBox(pW);
3002  }
3003 
3004  return bRealExecute ? nSelectedId : 0;
3005 }
3006 
3007 sal_uInt16 PopupMenu::ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible ) const
3008 {
3009  nMaxHeight -= 2 * ImplGetFloatingWindow()->GetScrollerHeight();
3010 
3011  tools::Long nHeight = 0;
3012  size_t nEntries = pItemList->size();
3013  sal_uInt16 nVisEntries = 0;
3014 
3015  if ( pLastVisible )
3016  *pLastVisible = 0;
3017 
3018  for ( size_t n = nStartEntry; n < nEntries; n++ )
3019  {
3020  if ( ImplIsVisible( n ) )
3021  {
3022  MenuItemData* pData = pItemList->GetDataFromPos( n );
3023  nHeight += pData->aSz.Height();
3024  if ( nHeight > nMaxHeight )
3025  break;
3026 
3027  if ( pLastVisible )
3028  *pLastVisible = n;
3029  nVisEntries++;
3030  }
3031  }
3032  return nVisEntries;
3033 }
3034 
3035 tools::Long PopupMenu::ImplCalcHeight( sal_uInt16 nEntries ) const
3036 {
3037  tools::Long nHeight = 0;
3038 
3039  sal_uInt16 nFound = 0;
3040  for ( size_t n = 0; ( nFound < nEntries ) && ( n < pItemList->size() ); n++ )
3041  {
3042  if ( ImplIsVisible( static_cast<sal_uInt16>(n) ) )
3043  {
3044  MenuItemData* pData = pItemList->GetDataFromPos( n );
3045  nHeight += pData->aSz.Height();
3046  nFound++;
3047  }
3048  }
3049 
3050  nHeight += 2*ImplGetFloatingWindow()->GetScrollerHeight();
3051 
3052  return nHeight;
3053 }
3054 
3055 css::uno::Reference<css::awt::XPopupMenu> PopupMenu::CreateMenuInterface()
3056 {
3058  if ( pWrapper )
3059  return pWrapper->CreateMenuInterface(this);
3060  return nullptr;
3061 }
3062 
3064 : mpNext( nullptr )
3065 , mpMenu( nullptr )
3066 {
3067  if( pMenu )
3068  const_cast< Menu* >( pMenu )->ImplAddDel( *this );
3069 }
3070 
3072 {
3073  if( mpMenu )
3074  const_cast< Menu* >( mpMenu.get() )->ImplRemoveDel( *this );
3075 }
3076 
3077 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void RemoveItem(sal_uInt16 nPos)
Definition: menu.cxx:496
OString GetHelpId(sal_uInt16 nItemId) const
Definition: menu.cxx:1128
VclPtr< Menu > pSubMenu
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: window3.cxx:65
Size GetSizePixel() const
Definition: Image.cxx:86
const Color & GetTextColor() const
Definition: outdev.hxx:1016
void SetPos(const Point &rPoint)
tools::Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId)
const Color & GetShadowColor() const
void UpdateNativeMenu()
Definition: menu.cxx:2177
void Clear()
Definition: menu.cxx:571
bool IsInputEnabled() const
Definition: window2.cxx:1150
void Deactivate()
Definition: menu.cxx:287
OUString GetAccessibleDescription(sal_uInt16 nItemId) const
Definition: menu.cxx:2298
bool HandleMenuButtonEvent(sal_uInt16 nEventId)
Definition: menu.cxx:2635
bool IsItemChecked(sal_uInt16 nItemId) const
Definition: menu.cxx:883
const Wallpaper & GetBackground() const
Definition: outdev.hxx:534
PopupMenu * GetPopupMenu(sal_uInt16 nItemId) const
Definition: menu.cxx:750
void StartPopupMode(const tools::Rectangle &rRect, FloatWinPopupFlags nFlags)
Definition: floatwin.cxx:776
sal_Int32 nIndex
void SetItemBits(sal_uInt16 nItemId, MenuItemBits nBits)
Definition: menu.cxx:671
void SetItemImage(sal_uInt16 nItemId, const Image &rImage)
Definition: menu.cxx:1003
SAL_DLLPRIVATE void ImplPaintMenuTitle(vcl::RenderContext &, const tools::Rectangle &rRect) const
Definition: menu.cxx:1665
bool bVisible
SAL_DLLPRIVATE void ImplFlushPendingSelect()
Definition: menu.cxx:2768
WinBits const WB_SYSTEMWINDOW
MenuItemType
Definition: vclenum.hxx:30
bool bCanceled
Terminated during a callback.
Definition: menu.hxx:151
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...
css::uno::Reference< css::accessibility::XAccessible > GetAccessible()
Definition: menu.cxx:1279
void ChangeHighlightItem(sal_uInt16 n, bool bStartPopupTimer)
void ShowButtons(bool bClose, bool bFloat, bool bHide)
Definition: menu.cxx:2407
SAL_DLLPRIVATE void ImplKillLayoutData() const
Definition: menu.cxx:2187
const Color & GetMenuBarTextColor() const
void setWidth(tools::Long nWidth)
int mnMenuFormatBorderX
Definition: svdata.hxx:319
tools::Rectangle GetCharacterBounds(sal_uInt16 nItemId, tools::Long nIndex) const
Definition: menu.cxx:2210
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)
SAL_DLLPRIVATE bool ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const
Definition: menu.cxx:1169
virtual void ClosePopup(Menu *pMenu) override
Close the 'pStartedFrom' menu window.
Definition: menu.cxx:2389
tools::Long getWidth() const
vcl::KeyCode aAccelKey
virtual void SelectItem(sal_uInt16 nId) override
Definition: menu.cxx:2511
void SetHelpId(sal_uInt16 nItemId, const OString &rHelpId)
Definition: menu.cxx:1120
constexpr tools::Long Left() const
Definition: help.hxx:60
void AddEventListener(const Link< VclMenuEvent &, void > &rEventListener)
Definition: menu.cxx:407
static Help * GetHelp()
Gets the application's help.
Definition: svapp.cxx:1469
SalLayoutGlyphs aTextGlyphs
Text layout of aText.
void PopupClosed(Menu const *pMenu)
SAL_DLLPRIVATE MenuItemData * NbcInsertItem(sal_uInt16 nId, MenuItemBits nBits, const OUString &rStr, Menu *pMenu, size_t nPos, const OString &rIdent)
Definition: menu.cxx:417
std::unique_ptr< sal_Int32[]> pData
bool mbNoDeactivate
Definition: svdata.hxx:270
bool IsBackground() const
Definition: outdev.hxx:537
OUString aHelpText
MenuItemBits GetItemBits(sal_uInt16 nItemId) const
Definition: menu.cxx:686
ImplSVAppData maAppData
Definition: svdata.hxx:398
SAL_DLLPRIVATE void ImplRemoveDel(ImplMenuDelData &rDel)
Definition: menu.cxx:1384
virtual ~Menu() override
Definition: menu.cxx:176
long Long
void disposeAndClear()
Definition: vclptr.hxx:200
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:760
constexpr sal_uInt16 KEY_A
Definition: keycodes.hxx:56
void SetHeight(tools::Long nHeight)
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:33
constexpr sal_uInt16 KEY_0
Definition: keycodes.hxx:45
VclPtr< PopupMenu > mpActivePopupMenu
Definition: svdata.hxx:151
virtual void ShowItem(unsigned nPos, bool bShow)
Definition: salmenu.hxx:86
const Color & GetFaceColor() const
static bool IsCycleKey(const vcl::KeyCode &rKeyCode)
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:804
ImplSVNWFData maNWFData
Definition: svdata.hxx:404
bool isDeleted() const
Definition: menu.hxx:110
sal_Int64 n
virtual void SetItemImage(unsigned nPos, SalMenuItem *pSalMenuItem, const Image &rImage)=0
Link< Menu *, bool > aSelectHdl
Definition: menu.hxx:132
PopupMenu * GetActivePopup() const
virtual Size GetSizePixel() const
Definition: window.cxx:2404
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:527
void SetWeight(FontWeight)
Definition: font/font.cxx:249
sal_Int16 nId
void SetLOKNotifier(const vcl::ILibreOfficeKitNotifier *pNotifier, bool bParent=false)
Interface to register for dialog / window tunneling.
Definition: window.cxx:3183
SAL_DLLPRIVATE void ImplCallEventListeners(VclEventId nEvent, sal_uInt16 nPos)
Definition: menu.cxx:383
Link< Menu *, bool > aDeactivateHdl
Definition: menu.hxx:131
void ChangeHighlightItem(sal_uInt16 n, bool bSelectPopupEntry, bool bAllowRestoreFocus=true, bool bDefaultToDocument=true)
void SetSelectedEntry(sal_uInt16 nId)
Definition: menu.cxx:2737
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:1120
void ShowButtons(bool bClose, bool bFloat, bool bHide)
void SetAutoPopup(bool bAuto)
sal_uInt16 GetCode() const
Definition: keycod.hxx:49
static bool IsUnifiedDisplay()
Determines if the screens that make up a display are separate or form one large display area...
Definition: svapp.cxx:1333
void setTristateVal(ButtonValue nTristate)
virtual OUString GetHelpText(const OUString &aHelpURL, const weld::Widget *pWidget)
Definition: help.cxx:72
sal_uInt16 GetItemPos(sal_uInt16 nItemId) const
Definition: menu.cxx:644
sal_uInt16 Execute(vcl::Window *pWindow, const Point &rPopupPos)
Definition: menu.cxx:2743
tools::Rectangle GetDesktopRectPixel() const
Definition: window.cxx:2801
VclPtr< vcl::Window > pWindow
Definition: menu.hxx:128
OUString CreateMnemonic(const OUString &rKey)
Definition: mnemonic.cxx:121
bool HandleMenuHighlightEvent(Menu *pMenu, sal_uInt16 nEventId) const
Definition: menu.cxx:2566
void SetHelpText(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1066
virtual css::uno::Reference< css::awt::XPopupMenu > CreateMenuInterface(PopupMenu *pPopupMenu)=0
FloatWinPopupFlags
Definition: vclenum.hxx:368
void KillActivePopup()
float x
void LayoutChanged()
Definition: menu.cxx:2422
void SetTipHelpText(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1102
OUString aTitleText
Definition: menu.hxx:138
static SAL_DLLPRIVATE bool ImplGetNativeSubmenuArrowSize(vcl::RenderContext const &rRenderContext, Size &rArrowSize, tools::Long &rArrowSpacing)
Definition: menu.cxx:1352
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
DrawTextFlags
VclPtr< Menu > pStartedFrom
Definition: menu.hxx:127
std::list< Link< VclMenuEvent &, void > > maEventListeners
Definition: menu.hxx:134
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. ...
const Color & GetHighlightColor() const
MenuItemBits
Definition: vclenum.hxx:32
static SAL_DLLPRIVATE VclPtr< vcl::Window > ImplCreate(vcl::Window *pParent, vcl::Window *pWindow, MenuBar *pMenu)
Definition: menu.cxx:2441
NONE
const Color & GetMenuHighlightTextColor() const
OString sSelectedIdent
Definition: menu.hxx:145
SAL_DLLPRIVATE Size ImplCalcSize(vcl::Window *pWin)
Definition: menu.cxx:1403
void SetMenuBarButtonHighlightHdl(sal_uInt16 nId, const Link< MenuBarButtonCallbackArg &, bool > &)
sal_uInt16 nImgOrChkPos
Definition: menu.hxx:148
WEIGHT_BOLD
tools::Long getHeight() const
constexpr tools::Long Width() const
OUString GetName() const
Definition: keycod.cxx:66
sal_uInt16 nTextPos
Definition: menu.hxx:149
sal_uInt16 sal_Unicode
void SetBackground()
Definition: background.cxx:27
OUString aCommandStr
WindowBorderStyle GetBorderStyle() const
Definition: window.cxx:2036
SAL_DLLPRIVATE OUString ImplGetHelpText(sal_uInt16 nItemId) const
Definition: menu.cxx:1074
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
void CreateAutoMnemonics()
Definition: menu.cxx:238
OUString aAccessibleName
SymbolType
Definition: vclenum.hxx:73
const vcl::Font & GetFont() const
Definition: outdev.hxx:540
EdgeEntry * mpNext
void * nUserValue
DrawImageFlags
ImplMenuDelData * mpNext
Definition: menu.hxx:104
bool IsHighlighted(sal_uInt16 nItemPos) const
Definition: menu.cxx:2317
SAL_DLLPRIVATE Menu * ImplFindMenu(sal_uInt16 nId)
Definition: menu.cxx:2125
virtual void ClosePopup(Menu *pMenu) override
Close the 'pStartedFrom' menu window.
Definition: menu.cxx:2678
MenuItemType GetItemType(sal_uInt16 nPos) const
Definition: menu.cxx:655
Class that implements the actual window of the floating menu.
int nCount
void SetItemCommand(sal_uInt16 nItemId, const OUString &rCommand)
Definition: menu.cxx:1029
OUString GetEllipsisString(const OUString &rStr, tools::Long nMaxWidth, DrawTextFlags nStyle=DrawTextFlags::EndEllipsis) const
Definition: text.cxx:2049
bool mbFloatBtnVisible
Definition: menu.hxx:409
void SetUserValue(sal_uInt16 nItemId, void *nUserValue, MenuUserDataReleaseFunction aFunc=nullptr)
Definition: menu.cxx:695
const Color & GetLightColor() const
virtual void Update()
Definition: salmenu.hxx:80
VclEventId
Definition: vclevent.hxx:37
constexpr tools::Long GetWidth() const
OUString GetItemCommand(sal_uInt16 nItemId) const
Definition: menu.cxx:1038
void Pop()
Definition: stack.cxx:92
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={}, const SalLayoutGlyphs *pGlyphs=nullptr) const
Return the exact bounding rectangle of rStr.
Definition: text.cxx:2377
void SetBorderStyle(WindowBorderStyle nBorderStyle)
Definition: window.cxx:1996
OUString aAccessibleDescription
virtual void SetOutputSizePixel(const Size &rNewSize)
Definition: window2.cxx:1297
tools::Long GetCtrlTextWidth(const OUString &rStr, const SalLayoutGlyphs *pLayoutCache=nullptr) const
Definition: text.cxx:2325
void SetMenuBarButtonHighlightHdl(sal_uInt16 nId, const Link< MenuBarButtonCallbackArg &, bool > &)
Definition: menu.cxx:2613
void InsertSeparator(const OString &rIdent=OString(), sal_uInt16 nPos=MENU_APPEND)
Definition: menu.cxx:472
void SetAccessible(const css::uno::Reference< css::accessibility::XAccessible > &)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::map< sal_uInt16, tools::Rectangle > m_aVisibleItemBoundRects
Definition: menu.cxx:66
SAL_DLLPRIVATE SalMenu * ImplGetSalMenu()
Definition: menu.hxx:181
OUString aTipHelpText
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:160
sal_uInt16 nCode
bool IsItemEnabled(sal_uInt16 nItemId) const
Definition: menu.cxx:928
const Color & GetMenuTextColor() const
Menu()
The Menu constructor is protected.
Definition: menu.cxx:158
static void ImplCallEventListeners(VclSimpleEvent &rEvent)
Send event to all VCL application event listeners.
Definition: svapp.cxx:814
void KillActivePopup(PopupMenu *pThisOnly=nullptr)
SAL_DLLPRIVATE sal_uInt16 ImplGetNextVisible(sal_uInt16 nPos) const
Definition: menu.cxx:613
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
virtual int GetMenuBarHeight() const
Definition: salvtables.cxx:212
std::vector< sal_uInt16 > m_aLineItemIds
Definition: menu.cxx:65
const Color & GetMenuColor() const
OUString VclResId(TranslateId aId)
Definition: svdata.cxx:260
float y
virtual void SetItemText(unsigned nPos, SalMenuItem *pSalMenuItem, const OUString &rText)=0
void SetPopupMenu(sal_uInt16 nItemId, PopupMenu *pMenu)
Definition: menu.cxx:713
DocumentType eType
Class that implements the actual window of the menu bar.
bool IsDisplayable() const
Definition: menu.hxx:460
OString aHelpId
bool HasCheck() const
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
Remove user event based on event ID.
Definition: svapp.cxx:1144
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
tools::Long ImplGetStartY() const
Get a negative pixel offset for an offset menu.
void SetLineColor()
Definition: line.cxx:36
void clear()
Definition: vclptr.hxx:190
size_t size() const
int GetMenuBarHeight() const
Definition: menu.cxx:2641
SAL_DLLPRIVATE bool ImplHandleKeyEvent(const KeyEvent &rKEvent)
Definition: menu.cxx:2481
static tools::Rectangle GetScreenPosSizePixel(unsigned int nScreen)
Get a screen's rectangular area.
Definition: svapp.cxx:1368
void SetAccessibleDescription(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:2290
sal_uInt16 GetCurItemId() const
Definition: menu.hxx:258
sal_uInt16 nId
ImplMenuDelData(const Menu *)
Definition: menu.cxx:3063
std::unique_ptr< MenuItemList > pItemList
Definition: menu.hxx:126
int i
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:884
const VclPtr< vcl::Window > & GetFocusId() const
const Color & GetMenuBarColor() const
bool bInCallback
In Activate/Deactivate.
Definition: menu.hxx:152
void SetMenu(MenuBar *pMenu)
Menu & operator=(const Menu &rMenu)
Definition: menu.cxx:1145
bool IsDark() const
bool HandleMenuDeActivateEvent(Menu *pMenu) const
Definition: menu.cxx:2551
virtual bool CanGetFocus() const
Definition: salmenu.hxx:82
static PopupMenu * GetActivePopupMenu()
Definition: menu.cxx:2694
SAL_DLLPRIVATE void ImplAddDel(ImplMenuDelData &rDel)
Definition: menu.cxx:1373
bool HandleMenuButtonEvent(sal_uInt16 i_nButtonId)
const OUString & get_id() const
Get the ID of the window.
Definition: menu.hxx:396
SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries(tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16 *pLastVisible=nullptr) const
Definition: menu.cxx:3007
VclPtr< const Menu > mpMenu
Definition: menu.hxx:105
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: menu.cxx:623
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1143
const Color & GetMenuBarHighlightTextColor() const
MenuItemType eType
Image GetItemImage(sal_uInt16 nItemId) const
Definition: menu.cxx:1019
bool HandleMenuActivateEvent(Menu *pMenu) const
Definition: menu.cxx:2535
void SetFillColor()
Definition: fill.cxx:29
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:175
const AllSettings & GetSettings() const
Definition: window3.cxx:129
#define ENSURE_OR_RETURN(c, m, r)
sal_uInt16 GetScrollerHeight() const
SAL_DLLPRIVATE bool ImplIsSelectable(sal_uInt16 nPos) const
Definition: menu.cxx:1267
void SetTextColor(const Color &rColor)
Definition: text.cxx:714
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
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
DrawSymbolFlags
Definition: decoview.hxx:34
PopupMenu()
Definition: menu.cxx:2662
SAL_DLLPRIVATE Menu * ImplFindSelectMenu()
Definition: menu.cxx:2110
SalFrameGeometry maGeometry
absolute, unmirrored values
Definition: salframe.hxx:129
constexpr tools::Long Top() const
size
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.
SAL_DLLPRIVATE sal_uInt16 ImplGetPrevVisible(sal_uInt16 nPos) const
Definition: menu.cxx:603
virtual ~PopupMenu() override
Definition: menu.cxx:2673
bool mbHideBtnVisible
Definition: menu.hxx:410
SAL_DLLPRIVATE tools::Long ImplCalcHeight(sal_uInt16 nEntries) const
Definition: menu.cxx:3035
virtual void RemoveItem(unsigned nPos)=0
const AllSettings & GetSettings() const
Definition: outdev.hxx:295
bool IsItemPosVisible(sal_uInt16 nItemPos) const
Definition: menu.cxx:1257
SAL_DLLPRIVATE bool ImplIsVisible(sal_uInt16 nPos) const
Definition: menu.cxx:1183
static unsigned int GetScreenCount()
Get the number of screens available for the display.
Definition: svapp.cxx:1327
MenuItemList * GetItemList() const
Definition: menu.hxx:343
static SAL_DLLPRIVATE unsigned int GetBestScreen(const tools::Rectangle &)
Get the "best" screen.
Definition: svapp.cxx:1394
virtual void ShowMenuBar(bool)
Definition: salmenu.hxx:64
sal_uInt16 GetHighlightedItem() const
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
constexpr sal_uInt16 KEY_MOD2
Definition: keycodes.hxx:32
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
std::unique_ptr< SalMenuItem > pSalMenuItem
tools::Rectangle GetBoundingRectangle(sal_uInt16 nItemPos) const
Definition: menu.cxx:2253
void GrabFocus()
Definition: window.cxx:2981
SAL_DLLPRIVATE Menu * ImplGetStartMenu()
Definition: menu.cxx:2075
vcl::Window * GetParent() const
Definition: window2.cxx:1120
SalLayoutGlyphs * GetTextGlyphs(const OutputDevice *pOutputDevice)
Computes aText's text layout (glyphs), cached in aTextGlyphs.
SystemWindow * GetFloatingWindow(const vcl::Window *pWin)
Definition: dockmgr.cxx:371
virtual void EnableItem(unsigned nPos, bool bEnable)=0
SAL_DLLPRIVATE sal_uInt16 ImplGetFirstVisible() const
Definition: menu.cxx:593
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
Definition: window.cxx:2857
void SetPosInParent(sal_uInt16 nPos)
OUString GetItemText(sal_uInt16 nItemId) const
Definition: menu.cxx:992
SAL_DLLPRIVATE vcl::Window * ImplGetWindow() const
Definition: menu.hxx:208
bool mbCloseBtnVisible
Definition: menu.hxx:408
void EnableItem(sal_uInt16 nItemId, bool bEnable=true)
Definition: menu.cxx:894
SalFrame * mpFrame
Definition: window.h:229
float GetDPIScaleFactor() const
Definition: outdev.hxx:403
OUString GetHelpCommand(sal_uInt16 nItemId) const
Definition: menu.cxx:1056
void CheckItem(sal_uInt16 nItemId, bool bCheck=true)
Definition: menu.cxx:813
virtual void MenuBarKeyInput(const KeyEvent &rEvent) override
Forward the KeyInput call to the MenuBar.
Definition: menu.cxx:2397
constexpr Point TopLeft() const
void HighlightItem(sal_uInt16 nItemPos)
Definition: menu.cxx:2332
bool IsInPopupMode(const vcl::Window *pWin)
Definition: dockmgr.cxx:358
virtual void dispose()
virtual void SetItemBits(unsigned, MenuItemBits)
Definition: salmenu.hxx:69
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
SAL_DLLPRIVATE void ImplEndPopupMode(FloatWinPopupEndFlags nFlags, const VclPtr< vcl::Window > &xFocusId)
Definition: floatwin.cxx:867
constexpr tools::Long Bottom() const
OUString aHelpCommandStr
virtual void KeyInput(const KeyEvent &rKEvt)
Definition: window.cxx:1807
bool mbDisplayable
Definition: menu.hxx:411
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: window.cxx:2426
SAL_DLLPRIVATE void ImplSelect()
Definition: menu.cxx:330
std::unique_ptr< vcl::MenuLayoutData > mpLayoutData
Definition: menu.hxx:156
void RemoveMenuBarButton(sal_uInt16 nId)
A construction helper for a temporary VclPtr.
Definition: vclptr.hxx:275
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
OUString GetTipHelpText(sal_uInt16 nItemId) const
Definition: menu.cxx:1110
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
MenuItemData * GetDataFromPos(size_t nPos) const
Definition: menu.hxx:115
constexpr Size GetSize() const
virtual void MenuBarKeyInput(const KeyEvent &rEvent)
Forward the KeyInput call to the MenuBar.
Definition: menu.cxx:2183
void SetHelpCommand(sal_uInt16 nItemId, const OUString &rString)
Definition: menu.cxx:1048
KeyEvent GetActivationKey(sal_uInt16 nItemId) const
Definition: menu.cxx:788
virtual void SetAccelerator(unsigned nPos, SalMenuItem *pSalMenuItem, const vcl::KeyCode &rKeyCode, const OUString &rKeyName)=0
void GetSystemMenuData(SystemMenuData *pData) const
Definition: menu.cxx:2308
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible(Menu *pMenu, bool bIsMenuBar)=0
void EndExecute()
Definition: menu.cxx:2700
OString sIdent
virtual void CheckItem(unsigned nPos, bool bCheck)=0
DockingManager * ImplGetDockingManager()
Definition: svdata.cxx:315
void RemoveEventListener(const Link< VclMenuEvent &, void > &rEventListener)
Definition: menu.cxx:412
virtual bool ShowNativePopupMenu(FloatingWindow *pWin, const tools::Rectangle &rRect, FloatWinPopupFlags nFlags)
Definition: salvtables.cxx:196
void * GetUserValue(sal_uInt16 nItemId) const
Definition: menu.cxx:707
void SetFocusId(const VclPtr< vcl::Window > &xId)
void SetAccessible(const css::uno::Reference< css::accessibility::XAccessible > &rxAccessible)
Definition: menu.cxx:1311
bool GetUseImagesInMenus() const
void Activate()
Definition: menu.cxx:256
#define SAL_WARN_IF(condition, area, stream)
SAL_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const
Definition: menu.cxx:582
void SetAccessibleName(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:2268
constexpr tools::Long Height() const
WinBits const WB_BORDER
void SetDisplayable(bool bDisplayable)
Definition: menu.cxx:2429
vcl::Window * GetWindow() const
Definition: menu.hxx:370
MenuUserDataReleaseFunction aUserValueReleaseFunc
virtual bool IsMenuBar() const =0
void setWidth(tools::Long n)
void SetFont(const vcl::Font &rNewFont)
Definition: outdev/font.cxx:53
bool mbFlatMenu
Definition: svdata.hxx:327
SAL_DLLPRIVATE void ImplFillLayoutData() const
Definition: menu.cxx:2192
void ShowItem(sal_uInt16 nItemId, bool bVisible=true)
Definition: menu.cxx:939
tools::Long GetIndexForPoint(const Point &rPoint, sal_uInt16 &rItemID) const
Definition: menu.cxx:2229
ImplMenuDelData * mpFirstDel
Definition: menu.hxx:125
bool IsVisible() const
Definition: window2.cxx:1125
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: text.cxx:895
OUString aName
::OutputDevice const * GetOutDev() const
Definition: window.cxx:567
sal_uInt16 GetItemCount() const
Definition: menu.cxx:577
tools::Long AdjustWidth(tools::Long n)
Definition: image.hxx:39
sal_uInt16 nSelectedId
Definition: menu.hxx:144
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
MenuItemData * GetData(sal_uInt16 nSVId, size_t &rPos) const
sal_uInt16 nTitleHeight
Definition: menu.hxx:139
OUString GetHelpText(sal_uInt16 nItemId) const
Definition: menu.cxx:1097
void * p
sal_uInt16 mnHighlightedItemPos
Definition: menu.hxx:142
void SetAccelKey(sal_uInt16 nItemId, const vcl::KeyCode &rKeyCode)
Definition: menu.cxx:760
const vcl::Font & GetFont() const
Definition: window3.cxx:58
bool GetSkipDisabledInMenus() const
tools::Long AdjustHeight(tools::Long n)
vcl::KeyCode GetAccelKey(sal_uInt16 nItemId) const
Definition: menu.cxx:778
virtual void InsertItem(SalMenuItem *pSalMenuItem, unsigned nPos)=0
VclPtr< FloatingWindow > mpFirstFloat
Definition: svdata.hxx:258
SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const
Definition: menu.cxx:2658
virtual std::unique_ptr< SalMenu > CreateMenu(bool bMenuBar, Menu *pMenu)
Definition: salvtables.cxx:135
Size GetOutputSizePixel() const
Definition: window3.cxx:89
constexpr Point BottomRight() const
std::unique_ptr< SalMenu > mpSalMenu
Definition: menu.hxx:157
void setHeight(tools::Long nHeight)
WindowType GetType() const
Definition: window2.cxx:997
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
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
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
bool IsEnabled() const
Definition: window2.cxx:1145
const vcl::ILibreOfficeKitNotifier * GetLOKNotifier() const
Definition: window.cxx:3253
#define SAL_WARN(area, stream)
SAL_DLLPRIVATE void ImplCallHighlight(sal_uInt16 nHighlightItem)
Definition: menu.cxx:2083
void DrawSymbol(const tools::Rectangle &rRect, SymbolType eType, const Color &rColor, DrawSymbolFlags nStyle=DrawSymbolFlags::NONE)
Definition: decoview.cxx:761
OUString aText
css::uno::Reference< css::accessibility::XAccessible > mxAccessible
Definition: menu.hxx:155
void SetFont(const vcl::Font &rNewFont)
Definition: window3.cxx:59
ImplSVEvent * nEventId
Definition: menu.hxx:141
virtual void GetSystemMenuData(SystemMenuData *pData)=0
MenuBar()
Definition: menu.cxx:2359
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2808
tools::Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId)
Definition: menu.cxx:2629
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
static UnoWrapperBase * GetUnoWrapper(bool bCreateIfNotExists=true)
Get the application's UNO wrapper object.
Definition: svapp.cxx:1590
virtual void SelectItem(sal_uInt16 nId) override
Definition: menu.cxx:2706
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
Definition: window3.cxx:74
virtual void SetSubMenu(SalMenuItem *pSalMenuItem, SalMenu *pSubMenu, unsigned nPos)=0
bool IsInPopupMenuExecute()
Definition: menu.cxx:2688
static SettingsConfigItem * get()
sal_uInt16 AddMenuBarButton(const Image &, const Link< MenuBarButtonCallbackArg &, bool > &, const OUString &)
Definition: menu.cxx:2607
bool HandleMenuCommandEvent(Menu *pMenu, sal_uInt16 nEventId) const
Definition: menu.cxx:2591
bool IsReallyVisible() const
Definition: window2.cxx:1130
const Color & GetMenuBarRolloverTextColor() const
virtual ~MenuBar() override
Definition: menu.cxx:2378
static OUString GetNonMnemonicString(const OUString &rStr, sal_Int32 &rMnemonicPos)
Definition: text.cxx:2342
Link< Menu *, bool > aActivateHdl
Definition: menu.hxx:130
void RemoveDisabledEntries(bool bRemoveEmptyPopups=false)
Definition: menu.cxx:2142
SAL_DLLPRIVATE sal_uInt16 ImplExecute(const VclPtr< vcl::Window > &pW, const tools::Rectangle &rRect, FloatWinPopupFlags nPopupModeFlags, Menu *pSFrom, bool bPreSelectFirst)
Definition: menu.cxx:2781
OString GetItemIdent(sal_uInt16 nItemId) const
Definition: menu.cxx:665
OUString GetAccessibleName(sal_uInt16 nItemId) const
Definition: menu.cxx:2280
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:795
void RegisterMnemonic(const OUString &rKey)
Definition: mnemonic.cxx:81
SAL_DLLPRIVATE Size ImplGetNativeCheckAndRadioSize(vcl::RenderContext const &rRenderContext, tools::Long &rCheckHeight, tools::Long &rRadioHeight) const
Definition: menu.cxx:1316
void EndPopupMode(FloatWinPopupEndFlags nFlags=FloatWinPopupEndFlags::NONE)
Definition: floatwin.cxx:949
sal_Int32 nState
bool bKilled
Killed.
Definition: menu.hxx:153
aStr
bool isDisposed() const
virtual void dispose() override
Definition: menu.cxx:181
virtual bool VisibleMenuBar()=0
AnyEventRef aEvent
bool IsMenuVisible() const
Definition: menu.cxx:1262
SalInstance * mpDefInst
Definition: svdata.hxx:390
MenuFlags nMenuFlags
Definition: menu.hxx:143
unsigned int nDisplayScreenNumber
Definition: salgeom.hxx:38
void RemoveMenuBarButton(sal_uInt16 nId)
Definition: menu.cxx:2621
void setHeight(tools::Long n)
sal_uInt16 nPos
void Select()
Definition: menu.cxx:351
virtual void dispose() override
Definition: menu.cxx:2383
void ShowCloseButton(bool bShow)
Definition: menu.cxx:2402
css::uno::Reference< css::awt::XPopupMenu > CreateMenuInterface()
Definition: menu.cxx:3055
ImplSVWinData * mpWinData
Definition: svdata.hxx:401
bool m_bDetectedRangeSegmentation false
MenuBarWindow * getMenuBarWindow()
Return the MenuBarWindow.
Definition: menu.cxx:2349
constexpr tools::Long GetHeight() const
void SetItemText(sal_uInt16 nItemId, const OUString &rStr)
Definition: menu.cxx:961
bool HandleKeyEvent(const KeyEvent &rKEvent, bool bFromMenu=true)
MenuItemBits nBits
static SAL_DLLPRIVATE void ImplDestroy(MenuBar *pMenu, bool bDelete)
Definition: menu.cxx:2465