1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: addonstoolbarmanager.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
33 #include <uielement/addonstoolbarmanager.hxx>
34 #include <uielement/toolbarmerger.hxx>
36 //_________________________________________________________________________________________________________________
38 //_________________________________________________________________________________________________________________
41 #ifndef __FRAMEWORK_UIELEMENT_TOOLBAR_HXX
42 #include <uielement/toolbar.hxx>
44 #ifndef __FRAMEWORK_UIELEMENT_GENERICTOOLBARCONTROLLER_HXX
45 #include <uielement/generictoolbarcontroller.hxx>
47 #include <threadhelp/resetableguard.hxx>
49 #include <helper/imageproducer.hxx>
50 #include <classes/sfxhelperfunctions.hxx>
51 #include <classes/fwkresid.hxx>
52 #ifndef __FRAMEWORK_CLASES_RESOURCE_HRC_
53 #include <classes/resource.hrc>
55 #include <classes/addonsoptions.hxx>
56 #ifndef __FRAMEWORK_UIELEMENT_COMBOBOXTOOLBARCONTROLLER_HXX
57 #include <uielement/comboboxtoolbarcontroller.hxx>
59 #ifndef __FRAMEWORK_UIELEMENT_IMAGEBUTTONTOOLBARCONTROLLER_HXX
60 #include <uielement/imagebuttontoolbarcontroller.hxx>
62 #ifndef __FRAMEWORK_UIELEMENT_TOGGLEBUTTONTOOLBARCONTROLLER_HXX
63 #include <uielement/togglebuttontoolbarcontroller.hxx>
65 #include <uielement/buttontoolbarcontroller.hxx>
66 #include <uielement/spinfieldtoolbarcontroller.hxx>
67 #include <uielement/edittoolbarcontroller.hxx>
68 #include <uielement/dropdownboxtoolbarcontroller.hxx>
69 #include <uielement/toolbarmerger.hxx>
71 //_________________________________________________________________________________________________________________
73 //_________________________________________________________________________________________________________________
74 #include <com/sun/star/ui/ItemType.hpp>
75 #include <com/sun/star/frame/XToolbarController.hpp>
76 #include <com/sun/star/frame/XDispatchProvider.hpp>
77 #ifndef _COM_SUN_STAR_BEANS_XLAYOUTMANAGER_HPP_
78 #include <com/sun/star/beans/XPropertySet.hpp>
80 #include <com/sun/star/lang/XServiceInfo.hpp>
81 #include <com/sun/star/frame/XLayoutManager.hpp>
82 #ifndef _COM_SUN_STAR_UI_XDOCKINGAREA_HPP_
83 #include <com/sun/star/ui/DockingArea.hpp>
85 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
87 //_________________________________________________________________________________________________________________
89 //_________________________________________________________________________________________________________________
90 #include <svtools/imgdef.hxx>
91 #include <svtools/toolboxcontroller.hxx>
92 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
93 #include <toolkit/unohlp.hxx>
96 #include <svtools/miscopt.hxx>
97 #include <vcl/svapp.hxx>
98 #include <vcl/menu.hxx>
99 #include <vcl/syswin.hxx>
100 #include <vcl/taskpanelist.hxx>
102 //_________________________________________________________________________________________________________________
104 //_________________________________________________________________________________________________________________
106 using namespace ::com::sun::star
;
107 using namespace ::com::sun::star::awt
;
108 using namespace ::com::sun::star::beans
;
109 using namespace ::com::sun::star::uno
;
110 using namespace ::com::sun::star::lang
;
111 using namespace ::com::sun::star::frame
;
112 using namespace ::com::sun::star::util
;
113 using namespace ::com::sun::star::container
;
114 using namespace ::com::sun::star::frame
;
115 using namespace ::com::sun::star::ui
;
120 static const char TOOLBOXITEM_SEPARATOR_STR
[] = "private:separator";
121 static const USHORT TOOLBOXITEM_SEPARATOR_STR_LEN
= sizeof( TOOLBOXITEM_SEPARATOR_STR
)-1;
123 AddonsToolBarManager::AddonsToolBarManager( const Reference
< XMultiServiceFactory
>& rServiceManager
,
124 const Reference
< XFrame
>& rFrame
,
125 const rtl::OUString
& rResourceName
,
126 ToolBar
* pToolBar
) :
127 ToolBarManager( rServiceManager
, rFrame
, rResourceName
, pToolBar
)
129 // Configuration data is retrieved from non-writable configuration layer. Therefor we
130 // must disable some menu entries.
131 m_bCanBeCustomized
= sal_False
;
133 m_pToolBar
->SetMenuType( TOOLBOX_MENUTYPE_CLIPPEDITEMS
);
134 m_pToolBar
->SetSelectHdl( LINK( this, AddonsToolBarManager
, Select
) );
135 m_pToolBar
->SetActivateHdl( LINK( this, AddonsToolBarManager
, Activate
) );
136 m_pToolBar
->SetDeactivateHdl( LINK( this, AddonsToolBarManager
, Deactivate
) );
137 m_pToolBar
->SetClickHdl( LINK( this, AddonsToolBarManager
, Click
) );
138 m_pToolBar
->SetDoubleClickHdl( LINK( this, AddonsToolBarManager
, DoubleClick
) );
139 m_pToolBar
->SetCommandHdl( LINK( this, AddonsToolBarManager
, Command
) );
140 m_pToolBar
->SetStateChangedHdl( LINK( this, AddonsToolBarManager
, StateChanged
) );
141 m_pToolBar
->SetDataChangedHdl( LINK( this, AddonsToolBarManager
, DataChanged
) );
144 AddonsToolBarManager::~AddonsToolBarManager()
148 static sal_Bool
IsCorrectContext( const ::rtl::OUString
& rModuleIdentifier
, const ::rtl::OUString
& aContextList
)
150 if ( aContextList
.getLength() == 0 )
153 if ( rModuleIdentifier
.getLength() > 0 )
155 sal_Int32 nIndex
= aContextList
.indexOf( rModuleIdentifier
);
156 return ( nIndex
>= 0 );
162 static Image
RetrieveImage( Reference
< com::sun::star::frame::XFrame
>& rFrame
,
163 const rtl::OUString
& aImageId
,
164 const rtl::OUString
& aURL
,
170 if ( aImageId
.getLength() > 0 )
172 aImage
= framework::AddonsOptions().GetImageFromURL( aImageId
, bBigImage
, bHiContrast
);
176 aImage
= GetImageFromURL( rFrame
, aImageId
, bBigImage
, bHiContrast
);
181 aImage
= framework::AddonsOptions().GetImageFromURL( aURL
, bBigImage
, bHiContrast
);
183 aImage
= GetImageFromURL( rFrame
, aImageId
, bBigImage
, bHiContrast
);
189 void SAL_CALL
AddonsToolBarManager::dispose() throw( RuntimeException
)
191 Reference
< XComponent
> xThis( static_cast< OWeakObject
* >(this), UNO_QUERY
);
194 // Remove addon specific data from toolbar items.
195 ResetableGuard
aGuard( m_aLock
);
196 for ( sal_uInt16 n
= 0; n
< m_pToolBar
->GetItemCount(); n
++ )
198 USHORT
nId( m_pToolBar
->GetItemId( n
) );
202 AddonsParams
* pRuntimeItemData
= (AddonsParams
*)m_pToolBar
->GetItemData( nId
);
203 if ( pRuntimeItemData
)
204 delete pRuntimeItemData
;
205 m_pToolBar
->SetItemData( nId
, NULL
);
210 // Base class will destroy our m_pToolBar member
211 ToolBarManager::dispose();
214 bool AddonsToolBarManager::MenuItemAllowed( sal_uInt16 nId
) const
216 if (( nId
== MENUITEM_TOOLBAR_VISIBLEBUTTON
) ||
217 ( nId
== MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR
))
223 void AddonsToolBarManager::RefreshImages()
225 sal_Bool
bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
226 for ( USHORT nPos
= 0; nPos
< m_pToolBar
->GetItemCount(); nPos
++ )
228 USHORT
nId( m_pToolBar
->GetItemId( nPos
) );
232 ::rtl::OUString aCommandURL
= m_pToolBar
->GetItemCommand( nId
);
233 ::rtl::OUString aImageId
;
234 AddonsParams
* pRuntimeItemData
= (AddonsParams
*)m_pToolBar
->GetItemData( nId
);
235 if ( pRuntimeItemData
)
236 aImageId
= pRuntimeItemData
->aImageId
;
238 m_pToolBar
->SetItemImage( nId
, RetrieveImage( m_xFrame
,
247 void AddonsToolBarManager::FillToolbar( const Sequence
< Sequence
< PropertyValue
> >& rAddonToolbar
)
249 ResetableGuard
aGuard( m_aLock
);
259 m_aControllerMap
.clear();
261 ::rtl::OUString aModuleIdentifier
;
264 Reference
< XModuleManager
> xModuleManager(
265 m_xServiceManager
->createInstance( SERVICENAME_MODULEMANAGER
), UNO_QUERY_THROW
);
266 aModuleIdentifier
= xModuleManager
->identify( m_xFrame
);
272 Reference
< XMultiComponentFactory
> xToolbarControllerFactory( m_xToolbarControllerRegistration
, UNO_QUERY
);
273 Reference
< XComponentContext
> xComponentContext
;
274 Reference
< XPropertySet
> xProps( m_xServiceManager
, UNO_QUERY
);
277 xProps
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComponentContext
;
279 sal_uInt32
nElements( 0 );
280 sal_Bool
bAppendSeparator( sal_False
);
281 Reference
< XWindow
> xToolbarWindow
= VCLUnoHelper::GetInterface( m_pToolBar
);
282 for ( sal_uInt32 n
= 0; n
< (sal_uInt32
)rAddonToolbar
.getLength(); n
++ )
284 rtl::OUString aValueName
;
287 rtl::OUString aTitle
;
288 rtl::OUString aImageId
;
289 rtl::OUString aContext
;
290 rtl::OUString aTarget
;
291 rtl::OUString aControlType
;
292 sal_uInt16
nWidth( 0 );
294 const Sequence
< PropertyValue
>& rSeq
= rAddonToolbar
[n
];
296 ToolBarMerger::ConvertSequenceToValues( rSeq
, aURL
, aTitle
, aImageId
, aTarget
, aContext
, aControlType
, nWidth
);
298 if ( IsCorrectContext( aModuleIdentifier
, aContext
))
300 if ( aURL
.equalsAsciiL( TOOLBOXITEM_SEPARATOR_STR
, TOOLBOXITEM_SEPARATOR_STR_LEN
))
302 USHORT nCount
= m_pToolBar
->GetItemCount();
303 if ( nCount
> 0 && ( m_pToolBar
->GetItemType( nCount
-1 ) != TOOLBOXITEM_SEPARATOR
) && nElements
> 0 )
306 m_pToolBar
->InsertSeparator();
311 USHORT nCount
= m_pToolBar
->GetItemCount();
312 if ( bAppendSeparator
&& nCount
> 0 && ( m_pToolBar
->GetItemType( nCount
-1 ) != TOOLBOXITEM_SEPARATOR
))
314 // We have to append a separator first if the last item is not a separator
315 m_pToolBar
->InsertSeparator();
317 bAppendSeparator
= FALSE
;
319 m_pToolBar
->InsertItem( nId
, aTitle
);
321 Image aImage
= RetrieveImage( m_xFrame
, aImageId
, aURL
, !m_bSmallSymbols
, m_bIsHiContrast
);
323 m_pToolBar
->SetItemImage( nId
, aImage
);
325 // Create TbRuntimeItemData to hold additional information we will need in the future
326 AddonsParams
* pRuntimeItemData
= new AddonsParams
;
327 pRuntimeItemData
->aImageId
= aImageId
;
328 pRuntimeItemData
->aTarget
= aTarget
;
329 m_pToolBar
->SetItemData( nId
, pRuntimeItemData
);
330 m_pToolBar
->SetItemCommand( nId
, aURL
);
332 Reference
< XStatusListener
> xController
;
334 sal_Bool
bMustBeInit( sal_True
);
336 // Support external toolbar controller for add-ons!
337 if ( m_xToolbarControllerRegistration
.is() &&
338 m_xToolbarControllerRegistration
->hasController( aURL
, m_aModuleIdentifier
))
340 if ( xToolbarControllerFactory
.is() )
342 Sequence
< Any
> aArgs(5);
343 PropertyValue aPropValue
;
345 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
346 aPropValue
.Value
<<= m_aModuleIdentifier
;
347 aArgs
[0] <<= aPropValue
;
348 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
349 aPropValue
.Value
<<= m_xFrame
;
350 aArgs
[1] <<= aPropValue
;
351 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
352 aPropValue
.Value
<<= m_xServiceManager
;
353 aArgs
[2] <<= aPropValue
;
354 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
355 aPropValue
.Value
<<= xToolbarWindow
;
356 aArgs
[3] <<= aPropValue
;
357 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ItemId" ));
358 aPropValue
.Value
= makeAny( sal_Int32( nId
));
359 aArgs
[4] <<= aPropValue
;
363 xController
= Reference
< XStatusListener
>( xToolbarControllerFactory
->createInstanceWithArgumentsAndContext(
364 aURL
, aArgs
, xComponentContext
),
367 catch ( uno::Exception
& )
370 bMustBeInit
= sal_False
; // factory called init already!
375 ::cppu::OWeakObject
* pController
= 0;
377 pController
= ToolBarMerger::CreateController( m_xServiceManager
, m_xFrame
, m_pToolBar
, aURL
, nId
, nWidth
, aControlType
);
378 xController
= Reference
< XStatusListener
>( pController
, UNO_QUERY
);
381 // insert controller to the map
382 m_aControllerMap
[nId
] = xController
;
384 Reference
< XInitialization
> xInit( xController
, UNO_QUERY
);
385 if ( xInit
.is() && bMustBeInit
)
387 PropertyValue aPropValue
;
388 Sequence
< Any
> aArgs( 3 );
389 aPropValue
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
390 aPropValue
.Value
<<= m_xFrame
;
391 aArgs
[0] <<= aPropValue
;
392 aPropValue
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
393 aPropValue
.Value
<<= aURL
;
394 aArgs
[1] <<= aPropValue
;
395 aPropValue
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
396 aPropValue
.Value
<<= m_xServiceManager
;
397 aArgs
[2] <<= aPropValue
;
400 xInit
->initialize( aArgs
);
402 catch ( uno::Exception
& )
407 // Request a item window from the toolbar controller and set it at the VCL toolbar
408 Reference
< XToolbarController
> xTbxController( xController
, UNO_QUERY
);
409 if ( xTbxController
.is() && xToolbarWindow
.is() )
411 Reference
< XWindow
> xWindow
= xTbxController
->createItemWindow( xToolbarWindow
);
414 Window
* pItemWin
= VCLUnoHelper::GetWindow( xWindow
);
417 WindowType nType
= pItemWin
->GetType();
418 if ( nType
== WINDOW_LISTBOX
|| nType
== WINDOW_MULTILISTBOX
|| nType
== WINDOW_COMBOBOX
)
419 pItemWin
->SetAccessibleName( m_pToolBar
->GetItemText( nId
) );
420 m_pToolBar
->SetItemWindow( nId
, pItemWin
);
425 // Notify controller implementation to its listeners. Controller is now useable from outside.
426 Reference
< XUpdatable
> xUpdatable( xController
, UNO_QUERY
);
427 if ( xUpdatable
.is() )
431 xUpdatable
->update();
433 catch ( uno::Exception
& )
444 AddFrameActionListener();
447 IMPL_LINK( AddonsToolBarManager
, Click
, ToolBox
*, EMPTYARG
)
452 USHORT
nId( m_pToolBar
->GetCurItemId() );
453 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
454 if ( pIter
!= m_aControllerMap
.end() )
456 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
458 if ( xController
.is() )
459 xController
->click();
465 IMPL_LINK( AddonsToolBarManager
, DoubleClick
, ToolBox
*, EMPTYARG
)
470 USHORT
nId( m_pToolBar
->GetCurItemId() );
471 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
472 if ( pIter
!= m_aControllerMap
.end() )
474 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
476 if ( xController
.is() )
477 xController
->doubleClick();
483 IMPL_LINK( AddonsToolBarManager
, Command
, CommandEvent
*, EMPTYARG
)
485 ResetableGuard
aGuard( m_aLock
);
493 IMPL_LINK( AddonsToolBarManager
, Select
, ToolBox
*, EMPTYARG
)
498 sal_Int16
nKeyModifier( (sal_Int16
)m_pToolBar
->GetModifier() );
499 USHORT
nId( m_pToolBar
->GetCurItemId() );
500 ToolBarControllerMap::const_iterator pIter
= m_aControllerMap
.find( nId
);
501 if ( pIter
!= m_aControllerMap
.end() )
503 Reference
< XToolbarController
> xController( pIter
->second
, UNO_QUERY
);
505 if ( xController
.is() )
506 xController
->execute( nKeyModifier
);
512 IMPL_LINK( AddonsToolBarManager
, Highlight
, ToolBox
*, EMPTYARG
)
517 IMPL_LINK( AddonsToolBarManager
, Activate
, ToolBox
*, EMPTYARG
)
522 IMPL_LINK( AddonsToolBarManager
, Deactivate
, ToolBox
*, EMPTYARG
)
527 IMPL_LINK( AddonsToolBarManager
, StateChanged
, StateChangedType
*, pStateChangedType
)
529 if ( *pStateChangedType
== STATE_CHANGE_CONTROLBACKGROUND
)
531 // Check if we need to get new images for normal/high contrast mode
532 CheckAndUpdateImages();
537 IMPL_LINK( AddonsToolBarManager
, DataChanged
, DataChangedEvent
*, pDataChangedEvent
)
539 if ((( pDataChangedEvent
->GetType() == DATACHANGED_SETTINGS
) ||
540 ( pDataChangedEvent
->GetType() == DATACHANGED_DISPLAY
)) &&
541 ( pDataChangedEvent
->GetFlags() & SETTINGS_STYLE
))
543 // Check if we need to get new images for normal/high contrast mode
544 CheckAndUpdateImages();
547 for ( USHORT nPos
= 0; nPos
< m_pToolBar
->GetItemCount(); ++nPos
)
549 const USHORT nId
= m_pToolBar
->GetItemId(nPos
);
550 Window
* pWindow
= m_pToolBar
->GetItemWindow( nId
);
553 const DataChangedEvent
& rDCEvt( *pDataChangedEvent
);
554 pWindow
->DataChanged( rDCEvt
);