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