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 <uielement/addonstoolbarmanager.hxx>
21 #include <uielement/toolbarmerger.hxx>
23 #include <uielement/generictoolbarcontroller.hxx>
25 #include <framework/imageproducer.hxx>
26 #include <framework/sfxhelperfunctions.hxx>
27 #include <classes/fwkresid.hxx>
28 #include <classes/resource.hrc>
29 #include <framework/addonsoptions.hxx>
30 #include <uielement/comboboxtoolbarcontroller.hxx>
31 #include <uielement/imagebuttontoolbarcontroller.hxx>
32 #include <uielement/togglebuttontoolbarcontroller.hxx>
33 #include <uielement/buttontoolbarcontroller.hxx>
34 #include <uielement/spinfieldtoolbarcontroller.hxx>
35 #include <uielement/edittoolbarcontroller.hxx>
36 #include <uielement/dropdownboxtoolbarcontroller.hxx>
38 #include <com/sun/star/ui/ItemType.hpp>
39 #include <com/sun/star/frame/ModuleManager.hpp>
40 #include <com/sun/star/frame/XToolbarController.hpp>
41 #include <com/sun/star/frame/XDispatchProvider.hpp>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 #include <com/sun/star/frame/XLayoutManager.hpp>
45 #include <com/sun/star/ui/DockingArea.hpp>
46 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
47 #include <comphelper/processfactory.hxx>
48 #include <svtools/imgdef.hxx>
49 #include <svtools/toolboxcontroller.hxx>
50 #include <toolkit/helper/vclunohelper.hxx>
52 #include <svtools/miscopt.hxx>
53 #include <vcl/svapp.hxx>
54 #include <vcl/menu.hxx>
55 #include <vcl/syswin.hxx>
56 #include <vcl/taskpanelist.hxx>
57 #include <vcl/toolbox.hxx>
58 #include <vcl/settings.hxx>
62 using namespace ::com::sun::star
;
63 using namespace ::com::sun::star::awt
;
64 using namespace ::com::sun::star::beans
;
65 using namespace ::com::sun::star::uno
;
66 using namespace ::com::sun::star::lang
;
67 using namespace ::com::sun::star::frame
;
68 using namespace ::com::sun::star::util
;
69 using namespace ::com::sun::star::container
;
70 using namespace ::com::sun::star::ui
;
75 static const char TOOLBOXITEM_SEPARATOR_STR
[] = "private:separator";
77 AddonsToolBarManager::AddonsToolBarManager( const Reference
< XComponentContext
>& rxContext
,
78 const Reference
< XFrame
>& rFrame
,
79 const OUString
& rResourceName
,
81 ToolBarManager( rxContext
, rFrame
, rResourceName
, pToolBar
)
83 m_pToolBar
->SetMenuType( TOOLBOX_MENUTYPE_CLIPPEDITEMS
);
84 m_pToolBar
->SetSelectHdl( LINK( this, AddonsToolBarManager
, Select
) );
85 m_pToolBar
->SetActivateHdl( LINK( this, AddonsToolBarManager
, Activate
) );
86 m_pToolBar
->SetDeactivateHdl( LINK( this, AddonsToolBarManager
, Deactivate
) );
87 m_pToolBar
->SetClickHdl( LINK( this, AddonsToolBarManager
, Click
) );
88 m_pToolBar
->SetDoubleClickHdl( LINK( this, AddonsToolBarManager
, DoubleClick
) );
89 m_pToolBar
->SetCommandHdl( LINK( this, AddonsToolBarManager
, Command
) );
90 m_pToolBar
->SetStateChangedHdl( LINK( this, AddonsToolBarManager
, StateChanged
) );
91 m_pToolBar
->SetDataChangedHdl( LINK( this, AddonsToolBarManager
, DataChanged
) );
94 AddonsToolBarManager::~AddonsToolBarManager()
98 static bool IsCorrectContext( const OUString
& rModuleIdentifier
, const OUString
& aContextList
)
100 if ( aContextList
.isEmpty() )
103 if ( !rModuleIdentifier
.isEmpty() )
105 sal_Int32 nIndex
= aContextList
.indexOf( rModuleIdentifier
);
106 return ( nIndex
>= 0 );
112 static Image
RetrieveImage( Reference
< com::sun::star::frame::XFrame
>& rFrame
,
113 const OUString
& aImageId
,
114 const OUString
& aURL
,
120 if ( !aImageId
.isEmpty() )
122 aImage
= framework::AddonsOptions().GetImageFromURL( aImageId
, bBigImage
);
126 aImage
= GetImageFromURL( rFrame
, aImageId
, bBigImage
);
131 aImage
= framework::AddonsOptions().GetImageFromURL( aURL
, bBigImage
);
133 aImage
= GetImageFromURL( rFrame
, aImageId
, bBigImage
);
139 void SAL_CALL
AddonsToolBarManager::dispose() throw( RuntimeException
, std::exception
)
141 Reference
< XComponent
> xThis( static_cast< OWeakObject
* >(this), UNO_QUERY
);
144 // Remove addon specific data from toolbar items.
146 for ( sal_uInt16 n
= 0; n
< m_pToolBar
->GetItemCount(); n
++ )
148 sal_uInt16
nId( m_pToolBar
->GetItemId( n
) );
152 AddonsParams
* pRuntimeItemData
= static_cast<AddonsParams
*>(m_pToolBar
->GetItemData( nId
));
153 if ( pRuntimeItemData
)
154 delete pRuntimeItemData
;
155 m_pToolBar
->SetItemData( nId
, NULL
);
160 // Base class will destroy our m_pToolBar member
161 ToolBarManager::dispose();
164 bool AddonsToolBarManager::MenuItemAllowed( sal_uInt16 nId
) const
166 if (( nId
== MENUITEM_TOOLBAR_VISIBLEBUTTON
) ||
167 ( nId
== MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR
))
173 void AddonsToolBarManager::RefreshImages()
175 bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
176 for ( sal_uInt16 nPos
= 0; nPos
< m_pToolBar
->GetItemCount(); nPos
++ )
178 sal_uInt16
nId( m_pToolBar
->GetItemId( nPos
) );
182 OUString aCommandURL
= m_pToolBar
->GetItemCommand( nId
);
184 AddonsParams
* pRuntimeItemData
= static_cast<AddonsParams
*>(m_pToolBar
->GetItemData( nId
));
185 if ( pRuntimeItemData
)
186 aImageId
= pRuntimeItemData
->aImageId
;
188 m_pToolBar
->SetItemImage(
190 RetrieveImage( m_xFrame
, aImageId
, aCommandURL
, bBigImages
)
194 m_pToolBar
->SetToolboxButtonSize( bBigImages
? TOOLBOX_BUTTONSIZE_LARGE
: TOOLBOX_BUTTONSIZE_SMALL
);
195 ::Size aSize
= m_pToolBar
->CalcWindowSizePixel();
196 m_pToolBar
->SetOutputSizePixel( aSize
);
199 void AddonsToolBarManager::FillToolbar( const Sequence
< Sequence
< PropertyValue
> >& rAddonToolbar
)
211 m_aControllerMap
.clear();
213 OUString aModuleIdentifier
;
216 Reference
< XModuleManager2
> xModuleManager
= ModuleManager::create( m_xContext
);
217 aModuleIdentifier
= xModuleManager
->identify( m_xFrame
);
219 catch ( const Exception
& )
223 sal_uInt32
nElements( 0 );
224 bool bAppendSeparator( false );
225 Reference
< XWindow
> xToolbarWindow
= VCLUnoHelper::GetInterface( m_pToolBar
);
226 for ( sal_uInt32 n
= 0; n
< (sal_uInt32
)rAddonToolbar
.getLength(); n
++ )
233 OUString aControlType
;
234 sal_uInt16
nWidth( 0 );
236 const Sequence
< PropertyValue
>& rSeq
= rAddonToolbar
[n
];
238 ToolBarMerger::ConvertSequenceToValues( rSeq
, aURL
, aTitle
, aImageId
, aTarget
, aContext
, aControlType
, nWidth
);
240 if ( IsCorrectContext( aModuleIdentifier
, aContext
))
242 if ( aURL
== TOOLBOXITEM_SEPARATOR_STR
)
244 sal_uInt16 nCount
= m_pToolBar
->GetItemCount();
245 if ( nCount
> 0 && ( m_pToolBar
->GetItemType( nCount
-1 ) != ToolBoxItemType::SEPARATOR
) && nElements
> 0 )
248 m_pToolBar
->InsertSeparator();
253 sal_uInt16 nCount
= m_pToolBar
->GetItemCount();
254 if ( bAppendSeparator
&& nCount
> 0 && ( m_pToolBar
->GetItemType( nCount
-1 ) != ToolBoxItemType::SEPARATOR
))
256 // We have to append a separator first if the last item is not a separator
257 m_pToolBar
->InsertSeparator();
259 bAppendSeparator
= false;
261 m_pToolBar
->InsertItem( nId
, aTitle
);
263 // don't setup images yet, AddonsToolbarWrapper::populateImages does that.
265 // Create TbRuntimeItemData to hold additional information we will need in the future
266 AddonsParams
* pRuntimeItemData
= new AddonsParams
;
267 pRuntimeItemData
->aImageId
= aImageId
;
268 pRuntimeItemData
->aTarget
= aTarget
;
269 m_pToolBar
->SetItemData( nId
, pRuntimeItemData
);
270 m_pToolBar
->SetItemCommand( nId
, aURL
);
272 Reference
< XStatusListener
> xController
;
274 bool bMustBeInit( true );
276 // Support external toolbar controller for add-ons!
277 if ( m_xToolbarControllerFactory
.is() &&
278 m_xToolbarControllerFactory
->hasController( aURL
, m_aModuleIdentifier
))
280 Sequence
< Any
> aArgs(5);
281 PropertyValue aPropValue
;
283 aPropValue
.Name
= "ModuleIdentifier";
284 aPropValue
.Value
<<= m_aModuleIdentifier
;
285 aArgs
[0] <<= aPropValue
;
286 aPropValue
.Name
= "Frame";
287 aPropValue
.Value
<<= m_xFrame
;
288 aArgs
[1] <<= aPropValue
;
289 aPropValue
.Name
= "ServiceManager";
290 aPropValue
.Value
<<= Reference
<XMultiServiceFactory
>(m_xContext
->getServiceManager(), UNO_QUERY_THROW
);
291 aArgs
[2] <<= aPropValue
;
292 aPropValue
.Name
= "ParentWindow";
293 aPropValue
.Value
<<= xToolbarWindow
;
294 aArgs
[3] <<= aPropValue
;
295 aPropValue
.Name
= "ItemId";
296 aPropValue
.Value
= makeAny( sal_Int32( nId
));
297 aArgs
[4] <<= aPropValue
;
301 xController
= Reference
< XStatusListener
>( m_xToolbarControllerFactory
->createInstanceWithArgumentsAndContext(
302 aURL
, aArgs
, m_xContext
),
305 catch ( uno::Exception
& )
308 bMustBeInit
= false; // factory called init already!
312 ::cppu::OWeakObject
* pController
= 0;
314 pController
= ToolBarMerger::CreateController( m_xContext
, m_xFrame
, m_pToolBar
, aURL
, nId
, nWidth
, aControlType
);
315 xController
= Reference
< XStatusListener
>( pController
, UNO_QUERY
);
318 // insert controller to the map
319 m_aControllerMap
[nId
] = xController
;
321 Reference
< XInitialization
> xInit( xController
, UNO_QUERY
);
322 if ( xInit
.is() && bMustBeInit
)
324 PropertyValue aPropValue
;
325 Sequence
< Any
> aArgs( 3 );
326 aPropValue
.Name
= "Frame";
327 aPropValue
.Value
<<= m_xFrame
;
328 aArgs
[0] <<= aPropValue
;
329 aPropValue
.Name
= "CommandURL";
330 aPropValue
.Value
<<= aURL
;
331 aArgs
[1] <<= aPropValue
;
332 aPropValue
.Name
= "ServiceManager";
333 aPropValue
.Value
<<= Reference
<XMultiServiceFactory
>(m_xContext
->getServiceManager(), UNO_QUERY_THROW
);
334 aArgs
[2] <<= aPropValue
;
337 xInit
->initialize( aArgs
);
339 catch ( const uno::Exception
& )
344 // Request a item window from the toolbar controller and set it at the VCL toolbar
345 Reference
< XToolbarController
> xTbxController( xController
, UNO_QUERY
);
346 if ( xTbxController
.is() && xToolbarWindow
.is() )
348 Reference
< XWindow
> xWindow
= xTbxController
->createItemWindow( xToolbarWindow
);
351 vcl::Window
* pItemWin
= VCLUnoHelper::GetWindow( xWindow
);
354 WindowType nType
= pItemWin
->GetType();
355 if ( nType
== WINDOW_LISTBOX
|| nType
== WINDOW_MULTILISTBOX
|| nType
== WINDOW_COMBOBOX
)
356 pItemWin
->SetAccessibleName( m_pToolBar
->GetItemText( nId
) );
357 m_pToolBar
->SetItemWindow( nId
, pItemWin
);
362 // Notify controller implementation to its listeners. Controller is now useable from outside.
363 Reference
< XUpdatable
> xUpdatable( xController
, UNO_QUERY
);
364 if ( xUpdatable
.is() )
368 xUpdatable
->update();
370 catch ( const uno::Exception
& )
381 AddFrameActionListener();
384 IMPL_LINK_NOARG_TYPED(AddonsToolBarManager
, Click
, ToolBox
*, void)
389 sal_uInt16
nId( m_pToolBar
->GetCurItemId() );
390 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
391 if ( pIter
!= m_aControllerMap
.end() )
393 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
395 if ( xController
.is() )
396 xController
->click();
400 IMPL_LINK_NOARG_TYPED(AddonsToolBarManager
, DoubleClick
, ToolBox
*, void)
405 sal_uInt16
nId( m_pToolBar
->GetCurItemId() );
406 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
407 if ( pIter
!= m_aControllerMap
.end() )
409 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
411 if ( xController
.is() )
412 xController
->doubleClick();
416 IMPL_LINK_NOARG_TYPED(AddonsToolBarManager
, Command
, CommandEvent
const *, void)
419 IMPL_LINK_NOARG_TYPED(AddonsToolBarManager
, Select
, ToolBox
*, void)
424 sal_Int16
nKeyModifier( (sal_Int16
)m_pToolBar
->GetModifier() );
425 sal_uInt16
nId( m_pToolBar
->GetCurItemId() );
426 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
427 if ( pIter
!= m_aControllerMap
.end() )
429 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
431 if ( xController
.is() )
432 xController
->execute( nKeyModifier
);
436 IMPL_LINK_NOARG_TYPED(AddonsToolBarManager
, Activate
, ToolBox
*, void)
439 IMPL_LINK_NOARG_TYPED(AddonsToolBarManager
, Deactivate
, ToolBox
*, void)
442 IMPL_LINK_TYPED( AddonsToolBarManager
, StateChanged
, StateChangedType
const *, pStateChangedType
, void )
444 if ( *pStateChangedType
== StateChangedType::ControlBackground
)
446 CheckAndUpdateImages();
450 IMPL_LINK_TYPED( AddonsToolBarManager
, DataChanged
, DataChangedEvent
const *, pDataChangedEvent
, void )
452 if ((( pDataChangedEvent
->GetType() == DataChangedEventType::SETTINGS
) ||
453 ( pDataChangedEvent
->GetType() == DataChangedEventType::DISPLAY
)) &&
454 ( pDataChangedEvent
->GetFlags() & AllSettingsFlags::STYLE
))
456 CheckAndUpdateImages();
459 for ( sal_uInt16 nPos
= 0; nPos
< m_pToolBar
->GetItemCount(); ++nPos
)
461 const sal_uInt16 nId
= m_pToolBar
->GetItemId(nPos
);
462 vcl::Window
* pWindow
= m_pToolBar
->GetItemWindow( nId
);
465 const DataChangedEvent
& rDCEvt( *pDataChangedEvent
);
466 pWindow
->DataChanged( rDCEvt
);
473 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */