LibreOffice Module vcl (master) 1
menubtn.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 <vcl/dockwin.hxx>
21#include <vcl/event.hxx>
23#include <vcl/menu.hxx>
24#include <vcl/timer.hxx>
26#include <vcl/settings.hxx>
28#include <vcl/uitest/logger.hxx>
30#include <menutogglebutton.hxx>
31#include <tools/json_writer.hxx>
32
33namespace
34{
35void collectUIInformation( const OUString& aID, const OUString& aevent , const OUString& akey , const OUString& avalue)
36{
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);
44}
45}
46
48{
49 if ( !(nStyle & WB_NOTABSTOP) )
50 nStyle |= WB_TABSTOP;
51
52 PushButton::ImplInit( pParent, nStyle );
54}
55
57{
58 mbStartingMenu = true;
59
60 Activate();
61
62 if (!mpMenu && !mpFloatingWindow)
63 {
64 mbStartingMenu = false;
65 return;
66 }
67
68 Size aSize = GetSizePixel();
69 SetPressed( true );
71 if (mpMenu)
72 {
73 Point aPos(0, 1);
74 tools::Rectangle aRect(aPos, aSize );
76
77 if (isDisposed())
78 return;
79
82 }
83 else
84 {
86 tools::Rectangle aRect(aPos, aSize );
89 static_cast<FloatingWindow*>(mpFloatingWindow.get())->StartPopupMode(aRect, nFlags);
90 else
91 {
92 mpFloatingWindow->EnableDocking();
94 }
95 }
96
97 mbStartingMenu = false;
98
99 SetPressed(false);
100 OUString aID = get_id(); // tdf#136678 take a copy if we are destroyed by Select callback
101 if (mnCurItemId)
102 {
103 Select();
104 mnCurItemId = 0;
105 msCurItemIdent.clear();
106 }
107 collectUIInformation(aID,"OPENLIST","","");
108}
109
111{
112 if (!mpMenu && !mpFloatingWindow)
113 return;
114
115 if (mpMenu)
116 {
118 }
119 else
120 {
122 static_cast<FloatingWindow*>(mpFloatingWindow.get())->EndPopupMode();
123 else
125 }
126 collectUIInformation(get_id(),"CLOSELIST","","");
127}
128
130{
131 if (mbStartingMenu)
132 return true;
133
134 if (!mpMenu && !mpFloatingWindow)
135 return false;
136
137 if (mpMenu)
139 else
140 {
142 return static_cast<const FloatingWindow*>(mpFloatingWindow.get())->IsInPopupMode();
143 else
145 }
146}
147
150 , mnCurItemId(0)
151 , mbDelayMenu(false)
152 , mbStartingMenu(false)
153{
155 ImplInit(pParent, nWinBits);
156}
157
159{
160 disposeOnce();
161}
162
164{
165 mpMenuTimer.reset();
167 mpMenu.clear();
169}
170
171IMPL_LINK_NOARG(MenuButton, ImplMenuTimeoutHdl, Timer *, void)
172{
173 // See if Button Tracking is still active, as it could've been cancelled earlier
174 if ( IsTracking() )
175 {
176 if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
177 GrabFocus();
178 ExecuteMenu();
179 }
180}
181
183{
184 bool bExecute = true;
185 if (mbDelayMenu)
186 {
187 // If the separated dropdown symbol is not hit, delay the popup execution
188 if( rMEvt.GetPosPixel().X() <= ImplGetSeparatorX() )
189 {
190 if ( !mpMenuTimer )
191 {
192 mpMenuTimer.reset(new Timer("MenuTimer"));
193 mpMenuTimer->SetInvokeHandler( LINK( this, MenuButton, ImplMenuTimeoutHdl ) );
194 }
195
197 mpMenuTimer->Start();
198
200 bExecute = false;
201 }
202 }
203 if( bExecute )
204 {
205 if ( PushButton::ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
206 {
207 if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
208 GrabFocus();
209 ExecuteMenu();
210 }
211 }
212}
213
214void MenuButton::KeyInput( const KeyEvent& rKEvt )
215{
216 vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
217 sal_uInt16 nCode = aKeyCode.GetCode();
218 if ( (nCode == KEY_DOWN) && aKeyCode.IsMod2() )
219 ExecuteMenu();
220 else if ( !mbDelayMenu &&
221 !aKeyCode.GetModifier() &&
222 ((nCode == KEY_RETURN) || (nCode == KEY_SPACE)) )
223 ExecuteMenu();
224 else
225 PushButton::KeyInput( rKEvt );
226}
227
229{
230 maActivateHdl.Call( this );
231}
232
234{
235 if (mnCurItemId)
236 collectUIInformation(get_id(),"OPENFROMLIST","POS",OUString::number(mnCurItemId));
237
238 maSelectHdl.Call( this );
239}
240
242{
243 if (pNewMenu == mpMenu)
244 return;
245
246 mpMenu = pNewMenu;
247}
248
249void MenuButton::SetPopover(Window* pWindow)
250{
251 if (pWindow == mpFloatingWindow)
252 return;
253
254 mpFloatingWindow = pWindow;
255}
256
257
259{
261}
262
266}
267
269{
271
272 if (mpMenu)
273 {
274 auto aMenuNode = rJsonWriter.startArray("menu");
275 for (int i = 0; i < mpMenu->GetItemCount(); i++)
276 {
277 auto aEntryNode = rJsonWriter.startStruct();
278 auto sId = mpMenu->GetItemId(i);
279 rJsonWriter.put("id", mpMenu->GetItemIdent(sId));
280 rJsonWriter.put("text", mpMenu->GetItemText(sId));
281 }
282 }
283}
284
285//class MenuToggleButton ----------------------------------------------------
286
288 : MenuButton( pParent, nWinBits )
289{
290}
291
293{
294 disposeOnce();
295}
296
298{
299 mbIsActive = bSel;
300}
301
303{
304 return mbIsActive;
305}
306
307/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool GetLayoutRTL()
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
Definition: button.cxx:112
SAL_DLLPRIVATE tools::Long ImplGetSeparatorX() const
The x-coordinate of the vertical separator line, use in MenuButton subclass only.
Definition: button.cxx:181
virtual void EnableRTL(bool bEnable=true) override
Definition: ctrl.cxx:68
bool IsInPopupMode(const vcl::Window *pWin)
Definition: dockmgr.cxx:358
void EndPopupMode(const vcl::Window *pWin)
Definition: dockmgr.cxx:364
void StartPopupMode(const vcl::Window *pWin, const tools::Rectangle &rRect, FloatWinPopupFlags nPopupModeFlags)
Definition: dockmgr.cxx:337
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
MenuButton(const MenuButton &)=delete
virtual void DumpAsPropertyTree(tools::JsonWriter &rJsonWriter) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON.
Definition: menubtn.cxx:268
void SetPopupMenu(PopupMenu *pNewMenu)
Definition: menubtn.cxx:241
sal_uInt16 mnCurItemId
Definition: menubtn.hxx:43
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: menubtn.cxx:214
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: menubtn.cxx:182
void SetPopover(Window *pWindow)
Definition: menubtn.cxx:249
void Select()
Definition: menubtn.cxx:233
OUString msCurItemIdent
Definition: menubtn.hxx:42
VclPtr< Window > mpFloatingWindow
Definition: menubtn.hxx:41
bool mbDelayMenu
Definition: menubtn.hxx:44
VclPtr< PopupMenu > mpMenu
Definition: menubtn.hxx:40
bool InPopupMode() const
Definition: menubtn.cxx:129
void ExecuteMenu()
Definition: menubtn.cxx:56
virtual FactoryFunction GetUITestFactory() const override
Definition: menubtn.cxx:258
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: menubtn.cxx:47
void CancelMenu()
Definition: menubtn.cxx:110
std::unique_ptr< Timer > mpMenuTimer
Definition: menubtn.hxx:39
bool mbStartingMenu
Definition: menubtn.hxx:45
virtual ~MenuButton() override
Definition: menubtn.cxx:158
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
Definition: menubtn.cxx:163
Link< MenuButton *, void > maActivateHdl
Definition: menubtn.hxx:46
Link< MenuButton *, void > maSelectHdl
Definition: menubtn.hxx:47
virtual void Activate() override
Definition: menubtn.cxx:228
void SetCurItemId()
Definition: menubtn.cxx:263
MenuToggleButton(vcl::Window *pParent, WinBits nStyle)
Definition: menubtn.cxx:287
void SetActive(bool bSel)
Definition: menubtn.cxx:297
bool GetActive() const
Definition: menubtn.cxx:302
virtual ~MenuToggleButton() override
Definition: menubtn.cxx:292
OUString GetItemText(sal_uInt16 nItemId) const
Definition: menu.cxx:1017
sal_uInt16 GetCurItemId() const
Definition: menu.hxx:262
OUString const & GetCurItemIdent() const
Definition: menu.hxx:263
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: menu.cxx:641
OUString GetItemIdent(sal_uInt16 nItemId) const
Definition: menu.cxx:683
sal_uInt16 GetItemCount() const
Definition: menu.cxx:577
const Point & GetPosPixel() const
Definition: event.hxx:123
static sal_Int32 GetActionDelay()
constexpr tools::Long X() const
sal_uInt16 Execute(vcl::Window *pWindow, const Point &rPopupPos)
Definition: menu.cxx:2771
static PopupMenu * GetActivePopupMenu()
Definition: menu.cxx:2722
void EndExecute()
Definition: menu.cxx:2728
void EndSelection()
Definition: button.cxx:1692
PushButtonDropdownStyle mnDDStyle
Definition: button.hxx:188
void SetPressed(bool bPressed)
Definition: button.cxx:1683
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:678
bool mbIsActive
Definition: button.hxx:189
static SAL_DLLPRIVATE bool ImplHitTestPushButton(vcl::Window const *pDev, const Point &rPos)
Definition: button.cxx:794
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: button.cxx:1269
void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON.
Definition: button.cxx:641
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:1352
Definition: timer.hxx:27
static UITestLogger & getInstance()
Definition: logger.cxx:611
void logEvent(const EventDescription &rDescription)
Definition: logger.cxx:372
void clear()
Definition: vclptr.hxx:190
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
bool isDisposed() const
void put(std::u16string_view pPropName, const OUString &rPropValue)
ScopedJsonWriterStruct startStruct()
ScopedJsonWriterArray startArray(std::string_view)
sal_uInt16 GetCode() const
Definition: keycod.hxx:49
sal_uInt16 GetModifier() const
Definition: keycod.hxx:52
bool IsMod2() const
Definition: keycod.hxx:58
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2806
vcl::Window * GetParent() const
Definition: window2.cxx:1123
const OUString & get_id() const
Get the ID of the window.
Definition: window.cxx:3935
static DockingManager * GetDockingManager()
Definition: window2.cxx:834
void GrabFocus()
Definition: window.cxx:2976
virtual Point GetPosPixel() const
Definition: window.cxx:2794
WinBits GetStyle() const
Definition: window2.cxx:979
virtual Size GetSizePixel() const
Definition: window.cxx:2402
std::function< std::unique_ptr< UIObject >(vcl::Window *)> FactoryFunction
constexpr sal_uInt16 KEY_RETURN
Definition: keycodes.hxx:119
constexpr sal_uInt16 KEY_DOWN
Definition: keycodes.hxx:110
constexpr sal_uInt16 KEY_SPACE
Definition: keycodes.hxx:123
IMPL_LINK_NOARG(MenuButton, ImplMenuTimeoutHdl, Timer *, void)
Definition: menubtn.cxx:171
int i
std::map< OUString, OUString > aParameters
OUString sId
FloatWinPopupFlags
Definition: vclenum.hxx:323
sal_Int64 WinBits
Definition: wintypes.hxx:109
WindowType
Definition: wintypes.hxx:27
WinBits const WB_NOTABSTOP
Definition: wintypes.hxx:141
WinBits const WB_NOPOINTERFOCUS
Definition: wintypes.hxx:155
WinBits const WB_TABSTOP
Definition: wintypes.hxx:140