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