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>
24 #include <threadhelp/resetableguard.hxx>
26 #include <framework/imageproducer.hxx>
27 #include <framework/sfxhelperfunctions.hxx>
28 #include <classes/fwkresid.hxx>
29 #include <classes/resource.hrc>
30 #include <framework/addonsoptions.hxx>
31 #include <uielement/comboboxtoolbarcontroller.hxx>
32 #include <uielement/imagebuttontoolbarcontroller.hxx>
33 #include <uielement/togglebuttontoolbarcontroller.hxx>
34 #include <uielement/buttontoolbarcontroller.hxx>
35 #include <uielement/spinfieldtoolbarcontroller.hxx>
36 #include <uielement/edittoolbarcontroller.hxx>
37 #include <uielement/dropdownboxtoolbarcontroller.hxx>
39 #include <com/sun/star/ui/ItemType.hpp>
40 #include <com/sun/star/frame/ModuleManager.hpp>
41 #include <com/sun/star/frame/XToolbarController.hpp>
42 #include <com/sun/star/frame/XDispatchProvider.hpp>
43 #include <com/sun/star/lang/XServiceInfo.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/unohlp.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>
59 //_________________________________________________________________________________________________________________
61 //_________________________________________________________________________________________________________________
63 using namespace ::com::sun::star
;
64 using namespace ::com::sun::star::awt
;
65 using namespace ::com::sun::star::beans
;
66 using namespace ::com::sun::star::uno
;
67 using namespace ::com::sun::star::lang
;
68 using namespace ::com::sun::star::frame
;
69 using namespace ::com::sun::star::util
;
70 using namespace ::com::sun::star::container
;
71 using namespace ::com::sun::star::ui
;
76 static const char TOOLBOXITEM_SEPARATOR_STR
[] = "private:separator";
78 AddonsToolBarManager::AddonsToolBarManager( const Reference
< XComponentContext
>& rxContext
,
79 const Reference
< XFrame
>& rFrame
,
80 const OUString
& rResourceName
,
82 ToolBarManager( rxContext
, rFrame
, rResourceName
, pToolBar
)
84 m_pToolBar
->SetMenuType( TOOLBOX_MENUTYPE_CLIPPEDITEMS
);
85 m_pToolBar
->SetSelectHdl( LINK( this, AddonsToolBarManager
, Select
) );
86 m_pToolBar
->SetActivateHdl( LINK( this, AddonsToolBarManager
, Activate
) );
87 m_pToolBar
->SetDeactivateHdl( LINK( this, AddonsToolBarManager
, Deactivate
) );
88 m_pToolBar
->SetClickHdl( LINK( this, AddonsToolBarManager
, Click
) );
89 m_pToolBar
->SetDoubleClickHdl( LINK( this, AddonsToolBarManager
, DoubleClick
) );
90 m_pToolBar
->SetCommandHdl( LINK( this, AddonsToolBarManager
, Command
) );
91 m_pToolBar
->SetStateChangedHdl( LINK( this, AddonsToolBarManager
, StateChanged
) );
92 m_pToolBar
->SetDataChangedHdl( LINK( this, AddonsToolBarManager
, DataChanged
) );
95 AddonsToolBarManager::~AddonsToolBarManager()
99 static sal_Bool
IsCorrectContext( const OUString
& rModuleIdentifier
, const OUString
& aContextList
)
101 if ( aContextList
.isEmpty() )
104 if ( !rModuleIdentifier
.isEmpty() )
106 sal_Int32 nIndex
= aContextList
.indexOf( rModuleIdentifier
);
107 return ( nIndex
>= 0 );
113 static Image
RetrieveImage( Reference
< com::sun::star::frame::XFrame
>& rFrame
,
114 const OUString
& aImageId
,
115 const OUString
& aURL
,
121 if ( !aImageId
.isEmpty() )
123 aImage
= framework::AddonsOptions().GetImageFromURL( aImageId
, bBigImage
);
127 aImage
= GetImageFromURL( rFrame
, aImageId
, bBigImage
);
132 aImage
= framework::AddonsOptions().GetImageFromURL( aURL
, bBigImage
);
134 aImage
= GetImageFromURL( rFrame
, aImageId
, bBigImage
);
140 void SAL_CALL
AddonsToolBarManager::dispose() throw( RuntimeException
)
142 Reference
< XComponent
> xThis( static_cast< OWeakObject
* >(this), UNO_QUERY
);
145 // Remove addon specific data from toolbar items.
146 ResetableGuard
aGuard( m_aLock
);
147 for ( sal_uInt16 n
= 0; n
< m_pToolBar
->GetItemCount(); n
++ )
149 sal_uInt16
nId( m_pToolBar
->GetItemId( n
) );
153 AddonsParams
* pRuntimeItemData
= (AddonsParams
*)m_pToolBar
->GetItemData( nId
);
154 if ( pRuntimeItemData
)
155 delete pRuntimeItemData
;
156 m_pToolBar
->SetItemData( nId
, NULL
);
161 // Base class will destroy our m_pToolBar member
162 ToolBarManager::dispose();
165 bool AddonsToolBarManager::MenuItemAllowed( sal_uInt16 nId
) const
167 if (( nId
== MENUITEM_TOOLBAR_VISIBLEBUTTON
) ||
168 ( nId
== MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR
))
174 void AddonsToolBarManager::RefreshImages()
176 sal_Bool
bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
177 for ( sal_uInt16 nPos
= 0; nPos
< m_pToolBar
->GetItemCount(); nPos
++ )
179 sal_uInt16
nId( m_pToolBar
->GetItemId( nPos
) );
183 OUString aCommandURL
= m_pToolBar
->GetItemCommand( nId
);
185 AddonsParams
* pRuntimeItemData
= (AddonsParams
*)m_pToolBar
->GetItemData( nId
);
186 if ( pRuntimeItemData
)
187 aImageId
= pRuntimeItemData
->aImageId
;
189 m_pToolBar
->SetItemImage(
191 RetrieveImage( m_xFrame
, aImageId
, aCommandURL
, bBigImages
)
195 m_pToolBar
->SetToolboxButtonSize( bBigImages
? TOOLBOX_BUTTONSIZE_LARGE
: TOOLBOX_BUTTONSIZE_SMALL
);
196 ::Size aSize
= m_pToolBar
->CalcWindowSizePixel();
197 m_pToolBar
->SetOutputSizePixel( aSize
);
200 void AddonsToolBarManager::FillToolbar( const Sequence
< Sequence
< PropertyValue
> >& rAddonToolbar
)
202 ResetableGuard
aGuard( m_aLock
);
212 m_aControllerMap
.clear();
214 OUString aModuleIdentifier
;
217 Reference
< XModuleManager2
> xModuleManager
= ModuleManager::create( m_xContext
);
218 aModuleIdentifier
= xModuleManager
->identify( m_xFrame
);
220 catch ( const Exception
& )
224 sal_uInt32
nElements( 0 );
225 sal_Bool
bAppendSeparator( sal_False
);
226 Reference
< XWindow
> xToolbarWindow
= VCLUnoHelper::GetInterface( m_pToolBar
);
227 for ( sal_uInt32 n
= 0; n
< (sal_uInt32
)rAddonToolbar
.getLength(); n
++ )
234 OUString aControlType
;
235 sal_uInt16
nWidth( 0 );
237 const Sequence
< PropertyValue
>& rSeq
= rAddonToolbar
[n
];
239 ToolBarMerger::ConvertSequenceToValues( rSeq
, aURL
, aTitle
, aImageId
, aTarget
, aContext
, aControlType
, nWidth
);
241 if ( IsCorrectContext( aModuleIdentifier
, aContext
))
243 if ( aURL
== TOOLBOXITEM_SEPARATOR_STR
)
245 sal_uInt16 nCount
= m_pToolBar
->GetItemCount();
246 if ( nCount
> 0 && ( m_pToolBar
->GetItemType( nCount
-1 ) != TOOLBOXITEM_SEPARATOR
) && nElements
> 0 )
249 m_pToolBar
->InsertSeparator();
254 sal_uInt16 nCount
= m_pToolBar
->GetItemCount();
255 if ( bAppendSeparator
&& nCount
> 0 && ( m_pToolBar
->GetItemType( nCount
-1 ) != TOOLBOXITEM_SEPARATOR
))
257 // We have to append a separator first if the last item is not a separator
258 m_pToolBar
->InsertSeparator();
260 bAppendSeparator
= sal_False
;
262 m_pToolBar
->InsertItem( nId
, aTitle
);
264 // don't setup images yet, AddonsToolbarWrapper::populateImages does that.
266 // Create TbRuntimeItemData to hold additional information we will need in the future
267 AddonsParams
* pRuntimeItemData
= new AddonsParams
;
268 pRuntimeItemData
->aImageId
= aImageId
;
269 pRuntimeItemData
->aTarget
= aTarget
;
270 m_pToolBar
->SetItemData( nId
, pRuntimeItemData
);
271 m_pToolBar
->SetItemCommand( nId
, aURL
);
273 Reference
< XStatusListener
> xController
;
275 sal_Bool
bMustBeInit( sal_True
);
277 // Support external toolbar controller for add-ons!
278 if ( m_xToolbarControllerFactory
.is() &&
279 m_xToolbarControllerFactory
->hasController( aURL
, m_aModuleIdentifier
))
281 Sequence
< Any
> aArgs(5);
282 PropertyValue aPropValue
;
284 aPropValue
.Name
= OUString( "ModuleIdentifier" );
285 aPropValue
.Value
<<= m_aModuleIdentifier
;
286 aArgs
[0] <<= aPropValue
;
287 aPropValue
.Name
= OUString( "Frame" );
288 aPropValue
.Value
<<= m_xFrame
;
289 aArgs
[1] <<= aPropValue
;
290 aPropValue
.Name
= OUString( "ServiceManager" );
291 Reference
<XMultiServiceFactory
> xMSF(m_xContext
->getServiceManager(), UNO_QUERY_THROW
);
292 aPropValue
.Value
<<= xMSF
;
293 aArgs
[2] <<= aPropValue
;
294 aPropValue
.Name
= OUString( "ParentWindow" );
295 aPropValue
.Value
<<= xToolbarWindow
;
296 aArgs
[3] <<= aPropValue
;
297 aPropValue
.Name
= OUString( "ItemId" );
298 aPropValue
.Value
= makeAny( sal_Int32( nId
));
299 aArgs
[4] <<= aPropValue
;
303 xController
= Reference
< XStatusListener
>( m_xToolbarControllerFactory
->createInstanceWithArgumentsAndContext(
304 aURL
, aArgs
, m_xContext
),
307 catch ( uno::Exception
& )
310 bMustBeInit
= sal_False
; // factory called init already!
314 ::cppu::OWeakObject
* pController
= 0;
316 pController
= ToolBarMerger::CreateController( m_xContext
, m_xFrame
, m_pToolBar
, aURL
, nId
, nWidth
, aControlType
);
317 xController
= Reference
< XStatusListener
>( pController
, UNO_QUERY
);
320 // insert controller to the map
321 m_aControllerMap
[nId
] = xController
;
323 Reference
< XInitialization
> xInit( xController
, UNO_QUERY
);
324 if ( xInit
.is() && bMustBeInit
)
326 PropertyValue aPropValue
;
327 Sequence
< Any
> aArgs( 3 );
328 aPropValue
.Name
= OUString( "Frame" );
329 aPropValue
.Value
<<= m_xFrame
;
330 aArgs
[0] <<= aPropValue
;
331 aPropValue
.Name
= OUString( "CommandURL" );
332 aPropValue
.Value
<<= aURL
;
333 aArgs
[1] <<= aPropValue
;
334 aPropValue
.Name
= OUString( "ServiceManager" );
335 Reference
<XMultiServiceFactory
> xMSF(m_xContext
->getServiceManager(), UNO_QUERY_THROW
);
336 aPropValue
.Value
<<= xMSF
;
337 aArgs
[2] <<= aPropValue
;
340 xInit
->initialize( aArgs
);
342 catch ( const uno::Exception
& )
347 // Request a item window from the toolbar controller and set it at the VCL toolbar
348 Reference
< XToolbarController
> xTbxController( xController
, UNO_QUERY
);
349 if ( xTbxController
.is() && xToolbarWindow
.is() )
351 Reference
< XWindow
> xWindow
= xTbxController
->createItemWindow( xToolbarWindow
);
354 Window
* pItemWin
= VCLUnoHelper::GetWindow( xWindow
);
357 WindowType nType
= pItemWin
->GetType();
358 if ( nType
== WINDOW_LISTBOX
|| nType
== WINDOW_MULTILISTBOX
|| nType
== WINDOW_COMBOBOX
)
359 pItemWin
->SetAccessibleName( m_pToolBar
->GetItemText( nId
) );
360 m_pToolBar
->SetItemWindow( nId
, pItemWin
);
365 // Notify controller implementation to its listeners. Controller is now useable from outside.
366 Reference
< XUpdatable
> xUpdatable( xController
, UNO_QUERY
);
367 if ( xUpdatable
.is() )
371 xUpdatable
->update();
373 catch ( const uno::Exception
& )
384 AddFrameActionListener();
387 IMPL_LINK_NOARG(AddonsToolBarManager
, Click
)
392 sal_uInt16
nId( m_pToolBar
->GetCurItemId() );
393 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
394 if ( pIter
!= m_aControllerMap
.end() )
396 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
398 if ( xController
.is() )
399 xController
->click();
405 IMPL_LINK_NOARG(AddonsToolBarManager
, DoubleClick
)
410 sal_uInt16
nId( m_pToolBar
->GetCurItemId() );
411 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
412 if ( pIter
!= m_aControllerMap
.end() )
414 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
416 if ( xController
.is() )
417 xController
->doubleClick();
423 IMPL_LINK_NOARG(AddonsToolBarManager
, Command
)
425 ResetableGuard
aGuard( m_aLock
);
433 IMPL_LINK_NOARG(AddonsToolBarManager
, Select
)
438 sal_Int16
nKeyModifier( (sal_Int16
)m_pToolBar
->GetModifier() );
439 sal_uInt16
nId( m_pToolBar
->GetCurItemId() );
440 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
441 if ( pIter
!= m_aControllerMap
.end() )
443 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
445 if ( xController
.is() )
446 xController
->execute( nKeyModifier
);
452 IMPL_LINK_NOARG(AddonsToolBarManager
, Activate
)
457 IMPL_LINK_NOARG(AddonsToolBarManager
, Deactivate
)
462 IMPL_LINK( AddonsToolBarManager
, StateChanged
, StateChangedType
*, pStateChangedType
)
464 if ( *pStateChangedType
== STATE_CHANGE_CONTROLBACKGROUND
)
466 CheckAndUpdateImages();
471 IMPL_LINK( AddonsToolBarManager
, DataChanged
, DataChangedEvent
*, pDataChangedEvent
)
473 if ((( pDataChangedEvent
->GetType() == DATACHANGED_SETTINGS
) ||
474 ( pDataChangedEvent
->GetType() == DATACHANGED_DISPLAY
)) &&
475 ( pDataChangedEvent
->GetFlags() & SETTINGS_STYLE
))
477 CheckAndUpdateImages();
480 for ( sal_uInt16 nPos
= 0; nPos
< m_pToolBar
->GetItemCount(); ++nPos
)
482 const sal_uInt16 nId
= m_pToolBar
->GetItemId(nPos
);
483 Window
* pWindow
= m_pToolBar
->GetItemWindow( nId
);
486 const DataChangedEvent
& rDCEvt( *pDataChangedEvent
);
487 pWindow
->DataChanged( rDCEvt
);
496 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */