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