sdext: adapt xpdfwrapper to poppler 24.12
[LibreOffice.git] / vcl / source / control / menubtn.cxx
blob1cfd0799fe3014ebcf07ef4ec8e08ee7e56fbe56
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/dockwin.hxx>
21 #include <vcl/event.hxx>
22 #include <vcl/toolkit/floatwin.hxx>
23 #include <vcl/menu.hxx>
24 #include <vcl/timer.hxx>
25 #include <vcl/toolkit/menubtn.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/uitest/uiobject.hxx>
28 #include <vcl/uitest/logger.hxx>
29 #include <vcl/uitest/eventdescription.hxx>
30 #include <menutogglebutton.hxx>
31 #include <tools/json_writer.hxx>
33 namespace
35 void collectUIInformation( const OUString& aID, const OUString& aevent , const OUString& akey , const OUString& avalue)
37 EventDescription aDescription;
38 aDescription.aID = aID;
39 aDescription.aParameters = {{ akey , avalue}};
40 aDescription.aAction = aevent;
41 aDescription.aParent = "MainWindow";
42 aDescription.aKeyWord = "MenuButton";
43 UITestLogger::getInstance().logEvent(aDescription);
47 void MenuButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
49 if ( !(nStyle & WB_NOTABSTOP) )
50 nStyle |= WB_TABSTOP;
52 PushButton::ImplInit( pParent, nStyle );
53 EnableRTL( AllSettings::GetLayoutRTL() );
56 void MenuButton::ExecuteMenu()
58 mbStartingMenu = true;
60 PrepareExecute();
62 if (!mpMenu && !mpFloatingWindow)
64 mbStartingMenu = false;
65 return;
68 Size aSize = GetSizePixel();
69 SetPressed( true );
70 EndSelection();
71 if (mpMenu)
73 Point aPos(0, 1);
74 tools::Rectangle aRect(aPos, aSize );
75 mpMenu->Execute(this, aRect, PopupMenuFlags::ExecuteDown);
77 if (isDisposed())
78 return;
80 mnCurItemId = mpMenu->GetCurItemId();
81 msCurItemIdent = mpMenu->GetCurItemIdent();
83 else
85 Point aPos(GetParent()->OutputToScreenPixel(GetPosPixel()));
86 tools::Rectangle aRect(aPos, aSize );
87 FloatWinPopupFlags nFlags = FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus;
88 if (mpFloatingWindow->GetType() == WindowType::FLOATINGWINDOW)
89 static_cast<FloatingWindow*>(mpFloatingWindow.get())->StartPopupMode(aRect, nFlags);
90 else
92 mpFloatingWindow->EnableDocking();
93 vcl::Window::GetDockingManager()->StartPopupMode(mpFloatingWindow, aRect, nFlags);
97 Activate();
99 mbStartingMenu = false;
101 SetPressed(false);
102 OUString aID = get_id(); // tdf#136678 take a copy if we are destroyed by Select callback
103 if (mnCurItemId)
105 Select();
106 mnCurItemId = 0;
107 msCurItemIdent.clear();
109 collectUIInformation(aID,u"OPENLIST"_ustr,u""_ustr,u""_ustr);
112 void MenuButton::CancelMenu()
114 if (!mpMenu && !mpFloatingWindow)
115 return;
117 if (mpMenu)
119 mpMenu->EndExecute();
121 else
123 if (mpFloatingWindow->GetType() == WindowType::FLOATINGWINDOW)
124 static_cast<FloatingWindow*>(mpFloatingWindow.get())->EndPopupMode();
125 else
126 vcl::Window::GetDockingManager()->EndPopupMode(mpFloatingWindow);
128 collectUIInformation(get_id(),u"CLOSELIST"_ustr,u""_ustr,u""_ustr);
131 bool MenuButton::InPopupMode() const
133 if (mbStartingMenu)
134 return true;
136 if (!mpMenu && !mpFloatingWindow)
137 return false;
139 if (mpMenu)
140 return PopupMenu::GetActivePopupMenu() == mpMenu;
141 else
143 if (mpFloatingWindow->GetType() == WindowType::FLOATINGWINDOW)
144 return static_cast<const FloatingWindow*>(mpFloatingWindow.get())->IsInPopupMode();
145 else
146 return vcl::Window::GetDockingManager()->IsInPopupMode(mpFloatingWindow);
150 MenuButton::MenuButton( vcl::Window* pParent, WinBits nWinBits )
151 : PushButton(WindowType::MENUBUTTON)
152 , mnCurItemId(0)
153 , mbDelayMenu(false)
154 , mbStartingMenu(false)
156 mnDDStyle = PushButtonDropdownStyle::MenuButton;
157 ImplInit(pParent, nWinBits);
160 MenuButton::~MenuButton()
162 disposeOnce();
165 void MenuButton::dispose()
167 mpMenuTimer.reset();
168 mpFloatingWindow.clear();
169 if (mpMenu && mbOwnPopupMenu)
170 mpMenu->dispose();
171 mpMenu.clear();
172 PushButton::dispose();
175 IMPL_LINK_NOARG(MenuButton, ImplMenuTimeoutHdl, Timer *, void)
177 // See if Button Tracking is still active, as it could've been cancelled earlier
178 if ( IsTracking() )
180 if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
181 GrabFocus();
182 ExecuteMenu();
186 void MenuButton::MouseButtonDown( const MouseEvent& rMEvt )
188 bool bExecute = true;
189 if (mbDelayMenu)
191 // If the separated dropdown symbol is not hit, delay the popup execution
192 if( rMEvt.GetPosPixel().X() <= ImplGetSeparatorX() )
194 if ( !mpMenuTimer )
196 mpMenuTimer.reset(new Timer("MenuTimer"));
197 mpMenuTimer->SetInvokeHandler( LINK( this, MenuButton, ImplMenuTimeoutHdl ) );
200 mpMenuTimer->SetTimeout( MouseSettings::GetActionDelay() );
201 mpMenuTimer->Start();
203 PushButton::MouseButtonDown( rMEvt );
204 bExecute = false;
207 if( bExecute )
209 if ( PushButton::ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
211 if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
212 GrabFocus();
213 ExecuteMenu();
218 void MenuButton::KeyInput( const KeyEvent& rKEvt )
220 vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
221 sal_uInt16 nCode = aKeyCode.GetCode();
222 if ( (nCode == KEY_DOWN) && aKeyCode.IsMod2() )
223 ExecuteMenu();
224 else if ( !mbDelayMenu &&
225 !aKeyCode.GetModifier() &&
226 ((nCode == KEY_RETURN) || (nCode == KEY_SPACE)) )
227 ExecuteMenu();
228 else
229 PushButton::KeyInput( rKEvt );
232 void MenuButton::Activate()
234 maActivateHdl.Call( this );
237 void MenuButton::Select()
239 if (mnCurItemId)
240 collectUIInformation(get_id(),u"OPENFROMLIST"_ustr,u"POS"_ustr,OUString::number(mnCurItemId));
242 maSelectHdl.Call( this );
245 void MenuButton::SetPopupMenu(PopupMenu* pNewMenu, bool bTakeOwnership)
247 if (pNewMenu == mpMenu)
248 return;
250 if (mpMenu && mbOwnPopupMenu)
251 mpMenu->dispose();
253 mpMenu = pNewMenu;
254 mbOwnPopupMenu = bTakeOwnership;
257 void MenuButton::SetPopover(Window* pWindow)
259 if (pWindow == mpFloatingWindow)
260 return;
262 mpFloatingWindow = pWindow;
266 FactoryFunction MenuButton::GetUITestFactory() const
268 return MenuButtonUIObject::create;
271 void MenuButton::SetCurItemId(){
272 mnCurItemId = mpMenu->GetCurItemId();
273 msCurItemIdent = mpMenu->GetCurItemIdent();
276 void MenuButton::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter)
278 PushButton::DumpAsPropertyTree(rJsonWriter);
280 if (mpMenu)
282 auto aMenuNode = rJsonWriter.startArray("menu");
283 for (int i = 0; i < mpMenu->GetItemCount(); i++)
285 auto aEntryNode = rJsonWriter.startStruct();
286 auto sId = mpMenu->GetItemId(i);
287 rJsonWriter.put("id", mpMenu->GetItemIdent(sId));
288 rJsonWriter.put("text", mpMenu->GetItemText(sId));
293 //class MenuToggleButton ----------------------------------------------------
295 MenuToggleButton::MenuToggleButton( vcl::Window* pParent, WinBits nWinBits )
296 : MenuButton( pParent, nWinBits )
300 MenuToggleButton::~MenuToggleButton()
302 disposeOnce();
305 void MenuToggleButton::SetActive( bool bSel )
307 mbIsActive = bSel;
310 bool MenuToggleButton::GetActive() const
312 return mbIsActive;
315 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */