LibreOffice Module sfx2 (master) 1
NotebookbarTabControl.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
21#include <vcl/layout.hxx>
23#include <vcl/tabpage.hxx>
24#include <sfx2/viewfrm.hxx>
26#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
27#include <com/sun/star/ui/ItemType.hpp>
28#include <com/sun/star/frame/XModuleManager.hpp>
29#include <com/sun/star/frame/ModuleManager.hpp>
30#include <com/sun/star/frame/XFrame.hpp>
31#include <com/sun/star/uno/Reference.h>
32#include <com/sun/star/awt/PopupMenuDirection.hpp>
33#include <com/sun/star/awt/XVclWindowPeer.hpp>
34#include <com/sun/star/frame/XPopupMenuController.hpp>
40
41#define ICON_SIZE 25
42constexpr OUStringLiteral TOOLBAR_STR = u"private:resource/toolbar/notebookbarshortcuts";
43
44using namespace css::uno;
45using namespace css::ui;
46using namespace css::frame;
47
48class ChangedUIEventListener : public ::cppu::WeakImplHelper<XUIConfigurationListener>
49{
51
52public:
54 : m_pParent(p)
55 {
56 try
57 {
58 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
59 {
60 Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
61 const Reference<XModuleManager> xModuleManager = ModuleManager::create( xContext );
62 Reference<XFrame> xFrame = pViewFrm->GetFrame().GetFrameInterface();
63 OUString aModuleName = xModuleManager->identify( xFrame );
64
65 Reference<XUIConfigurationManager> m_xConfigManager;
66 Reference<XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
67 theModuleUIConfigurationManagerSupplier::get( xContext ) );
68 m_xConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleName ) );
69 css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY_THROW );
70 xConfig->addConfigurationListener( this );
71 }
72 }
73 catch( const css::uno::RuntimeException& ) {}
74 }
75
76 // XUIConfigurationListener
77 virtual void SAL_CALL elementInserted( const ConfigurationEvent& rEvent ) override
78 {
79 if( rEvent.ResourceURL == TOOLBAR_STR )
80 {
81 m_pParent->m_bInvalidate = true;
82 m_pParent->StateChanged(StateChangedType::UpdateMode);
83 }
84 }
85
86 virtual void SAL_CALL elementRemoved( const ConfigurationEvent& rEvent ) override
87 {
88 elementInserted( rEvent );
89 }
90
91 virtual void SAL_CALL elementReplaced( const ConfigurationEvent& rEvent ) override
92 {
93 elementInserted( rEvent );
94 }
95
96 virtual void SAL_CALL disposing(const ::css::lang::EventObject&) override
97 {
98 try
99 {
100 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
101 {
102 Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
103 const Reference<XModuleManager> xModuleManager = ModuleManager::create( xContext );
104 Reference<XFrame> xFrame = pViewFrm->GetFrame().GetFrameInterface();
105 OUString aModuleName = xModuleManager->identify( xFrame );
106
107 Reference<XUIConfigurationManager> m_xConfigManager;
108 Reference<XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
109 theModuleUIConfigurationManagerSupplier::get( xContext ) );
110 m_xConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleName ) );
111 css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY_THROW );
112 xConfig->removeConfigurationListener( this );
113 }
114 }
115 catch( const css::uno::RuntimeException& ) {}
116
118 }
119};
120
121namespace {
122
123class ShortcutsToolBox : public sfx2::sidebar::SidebarToolBox
124{
125public:
126 ShortcutsToolBox( Window* pParent )
127 : sfx2::sidebar::SidebarToolBox( pParent )
128 {
129 mbUseDefaultButtonSize = false;
130 mbSideBar = false;
131 SetToolboxButtonSize(ToolBoxButtonSize::Small);
132 }
133
134 virtual void KeyInput( const KeyEvent& rKEvt ) override
135 {
136 if ( rKEvt.GetKeyCode().IsMod1() )
137 {
138 sal_uInt16 nCode( rKEvt.GetKeyCode().GetCode() );
139 if ( nCode == KEY_RIGHT || nCode == KEY_LEFT )
140 {
141 GetParent()->KeyInput( rKEvt );
142 return;
143 }
144 }
146 }
147};
148
149}
150
152: NotebookbarTabControlBase( pParent )
153, m_bInitialized( false )
154, m_bInvalidate( true )
155{
156}
157
159{
160}
161
162void NotebookbarTabControl::ArrowStops( sal_uInt16 nCode )
163{
164 ToolBox* pToolBox( GetToolBox() );
165 Control* pOpenMenu( GetOpenMenu() );
166
167 if ( nCode == KEY_LEFT )
168 {
169 if ( HasFocus() )
170 {
171 if ( pToolBox )
172 pToolBox->GrabFocus();
173 else if ( pOpenMenu )
174 pOpenMenu->GrabFocus();
175 }
176 else if ( pToolBox && pToolBox->HasFocus() )
177 {
178 if ( pOpenMenu )
179 pOpenMenu->GrabFocus();
180 else
181 GrabFocus();
182 }
183 else if ( pOpenMenu && pOpenMenu->HasFocus() )
184 {
185 GrabFocus();
186 }
187 }
188 else if ( nCode == KEY_RIGHT )
189 {
190 if ( HasFocus() )
191 {
192 if ( pOpenMenu )
193 pOpenMenu->GrabFocus();
194 else if ( pToolBox )
195 pToolBox->GrabFocus();
196 }
197 else if ( pToolBox && pToolBox->HasFocus() )
198 {
199 GrabFocus();
200 }
201 else if ( pOpenMenu && pOpenMenu->HasFocus() )
202 {
203 if ( pToolBox )
204 pToolBox->GrabFocus();
205 else
206 GrabFocus();
207 }
208 }
209}
210
212{
213 if ( rKEvt.GetKeyCode().IsMod1() )
214 {
215 sal_uInt16 nCode( rKEvt.GetKeyCode().GetCode() );
216 if ( nCode == KEY_RIGHT || nCode == KEY_LEFT )
217 {
218 ArrowStops( nCode );
219 return;
220 }
221 }
222 return NotebookbarTabControlBase::KeyInput( rKEvt );
223}
224
226{
227 if ( rNEvt.GetType() == NotifyEventType::KEYINPUT )
228 {
229 const vcl::KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
230 sal_uInt16 nCode = rKey.GetCode();
231 if ( rKey.IsMod1() && ( nCode == KEY_RIGHT || nCode == KEY_LEFT ) )
232 {
233 ArrowStops( nCode );
234 return true;
235 }
236 }
237 return NotebookbarTabControlBase::EventNotify( rNEvt );
238}
239
241{
243 if (!m_bInitialized && pViewFrm)
244 {
246 pShortcuts->Show();
247
248 SetToolBox( static_cast<ToolBox*>( pShortcuts.get() ) );
249 SetIconClickHdl( LINK( this, NotebookbarTabControl, OpenNotebookbarPopupMenu ) );
250
252
253 m_bInitialized = true;
254 }
255 if (m_bInitialized && m_bInvalidate && pViewFrm)
256 {
257 ToolBox* pToolBox = GetToolBox();
258 if( !pToolBox )
259 return;
260
261 pToolBox->Clear();
262
263 Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
264 const Reference<XModuleManager> xModuleManager = ModuleManager::create( xContext );
265 m_xFrame = pViewFrm->GetFrame().GetFrameInterface();
266 OUString aModuleName = xModuleManager->identify( m_xFrame );
267
268 FillShortcutsToolBox( xContext, m_xFrame, aModuleName, pToolBox );
269
270 Size aSize( pToolBox->GetOptimalSize() );
271 Point aPos( ICON_SIZE + 10, 0 );
272 pToolBox->SetPosSizePixel( aPos, aSize );
273 ImplPlaceTabs( GetSizePixel().getWidth() );
274
275 m_bInvalidate = false;
276 }
277 NotebookbarTabControlBase::StateChanged( nStateChange );
278}
279
280void NotebookbarTabControl::FillShortcutsToolBox(Reference<XComponentContext> const & xContext,
281 const Reference<XFrame>& xFrame,
282 const OUString& aModuleName,
283 ToolBox* pShortcuts
284)
285{
286 Reference<::com::sun::star::container::XIndexAccess> xIndex;
287
288 try
289 {
290 Reference<XUIConfigurationManager> m_xConfigManager;
291 Reference<XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
292 theModuleUIConfigurationManagerSupplier::get( xContext ) );
293 m_xConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleName ) );
294 xIndex = m_xConfigManager->getSettings( TOOLBAR_STR, false );
295 }
296 catch( const Exception& ) {}
297
298 if ( !xIndex.is() )
299 return;
300
301 Sequence< css::beans::PropertyValue > aPropSequence;
302 for ( sal_Int32 i = 0; i < xIndex->getCount(); ++i )
303 {
304 try
305 {
306 if ( xIndex->getByIndex( i ) >>= aPropSequence )
307 {
308 OUString aCommandURL;
309 sal_uInt16 nType = ItemType::DEFAULT;
310 bool bVisible = true;
311
312 for ( const auto& aProp: std::as_const(aPropSequence) )
313 {
314 if ( aProp.Name == "CommandURL" )
315 aProp.Value >>= aCommandURL;
316 else if ( aProp.Name == "Type" )
317 aProp.Value >>= nType;
318 else if ( aProp.Name == "IsVisible" )
319 aProp.Value >>= bVisible;
320 }
321 if ( bVisible && ( nType == ItemType::DEFAULT ) )
322 pShortcuts->InsertItem( aCommandURL, xFrame, ToolBoxItemBits::ICON_ONLY, Size( ICON_SIZE, ICON_SIZE ) );
323 }
324 }
325 catch ( const Exception& )
326 {
327 break;
328 }
329 }
330}
331
332IMPL_LINK(NotebookbarTabControl, OpenNotebookbarPopupMenu, NotebookBar*, pNotebookbar, void)
333{
334 if (!pNotebookbar || !m_xFrame.is())
335 return;
336
337 Sequence<Any> aArgs {
338 Any(comphelper::makePropertyValue("Value", OUString("notebookbar"))),
340
341 Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
342 Reference<XPopupMenuController> xPopupController(
343 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
344 "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext), UNO_QUERY);
345
347
348 if (!xPopupController.is() || !xPopupMenu.is())
349 return;
350
351 xPopupController->setPopupMenu(xPopupMenu);
352 Point aPos(pNotebookbar->GetSizePixel().getWidth(), NotebookbarTabControl::GetHeaderHeight() - ICON_SIZE + 10);
353 xPopupMenu->execute(pNotebookbar->GetComponentInterface(),
354 css::awt::Rectangle(aPos.X(), aPos.Y(), 1, 1),
355 css::awt::PopupMenuDirection::EXECUTE_DOWN);
356
357 Reference<css::lang::XComponent> xComponent(xPopupController, UNO_QUERY);
358 if (xComponent.is())
359 xComponent->dispose();
360}
361
363{
364 Size aSize = NotebookbarTabControlBase::calculateRequisition();
365
366 for (int i = 0; i < GetPageCount(); i++)
367 {
368 vcl::Window* pChild = GetTabPage(TabControl::GetPageId(i));
369
370 if (pChild)
371 {
372 Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
373
374 if (aChildSize.getWidth() < aSize.getWidth())
375 aSize.setWidth( aChildSize.Width() );
376 }
377 }
378
379 if (aSize.Width() < 400)
380 aSize.setWidth( 400 );
381
382 return aSize;
383}
384
386
387/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr OUStringLiteral TOOLBAR_STR
IMPL_LINK(NotebookbarTabControl, OpenNotebookbarPopupMenu, NotebookBar *, pNotebookbar, void)
#define ICON_SIZE
css::uno::Reference< css::lang::XComponent > m_xFrame
#define VCL_BUILDER_FACTORY(typeName)
virtual void SAL_CALL elementRemoved(const ConfigurationEvent &rEvent) override
virtual void SAL_CALL disposing(const ::css::lang::EventObject &) override
virtual void SAL_CALL elementReplaced(const ConfigurationEvent &rEvent) override
virtual void SAL_CALL elementInserted(const ConfigurationEvent &rEvent) override
ChangedUIEventListener(NotebookbarTabControl *p)
VclPtr< NotebookbarTabControl > m_pParent
const vcl::KeyCode & GetKeyCode() const
css::uno::Reference< css::frame::XFrame > m_xFrame
css::uno::Reference< css::ui::XUIConfigurationListener > m_pListener
virtual Size calculateRequisition() const override
virtual void KeyInput(const KeyEvent &rKEvt) override
virtual bool EventNotify(NotifyEvent &rNEvt) override
static void FillShortcutsToolBox(css::uno::Reference< css::uno::XComponentContext > const &xContext, const css::uno::Reference< css::frame::XFrame > &xFrame, const OUString &aModuleName, ToolBox *pShortcuts)
void ArrowStops(sal_uInt16 nCode)
virtual void StateChanged(StateChangedType nStateChange) override
NotebookbarTabControl(Window *pParent)
const KeyEvent * GetKeyEvent() const
NotifyEventType GetType() const
constexpr tools::Long Y() const
constexpr tools::Long X() const
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
Definition: frame.cxx:515
static SAL_WARN_UNUSED_RESULT SfxViewFrame * Current()
Definition: viewfrm.cxx:1975
SfxFrame & GetFrame() const
Definition: viewfrm.cxx:2782
constexpr tools::Long getWidth() const
void setWidth(tools::Long nWidth)
constexpr tools::Long Width() const
sal_uInt16 GetPageId(sal_uInt16 nPos) const
virtual Size GetOptimalSize() const override
virtual void InsertItem(const OUString &rCommand, const css::uno::Reference< css::frame::XFrame > &rFrame, ToolBoxItemBits nBits, const Size &rRequestedSize, ImplToolItems::size_type nPos=APPEND)
void Clear()
void SetToolboxButtonSize(ToolBoxButtonSize eSize)
static Size getLayoutRequisition(const vcl::Window &rWindow)
void clear()
reference_type * get() const
static VclPtr< reference_type > Create(Arg &&... arg)
The sidebar tool box has two responsibilities:
virtual void KeyInput(const KeyEvent &rKEvt) override
bool IsMod1() const
sal_uInt16 GetCode() const
vcl::Window * GetParent() const
void GrabFocus()
bool HasFocus() const
virtual void KeyInput(const KeyEvent &rKEvt)
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
float u
void * p
constexpr sal_uInt16 KEY_LEFT
constexpr sal_uInt16 KEY_RIGHT
@ Exception
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
QPRO_FUNC_TYPE nType
Reference< XFrame > xFrame
bool bVisible
StateChangedType