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/button.hxx>
22 #include <vcl/layout.hxx>
23 #include <vcl/notebookbar.hxx>
24 #include <vcl/tabpage.hxx>
25 #include <sfx2/viewfrm.hxx>
26 #include <notebookbar/NotebookbarTabControl.hxx>
27 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
28 #include <com/sun/star/ui/ItemType.hpp>
29 #include <com/sun/star/frame/XModuleManager.hpp>
30 #include <com/sun/star/frame/ModuleManager.hpp>
31 #include <com/sun/star/frame/XFrame.hpp>
32 #include <com/sun/star/uno/Reference.h>
33 #include <toolkit/awt/vclxmenu.hxx>
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 <cppuhelper/implbase.hxx>
41 #define TOOLBAR_STR "private:resource/toolbar/notebookbarshortcuts"
43 using namespace css::uno
;
44 using namespace css::ui
;
45 using namespace css::frame
;
47 class ChangedUIEventListener
: public ::cppu::WeakImplHelper
<XUIConfigurationListener
>
49 VclPtr
<NotebookbarTabControl
> m_pParent
;
52 explicit ChangedUIEventListener(NotebookbarTabControl
*p
)
57 if( SfxViewFrame::Current() )
59 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
60 const Reference
<XModuleManager
> xModuleManager
= ModuleManager::create( xContext
);
61 Reference
<XFrame
> xFrame
= SfxViewFrame::Current()->GetFrame().GetFrameInterface();
62 OUString aModuleName
= xModuleManager
->identify( xFrame
);
64 Reference
<XUIConfigurationManager
> m_xConfigManager
;
65 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgMgrSupplier(
66 theModuleUIConfigurationManagerSupplier::get( xContext
) );
67 m_xConfigManager
.set( xModuleCfgMgrSupplier
->getUIConfigurationManager( aModuleName
) );
68 css::uno::Reference
< css::ui::XUIConfiguration
> xConfig( m_xConfigManager
, css::uno::UNO_QUERY_THROW
);
69 xConfig
->addConfigurationListener( this );
72 catch( const css::uno::RuntimeException
& ) {}
75 // XUIConfigurationListener
76 virtual void SAL_CALL
elementInserted( const ConfigurationEvent
& rEvent
) override
78 if( rEvent
.ResourceURL
== TOOLBAR_STR
)
80 m_pParent
->m_bInvalidate
= true;
81 m_pParent
->StateChanged(StateChangedType::UpdateMode
);
85 virtual void SAL_CALL
elementRemoved( const ConfigurationEvent
& rEvent
) override
87 elementInserted( rEvent
);
90 virtual void SAL_CALL
elementReplaced( const ConfigurationEvent
& rEvent
) override
92 elementInserted( rEvent
);
95 virtual void SAL_CALL
disposing(const ::css::lang::EventObject
&) override
99 if( SfxViewFrame::Current() )
101 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
102 const Reference
<XModuleManager
> xModuleManager
= ModuleManager::create( xContext
);
103 Reference
<XFrame
> xFrame
= SfxViewFrame::Current()->GetFrame().GetFrameInterface();
104 OUString aModuleName
= xModuleManager
->identify( xFrame
);
106 Reference
<XUIConfigurationManager
> m_xConfigManager
;
107 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgMgrSupplier(
108 theModuleUIConfigurationManagerSupplier::get( xContext
) );
109 m_xConfigManager
.set( xModuleCfgMgrSupplier
->getUIConfigurationManager( aModuleName
) );
110 css::uno::Reference
< css::ui::XUIConfiguration
> xConfig( m_xConfigManager
, css::uno::UNO_QUERY_THROW
);
111 xConfig
->removeConfigurationListener( this );
114 catch( const css::uno::RuntimeException
& ) {}
122 class ShortcutsToolBox
: public sfx2::sidebar::SidebarToolBox
125 ShortcutsToolBox( Window
* pParent
)
126 : sfx2::sidebar::SidebarToolBox( pParent
)
128 mbUseDefaultButtonSize
= false;
130 SetToolboxButtonSize(ToolBoxButtonSize::Small
);
133 virtual void KeyInput( const KeyEvent
& rKEvt
) override
135 if ( rKEvt
.GetKeyCode().IsMod1() )
137 sal_uInt16
nCode( rKEvt
.GetKeyCode().GetCode() );
138 if ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
)
140 GetParent()->KeyInput( rKEvt
);
144 return sfx2::sidebar::SidebarToolBox::KeyInput( rKEvt
);
150 NotebookbarTabControl::NotebookbarTabControl( Window
* pParent
)
151 : NotebookbarTabControlBase( pParent
)
152 , m_bInitialized( false )
153 , m_bInvalidate( true )
157 NotebookbarTabControl::~NotebookbarTabControl()
161 void NotebookbarTabControl::ArrowStops( sal_uInt16 nCode
)
163 ToolBox
* pToolBox( GetToolBox() );
164 PushButton
* pOpenMenu( GetOpenMenu() );
166 if ( nCode
== KEY_LEFT
)
171 pToolBox
->GrabFocus();
172 else if ( pOpenMenu
)
173 pOpenMenu
->GrabFocus();
175 else if ( pToolBox
&& pToolBox
->HasFocus() )
178 pOpenMenu
->GrabFocus();
182 else if ( pOpenMenu
&& pOpenMenu
->HasFocus() )
187 else if ( nCode
== KEY_RIGHT
)
192 pOpenMenu
->GrabFocus();
194 pToolBox
->GrabFocus();
196 else if ( pToolBox
&& pToolBox
->HasFocus() )
200 else if ( pOpenMenu
&& pOpenMenu
->HasFocus() )
203 pToolBox
->GrabFocus();
210 void NotebookbarTabControl::KeyInput( const KeyEvent
& rKEvt
)
212 if ( rKEvt
.GetKeyCode().IsMod1() )
214 sal_uInt16
nCode( rKEvt
.GetKeyCode().GetCode() );
215 if ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
)
221 return NotebookbarTabControlBase::KeyInput( rKEvt
);
224 bool NotebookbarTabControl::EventNotify( NotifyEvent
& rNEvt
)
226 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
228 const vcl::KeyCode
& rKey
= rNEvt
.GetKeyEvent()->GetKeyCode();
229 sal_uInt16 nCode
= rKey
.GetCode();
230 if ( rKey
.IsMod1() && ( nCode
== KEY_RIGHT
|| nCode
== KEY_LEFT
) )
236 return NotebookbarTabControlBase::EventNotify( rNEvt
);
239 void NotebookbarTabControl::StateChanged(StateChangedType nStateChange
)
241 if( !m_bInitialized
&& SfxViewFrame::Current() )
243 VclPtr
<ShortcutsToolBox
> pShortcuts
= VclPtr
<ShortcutsToolBox
>::Create( this );
246 SetToolBox( static_cast<ToolBox
*>( pShortcuts
.get() ) );
247 SetIconClickHdl( LINK( this, NotebookbarTabControl
, OpenNotebookbarPopupMenu
) );
249 m_pListener
= new ChangedUIEventListener( this );
251 m_bInitialized
= true;
253 if( m_bInitialized
&& m_bInvalidate
&& SfxViewFrame::Current() )
255 ToolBox
* pToolBox
= GetToolBox();
261 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
262 const Reference
<XModuleManager
> xModuleManager
= ModuleManager::create( xContext
);
263 m_xFrame
= SfxViewFrame::Current()->GetFrame().GetFrameInterface();
264 OUString aModuleName
= xModuleManager
->identify( m_xFrame
);
266 FillShortcutsToolBox( xContext
, m_xFrame
, aModuleName
, pToolBox
);
268 Size
aSize( pToolBox
->GetOptimalSize() );
269 Point
aPos( ICON_SIZE
+ 10, 0 );
270 pToolBox
->SetPosSizePixel( aPos
, aSize
);
271 ImplPlaceTabs( GetSizePixel().getWidth() );
273 m_bInvalidate
= false;
275 NotebookbarTabControlBase::StateChanged( nStateChange
);
278 void NotebookbarTabControl::FillShortcutsToolBox(Reference
<XComponentContext
> const & xContext
,
279 const Reference
<XFrame
>& xFrame
,
280 const OUString
& aModuleName
,
284 Reference
<::com::sun::star::container::XIndexAccess
> xIndex
;
288 Reference
<XUIConfigurationManager
> m_xConfigManager
;
289 Reference
<XModuleUIConfigurationManagerSupplier
> xModuleCfgMgrSupplier(
290 theModuleUIConfigurationManagerSupplier::get( xContext
) );
291 m_xConfigManager
.set( xModuleCfgMgrSupplier
->getUIConfigurationManager( aModuleName
) );
292 xIndex
= m_xConfigManager
->getSettings( TOOLBAR_STR
, false );
294 catch( const Exception
& ) {}
299 Sequence
< css::beans::PropertyValue
> aPropSequence
;
300 for ( sal_Int32 i
= 0; i
< xIndex
->getCount(); ++i
)
304 if ( xIndex
->getByIndex( i
) >>= aPropSequence
)
306 OUString aCommandURL
;
307 sal_uInt16 nType
= ItemType::DEFAULT
;
308 bool bVisible
= true;
310 for ( const auto& aProp
: std::as_const(aPropSequence
) )
312 if ( aProp
.Name
== "CommandURL" )
313 aProp
.Value
>>= aCommandURL
;
314 else if ( aProp
.Name
== "Type" )
315 aProp
.Value
>>= nType
;
316 else if ( aProp
.Name
== "IsVisible" )
317 aProp
.Value
>>= bVisible
;
319 if ( bVisible
&& ( nType
== ItemType::DEFAULT
) )
320 pShortcuts
->InsertItem( aCommandURL
, xFrame
, ToolBoxItemBits::ICON_ONLY
, Size( ICON_SIZE
, ICON_SIZE
) );
323 catch ( const Exception
& )
330 IMPL_LINK(NotebookbarTabControl
, OpenNotebookbarPopupMenu
, NotebookBar
*, pNotebookbar
, void)
332 if (!pNotebookbar
|| !m_xFrame
.is())
335 Sequence
<Any
> aArgs
{
336 makeAny(comphelper::makePropertyValue("Value", OUString("notebookbar"))),
337 makeAny(comphelper::makePropertyValue("Frame", m_xFrame
)) };
339 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
340 Reference
<XPopupMenuController
> xPopupController(
341 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(
342 "com.sun.star.comp.framework.ResourceMenuController", aArgs
, xContext
), UNO_QUERY
);
344 Reference
<css::awt::XPopupMenu
> xPopupMenu(xContext
->getServiceManager()->createInstanceWithContext(
345 "com.sun.star.awt.PopupMenu", xContext
), UNO_QUERY
);
347 if (!xPopupController
.is() || !xPopupMenu
.is())
350 xPopupController
->setPopupMenu(xPopupMenu
);
351 VCLXMenu
* pAwtMenu
= comphelper::getUnoTunnelImplementation
<VCLXMenu
>(xPopupMenu
);
352 PopupMenu
* pVCLMenu
= static_cast<PopupMenu
*>(pAwtMenu
->GetMenu());
353 Point
aPos(pNotebookbar
->GetSizePixel().getWidth(), NotebookbarTabControl::GetHeaderHeight() - ICON_SIZE
+ 10);
354 pVCLMenu
->Execute(pNotebookbar
, tools::Rectangle(aPos
, aPos
),PopupMenuFlags::ExecuteDown
|PopupMenuFlags::NoMouseUpClose
);
356 Reference
<css::lang::XComponent
> xComponent(xPopupController
, UNO_QUERY
);
358 xComponent
->dispose();
361 Size
NotebookbarTabControl::calculateRequisition() const
363 Size aSize
= NotebookbarTabControlBase::calculateRequisition();
365 for (int i
= 0; i
< GetPageCount(); i
++)
367 vcl::Window
* pChild
= GetTabPage(TabControl::GetPageId(i
));
371 Size aChildSize
= VclAlignment::getLayoutRequisition(*pChild
);
373 if (aChildSize
.getWidth() < aSize
.getWidth())
374 aSize
.setWidth( aChildSize
.Width() );
378 if (aSize
.Width() < 400)
379 aSize
.setWidth( 400 );
384 VCL_BUILDER_FACTORY( NotebookbarTabControl
)
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */