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