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