1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/builderfactory.hxx>
21 #include <vcl/layout.hxx>
22 #include <vcl/notebookbar/notebookbar.hxx>
23 #include <vcl/tabpage.hxx>
24 #include <sfx2/viewfrm.hxx>
25 #include <notebookbar/NotebookbarTabControl.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>
35 #include <comphelper/processfactory.hxx>
36 #include <comphelper/propertyvalue.hxx>
37 #include <sidebar/SidebarToolBox.hxx>
38 #include <toolkit/awt/vclxmenu.hxx>
39 #include <cppuhelper/implbase.hxx>
42 constexpr OUString TOOLBAR_STR
= u
"private:resource/toolbar/notebookbarshortcuts"_ustr
;
44 using namespace css::uno
;
45 using namespace css::ui
;
46 using namespace css::frame
;
48 class ChangedUIEventListener
: public ::cppu::WeakImplHelper
<XUIConfigurationListener
>
50 VclPtr
<NotebookbarTabControl
> m_pParent
;
53 explicit ChangedUIEventListener(NotebookbarTabControl
*p
)
58 if (SfxViewFrame
* pViewFrm
= SfxViewFrame::Current())
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
);
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 );
73 catch( const css::uno::RuntimeException
& ) {}
76 // XUIConfigurationListener
77 virtual void SAL_CALL
elementInserted( const ConfigurationEvent
& rEvent
) override
79 if( rEvent
.ResourceURL
== TOOLBAR_STR
)
81 m_pParent
->m_bInvalidate
= true;
82 m_pParent
->StateChanged(StateChangedType::UpdateMode
);
86 virtual void SAL_CALL
elementRemoved( const ConfigurationEvent
& rEvent
) override
88 elementInserted( rEvent
);
91 virtual void SAL_CALL
elementReplaced( const ConfigurationEvent
& rEvent
) override
93 elementInserted( rEvent
);
96 virtual void SAL_CALL
disposing(const ::css::lang::EventObject
&) override
100 if (SfxViewFrame
* pViewFrm
= SfxViewFrame::Current())
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
);
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 );
115 catch( const css::uno::RuntimeException
& ) {}
123 class ShortcutsToolBox
: public sfx2::sidebar::SidebarToolBox
126 ShortcutsToolBox( Window
* pParent
)
127 : sfx2::sidebar::SidebarToolBox( pParent
)
129 mbUseDefaultButtonSize
= false;
131 SetToolboxButtonSize(ToolBoxButtonSize::Small
);
134 virtual void KeyInput( const KeyEvent
& rKEvt
) override
136 if ( rKEvt
.GetKeyCode().IsMod1() )
138 sal_uInt16
nCode( rKEvt
.GetKeyCode().GetCode() );
139 if ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
)
141 GetParent()->KeyInput( rKEvt
);
145 return sfx2::sidebar::SidebarToolBox::KeyInput( rKEvt
);
151 NotebookbarTabControl::NotebookbarTabControl( Window
* pParent
)
152 : NotebookbarTabControlBase( pParent
)
153 , m_bInitialized( false )
154 , m_bInvalidate( true )
158 NotebookbarTabControl::~NotebookbarTabControl()
162 void NotebookbarTabControl::ArrowStops( sal_uInt16 nCode
)
164 ToolBox
* pToolBox( GetToolBox() );
165 Control
* pOpenMenu( GetOpenMenu() );
167 if ( nCode
== KEY_LEFT
)
172 pToolBox
->GrabFocus();
173 else if ( pOpenMenu
)
174 pOpenMenu
->GrabFocus();
176 else if ( pToolBox
&& pToolBox
->HasFocus() )
179 pOpenMenu
->GrabFocus();
183 else if ( pOpenMenu
&& pOpenMenu
->HasFocus() )
188 else if ( nCode
== KEY_RIGHT
)
193 pOpenMenu
->GrabFocus();
195 pToolBox
->GrabFocus();
197 else if ( pToolBox
&& pToolBox
->HasFocus() )
201 else if ( pOpenMenu
&& pOpenMenu
->HasFocus() )
204 pToolBox
->GrabFocus();
211 void NotebookbarTabControl::KeyInput( const KeyEvent
& rKEvt
)
213 if ( rKEvt
.GetKeyCode().IsMod1() )
215 sal_uInt16
nCode( rKEvt
.GetKeyCode().GetCode() );
216 if ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
)
222 return NotebookbarTabControlBase::KeyInput( rKEvt
);
225 bool NotebookbarTabControl::EventNotify( NotifyEvent
& rNEvt
)
227 if ( rNEvt
.GetType() == NotifyEventType::KEYINPUT
)
229 const vcl::KeyCode
& rKey
= rNEvt
.GetKeyEvent()->GetKeyCode();
230 sal_uInt16 nCode
= rKey
.GetCode();
231 if ( rKey
.IsMod1() && ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
) )
237 return NotebookbarTabControlBase::EventNotify( rNEvt
);
240 void NotebookbarTabControl::StateChanged(StateChangedType nStateChange
)
242 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
243 if (!m_bInitialized
&& pViewFrm
)
245 VclPtr
<ShortcutsToolBox
> pShortcuts
= VclPtr
<ShortcutsToolBox
>::Create( this );
248 SetToolBox( static_cast<ToolBox
*>( pShortcuts
.get() ) );
249 SetIconClickHdl( LINK( this, NotebookbarTabControl
, OpenNotebookbarPopupMenu
) );
251 m_pListener
= new ChangedUIEventListener( this );
253 m_bInitialized
= true;
255 if (m_bInitialized
&& m_bInvalidate
&& pViewFrm
)
257 ToolBox
* pToolBox
= GetToolBox();
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
);
268 FillShortcutsToolBox( xContext
, m_xFrame
, aModuleName
, pToolBox
);
270 Size
aSize( pToolBox
->GetOptimalSize() );
271 Point
aPos( ICON_SIZE
+ 10, 0 );
272 pToolBox
->SetPosSizePixel( aPos
, aSize
);
273 ImplPlaceTabs( GetSizePixel().getWidth() );
275 m_bInvalidate
= false;
277 NotebookbarTabControlBase::StateChanged( nStateChange
);
280 void NotebookbarTabControl::FillShortcutsToolBox(Reference
<XComponentContext
> const & xContext
,
281 const Reference
<XFrame
>& xFrame
,
282 const OUString
& aModuleName
,
286 Reference
<::com::sun::star::container::XIndexAccess
> xIndex
;
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 );
296 catch( const Exception
& ) {}
301 Sequence
< css::beans::PropertyValue
> aPropSequence
;
302 for ( sal_Int32 i
= 0; i
< xIndex
->getCount(); ++i
)
306 if ( xIndex
->getByIndex( i
) >>= aPropSequence
)
308 OUString aCommandURL
;
309 sal_uInt16 nType
= ItemType::DEFAULT
;
310 bool bVisible
= true;
312 for ( const auto& aProp
: std::as_const(aPropSequence
) )
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
;
321 if ( bVisible
&& ( nType
== ItemType::DEFAULT
) )
322 pShortcuts
->InsertItem( aCommandURL
, xFrame
, ToolBoxItemBits::ICON_ONLY
, Size( ICON_SIZE
, ICON_SIZE
) );
325 catch ( const Exception
& )
332 IMPL_LINK(NotebookbarTabControl
, OpenNotebookbarPopupMenu
, NotebookBar
*, pNotebookbar
, void)
334 if (!pNotebookbar
|| !m_xFrame
.is())
337 Sequence
<Any
> aArgs
{
338 Any(comphelper::makePropertyValue("Value", OUString("notebookbar"))),
339 Any(comphelper::makePropertyValue("Frame", m_xFrame
)) };
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
);
346 rtl::Reference
<VCLXPopupMenu
> xPopupMenu
= new VCLXPopupMenu();
348 if (!xPopupController
.is() || !xPopupMenu
.is())
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
);
357 Reference
<css::lang::XComponent
> xComponent(xPopupController
, UNO_QUERY
);
359 xComponent
->dispose();
362 Size
NotebookbarTabControl::calculateRequisition() const
364 Size aSize
= NotebookbarTabControlBase::calculateRequisition();
366 for (int i
= 0; i
< GetPageCount(); i
++)
368 vcl::Window
* pChild
= GetTabPage(TabControl::GetPageId(i
));
372 Size aChildSize
= VclContainer::getLayoutRequisition(*pChild
);
374 if (aChildSize
.getWidth() < aSize
.getWidth())
375 aSize
.setWidth( aChildSize
.Width() );
379 if (aSize
.Width() < 400)
380 aSize
.setWidth( 400 );
385 VCL_BUILDER_FACTORY( NotebookbarTabControl
)
387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */