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/frame/XPopupMenuController.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/propertyvalue.hxx>
36 #include <sidebar/SidebarToolBox.hxx>
37 #include <cppuhelper/implbase.hxx>
40 #define TOOLBAR_STR "private:resource/toolbar/notebookbarshortcuts"
42 using namespace css::uno
;
43 using namespace css::ui
;
44 using namespace css::frame
;
46 class ChangedUIEventListener
: public ::cppu::WeakImplHelper
<XUIConfigurationListener
>
48 VclPtr
<NotebookbarTabControl
> m_pParent
;
51 explicit ChangedUIEventListener(NotebookbarTabControl
*p
)
56 if( SfxViewFrame::Current() )
58 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
59 const Reference
<XModuleManager
> xModuleManager
= ModuleManager::create( xContext
);
60 Reference
<XFrame
> xFrame
= SfxViewFrame::Current()->GetFrame().GetFrameInterface();
61 OUString aModuleName
= xModuleManager
->identify( xFrame
);
63 Reference
<XUIConfigurationManager
> m_xConfigManager
;
64 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgMgrSupplier(
65 theModuleUIConfigurationManagerSupplier::get( xContext
) );
66 m_xConfigManager
.set( xModuleCfgMgrSupplier
->getUIConfigurationManager( aModuleName
) );
67 css::uno::Reference
< css::ui::XUIConfiguration
> xConfig( m_xConfigManager
, css::uno::UNO_QUERY_THROW
);
68 xConfig
->addConfigurationListener( this );
71 catch( const css::uno::RuntimeException
& ) {}
74 // XUIConfigurationListener
75 virtual void SAL_CALL
elementInserted( const ConfigurationEvent
& rEvent
) override
77 if( rEvent
.ResourceURL
== TOOLBAR_STR
)
79 m_pParent
->m_bInvalidate
= true;
80 m_pParent
->StateChanged(StateChangedType::UpdateMode
);
84 virtual void SAL_CALL
elementRemoved( const ConfigurationEvent
& rEvent
) override
86 elementInserted( rEvent
);
89 virtual void SAL_CALL
elementReplaced( const ConfigurationEvent
& rEvent
) override
91 elementInserted( rEvent
);
94 virtual void SAL_CALL
disposing(const ::css::lang::EventObject
&) override
98 if( SfxViewFrame::Current() )
100 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
101 const Reference
<XModuleManager
> xModuleManager
= ModuleManager::create( xContext
);
102 Reference
<XFrame
> xFrame
= SfxViewFrame::Current()->GetFrame().GetFrameInterface();
103 OUString aModuleName
= xModuleManager
->identify( xFrame
);
105 Reference
<XUIConfigurationManager
> m_xConfigManager
;
106 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgMgrSupplier(
107 theModuleUIConfigurationManagerSupplier::get( xContext
) );
108 m_xConfigManager
.set( xModuleCfgMgrSupplier
->getUIConfigurationManager( aModuleName
) );
109 css::uno::Reference
< css::ui::XUIConfiguration
> xConfig( m_xConfigManager
, css::uno::UNO_QUERY_THROW
);
110 xConfig
->removeConfigurationListener( this );
113 catch( const css::uno::RuntimeException
& ) {}
121 class ShortcutsToolBox
: public sfx2::sidebar::SidebarToolBox
124 ShortcutsToolBox( Window
* pParent
)
125 : sfx2::sidebar::SidebarToolBox( pParent
)
127 mbUseDefaultButtonSize
= false;
129 SetToolboxButtonSize(ToolBoxButtonSize::Small
);
132 virtual void KeyInput( const KeyEvent
& rKEvt
) override
134 if ( rKEvt
.GetKeyCode().IsMod1() )
136 sal_uInt16
nCode( rKEvt
.GetKeyCode().GetCode() );
137 if ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
)
139 GetParent()->KeyInput( rKEvt
);
143 return sfx2::sidebar::SidebarToolBox::KeyInput( rKEvt
);
149 NotebookbarTabControl::NotebookbarTabControl( Window
* pParent
)
150 : NotebookbarTabControlBase( pParent
)
151 , m_bInitialized( false )
152 , m_bInvalidate( true )
156 NotebookbarTabControl::~NotebookbarTabControl()
160 void NotebookbarTabControl::ArrowStops( sal_uInt16 nCode
)
162 ToolBox
* pToolBox( GetToolBox() );
163 Control
* pOpenMenu( GetOpenMenu() );
165 if ( nCode
== KEY_LEFT
)
170 pToolBox
->GrabFocus();
171 else if ( pOpenMenu
)
172 pOpenMenu
->GrabFocus();
174 else if ( pToolBox
&& pToolBox
->HasFocus() )
177 pOpenMenu
->GrabFocus();
181 else if ( pOpenMenu
&& pOpenMenu
->HasFocus() )
186 else if ( nCode
== KEY_RIGHT
)
191 pOpenMenu
->GrabFocus();
193 pToolBox
->GrabFocus();
195 else if ( pToolBox
&& pToolBox
->HasFocus() )
199 else if ( pOpenMenu
&& pOpenMenu
->HasFocus() )
202 pToolBox
->GrabFocus();
209 void NotebookbarTabControl::KeyInput( const KeyEvent
& rKEvt
)
211 if ( rKEvt
.GetKeyCode().IsMod1() )
213 sal_uInt16
nCode( rKEvt
.GetKeyCode().GetCode() );
214 if ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
)
220 return NotebookbarTabControlBase::KeyInput( rKEvt
);
223 bool NotebookbarTabControl::EventNotify( NotifyEvent
& rNEvt
)
225 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
227 const vcl::KeyCode
& rKey
= rNEvt
.GetKeyEvent()->GetKeyCode();
228 sal_uInt16 nCode
= rKey
.GetCode();
229 if ( rKey
.IsMod1() && ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
) )
235 return NotebookbarTabControlBase::EventNotify( rNEvt
);
238 void NotebookbarTabControl::StateChanged(StateChangedType nStateChange
)
240 if( !m_bInitialized
&& SfxViewFrame::Current() )
242 VclPtr
<ShortcutsToolBox
> pShortcuts
= VclPtr
<ShortcutsToolBox
>::Create( this );
245 SetToolBox( static_cast<ToolBox
*>( pShortcuts
.get() ) );
246 SetIconClickHdl( LINK( this, NotebookbarTabControl
, OpenNotebookbarPopupMenu
) );
248 m_pListener
= new ChangedUIEventListener( this );
250 m_bInitialized
= true;
252 if( m_bInitialized
&& m_bInvalidate
&& SfxViewFrame::Current() )
254 ToolBox
* pToolBox
= GetToolBox();
260 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
261 const Reference
<XModuleManager
> xModuleManager
= ModuleManager::create( xContext
);
262 m_xFrame
= SfxViewFrame::Current()->GetFrame().GetFrameInterface();
263 OUString aModuleName
= xModuleManager
->identify( m_xFrame
);
265 FillShortcutsToolBox( xContext
, m_xFrame
, aModuleName
, pToolBox
);
267 Size
aSize( pToolBox
->GetOptimalSize() );
268 Point
aPos( ICON_SIZE
+ 10, 0 );
269 pToolBox
->SetPosSizePixel( aPos
, aSize
);
270 ImplPlaceTabs( GetSizePixel().getWidth() );
272 m_bInvalidate
= false;
274 NotebookbarTabControlBase::StateChanged( nStateChange
);
277 void NotebookbarTabControl::FillShortcutsToolBox(Reference
<XComponentContext
> const & xContext
,
278 const Reference
<XFrame
>& xFrame
,
279 const OUString
& aModuleName
,
283 Reference
<::com::sun::star::container::XIndexAccess
> xIndex
;
287 Reference
<XUIConfigurationManager
> m_xConfigManager
;
288 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgMgrSupplier(
289 theModuleUIConfigurationManagerSupplier::get( xContext
) );
290 m_xConfigManager
.set( xModuleCfgMgrSupplier
->getUIConfigurationManager( aModuleName
) );
291 xIndex
= m_xConfigManager
->getSettings( TOOLBAR_STR
, false );
293 catch( const Exception
& ) {}
298 Sequence
< css::beans::PropertyValue
> aPropSequence
;
299 for ( sal_Int32 i
= 0; i
< xIndex
->getCount(); ++i
)
303 if ( xIndex
->getByIndex( i
) >>= aPropSequence
)
305 OUString aCommandURL
;
306 sal_uInt16 nType
= ItemType::DEFAULT
;
307 bool bVisible
= true;
309 for ( const auto& aProp
: std::as_const(aPropSequence
) )
311 if ( aProp
.Name
== "CommandURL" )
312 aProp
.Value
>>= aCommandURL
;
313 else if ( aProp
.Name
== "Type" )
314 aProp
.Value
>>= nType
;
315 else if ( aProp
.Name
== "IsVisible" )
316 aProp
.Value
>>= bVisible
;
318 if ( bVisible
&& ( nType
== ItemType::DEFAULT
) )
319 pShortcuts
->InsertItem( aCommandURL
, xFrame
, ToolBoxItemBits::ICON_ONLY
, Size( ICON_SIZE
, ICON_SIZE
) );
322 catch ( const Exception
& )
329 IMPL_LINK(NotebookbarTabControl
, OpenNotebookbarPopupMenu
, NotebookBar
*, pNotebookbar
, void)
331 if (!pNotebookbar
|| !m_xFrame
.is())
334 Sequence
<Any
> aArgs
{
335 makeAny(comphelper::makePropertyValue("Value", OUString("notebookbar"))),
336 makeAny(comphelper::makePropertyValue("Frame", m_xFrame
)) };
338 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
339 Reference
<XPopupMenuController
> xPopupController(
340 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(
341 "com.sun.star.comp.framework.ResourceMenuController", aArgs
, xContext
), UNO_QUERY
);
343 Reference
<css::awt::XPopupMenu
> xPopupMenu(xContext
->getServiceManager()->createInstanceWithContext(
344 "com.sun.star.awt.PopupMenu", xContext
), UNO_QUERY
);
346 if (!xPopupController
.is() || !xPopupMenu
.is())
349 xPopupController
->setPopupMenu(xPopupMenu
);
350 Point
aPos(pNotebookbar
->GetSizePixel().getWidth(), NotebookbarTabControl::GetHeaderHeight() - ICON_SIZE
+ 10);
351 xPopupMenu
->execute(pNotebookbar
->GetComponentInterface(),
352 css::awt::Rectangle(aPos
.X(), aPos
.Y(), 1, 1),
353 css::awt::PopupMenuDirection::EXECUTE_DOWN
);
355 Reference
<css::lang::XComponent
> xComponent(xPopupController
, UNO_QUERY
);
357 xComponent
->dispose();
360 Size
NotebookbarTabControl::calculateRequisition() const
362 Size aSize
= NotebookbarTabControlBase::calculateRequisition();
364 for (int i
= 0; i
< GetPageCount(); i
++)
366 vcl::Window
* pChild
= GetTabPage(TabControl::GetPageId(i
));
370 Size aChildSize
= VclContainer::getLayoutRequisition(*pChild
);
372 if (aChildSize
.getWidth() < aSize
.getWidth())
373 aSize
.setWidth( aChildSize
.Width() );
377 if (aSize
.Width() < 400)
378 aSize
.setWidth( 400 );
383 VCL_BUILDER_FACTORY( NotebookbarTabControl
)
385 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */