1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 #include <uielement/addonstoolbarmanager.hxx>
27 #include <uielement/toolbarmerger.hxx>
28
29 //_________________________________________________________________________________________________________________
30 // my own includes
31 //_________________________________________________________________________________________________________________
32
33
34 #ifndef __FRAMEWORK_UIELEMENT_TOOLBAR_HXX
35 #include <uielement/toolbar.hxx>
36 #endif
37 #ifndef __FRAMEWORK_UIELEMENT_GENERICTOOLBARCONTROLLER_HXX
38 #include <uielement/generictoolbarcontroller.hxx>
39 #endif
40 #include <threadhelp/resetableguard.hxx>
41 #include "services.h"
42 #include <framework/imageproducer.hxx>
43 #include <framework/sfxhelperfunctions.hxx>
44 #include <classes/fwkresid.hxx>
45 #ifndef __FRAMEWORK_CLASES_RESOURCE_HRC_
46 #include <classes/resource.hrc>
47 #endif
48 #include <framework/addonsoptions.hxx>
49 #ifndef __FRAMEWORK_UIELEMENT_COMBOBOXTOOLBARCONTROLLER_HXX
50 #include <uielement/comboboxtoolbarcontroller.hxx>
51 #endif
52 #ifndef __FRAMEWORK_UIELEMENT_IMAGEBUTTONTOOLBARCONTROLLER_HXX
53 #include <uielement/imagebuttontoolbarcontroller.hxx>
54 #endif
55 #ifndef __FRAMEWORK_UIELEMENT_TOGGLEBUTTONTOOLBARCONTROLLER_HXX
56 #include <uielement/togglebuttontoolbarcontroller.hxx>
57 #endif
58 #include <uielement/buttontoolbarcontroller.hxx>
59 #include <uielement/spinfieldtoolbarcontroller.hxx>
60 #include <uielement/edittoolbarcontroller.hxx>
61 #include <uielement/dropdownboxtoolbarcontroller.hxx>
62 #include <uielement/toolbarmerger.hxx>
63
64 //_________________________________________________________________________________________________________________
65 // interface includes
66 //_________________________________________________________________________________________________________________
67 #include <com/sun/star/ui/ItemType.hpp>
68 #include <com/sun/star/frame/XToolbarController.hpp>
69 #include <com/sun/star/frame/XDispatchProvider.hpp>
70 #ifndef _COM_SUN_STAR_BEANS_XLAYOUTMANAGER_HPP_
71 #include <com/sun/star/beans/XPropertySet.hpp>
72 #endif
73 #include <com/sun/star/lang/XServiceInfo.hpp>
74 #include <com/sun/star/frame/XLayoutManager.hpp>
75 #ifndef _COM_SUN_STAR_UI_XDOCKINGAREA_HPP_
76 #include <com/sun/star/ui/DockingArea.hpp>
77 #endif
78 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
79
80 //_________________________________________________________________________________________________________________
81 // other includes
82 //_________________________________________________________________________________________________________________
83 #include <svtools/imgdef.hxx>
84 #include <svtools/toolboxcontroller.hxx>
85 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
86 #include <toolkit/helper/vclunohelper.hxx>
87 #endif
88
89 #include <svtools/miscopt.hxx>
90 #include <vcl/svapp.hxx>
91 #include <vcl/menu.hxx>
92 #include <vcl/syswin.hxx>
93 #include <vcl/taskpanelist.hxx>
94
95 //_________________________________________________________________________________________________________________
96 // namespaces
97 //_________________________________________________________________________________________________________________
98
99 using namespace ::com::sun::star;
100 using namespace ::com::sun::star::awt;
101 using namespace ::com::sun::star::beans;
102 using namespace ::com::sun::star::uno;
103 using namespace ::com::sun::star::lang;
104 using namespace ::com::sun::star::frame;
105 using namespace ::com::sun::star::util;
106 using namespace ::com::sun::star::container;
107 using namespace ::com::sun::star::frame;
108 using namespace ::com::sun::star::ui;
109
110 namespace framework
111 {
112
113 static const char TOOLBOXITEM_SEPARATOR_STR[] = "private:separator";
114 static const sal_uInt16 TOOLBOXITEM_SEPARATOR_STR_LEN = sizeof( TOOLBOXITEM_SEPARATOR_STR )-1;
115
AddonsToolBarManager(const Reference<XMultiServiceFactory> & rServiceManager,const Reference<XFrame> & rFrame,const rtl::OUString & rResourceName,ToolBar * pToolBar)116 AddonsToolBarManager::AddonsToolBarManager( const Reference< XMultiServiceFactory >& rServiceManager,
117 const Reference< XFrame >& rFrame,
118 const rtl::OUString& rResourceName,
119 ToolBar* pToolBar ) :
120 ToolBarManager( rServiceManager, rFrame, rResourceName, pToolBar )
121 {
122 // Configuration data is retrieved from non-writable configuration layer. Therefor we
123 // must disable some menu entries.
124 m_bCanBeCustomized = sal_False;
125
126 m_pToolBar->SetMenuType( TOOLBOX_MENUTYPE_CLIPPEDITEMS );
127 m_pToolBar->SetSelectHdl( LINK( this, AddonsToolBarManager, Select) );
128 m_pToolBar->SetActivateHdl( LINK( this, AddonsToolBarManager, Activate) );
129 m_pToolBar->SetDeactivateHdl( LINK( this, AddonsToolBarManager, Deactivate) );
130 m_pToolBar->SetClickHdl( LINK( this, AddonsToolBarManager, Click ) );
131 m_pToolBar->SetDoubleClickHdl( LINK( this, AddonsToolBarManager, DoubleClick ) );
132 m_pToolBar->SetCommandHdl( LINK( this, AddonsToolBarManager, Command ) );
133 m_pToolBar->SetStateChangedHdl( LINK( this, AddonsToolBarManager, StateChanged ) );
134 m_pToolBar->SetDataChangedHdl( LINK( this, AddonsToolBarManager, DataChanged ) );
135 }
136
~AddonsToolBarManager()137 AddonsToolBarManager::~AddonsToolBarManager()
138 {
139 }
140
IsCorrectContext(const::rtl::OUString & rModuleIdentifier,const::rtl::OUString & aContextList)141 static sal_Bool IsCorrectContext( const ::rtl::OUString& rModuleIdentifier, const ::rtl::OUString& aContextList )
142 {
143 if ( aContextList.getLength() == 0 )
144 return sal_True;
145
146 if ( rModuleIdentifier.getLength() > 0 )
147 {
148 sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
149 return ( nIndex >= 0 );
150 }
151
152 return sal_False;
153 }
154
RetrieveImage(Reference<com::sun::star::frame::XFrame> & rFrame,const rtl::OUString & aImageId,const rtl::OUString & aURL,sal_Bool bBigImage,sal_Bool bHiContrast)155 static Image RetrieveImage( Reference< com::sun::star::frame::XFrame >& rFrame,
156 const rtl::OUString& aImageId,
157 const rtl::OUString& aURL,
158 sal_Bool bBigImage,
159 sal_Bool bHiContrast )
160 {
161 Image aImage;
162
163 if ( aImageId.getLength() > 0 )
164 {
165 aImage = framework::AddonsOptions().GetImageFromURL( aImageId, bBigImage, bHiContrast );
166 if ( !!aImage )
167 return aImage;
168 else
169 aImage = GetImageFromURL( rFrame, aImageId, bBigImage, bHiContrast );
170 if ( !!aImage )
171 return aImage;
172 }
173
174 aImage = framework::AddonsOptions().GetImageFromURL( aURL, bBigImage, bHiContrast );
175 if ( !aImage )
176 aImage = GetImageFromURL( rFrame, aImageId, bBigImage, bHiContrast );
177
178 return aImage;
179 }
180
181 // XComponent
dispose()182 void SAL_CALL AddonsToolBarManager::dispose() throw( RuntimeException )
183 {
184 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
185
186 {
187 // Remove addon specific data from toolbar items.
188 ResetableGuard aGuard( m_aLock );
189 for ( sal_uInt16 n = 0; n < m_pToolBar->GetItemCount(); n++ )
190 {
191 sal_uInt16 nId( m_pToolBar->GetItemId( n ) );
192
193 if ( nId > 0 )
194 {
195 AddonsParams* pRuntimeItemData = (AddonsParams*)m_pToolBar->GetItemData( nId );
196 if ( pRuntimeItemData )
197 delete pRuntimeItemData;
198 m_pToolBar->SetItemData( nId, NULL );
199 }
200 }
201 }
202
203 // Base class will destroy our m_pToolBar member
204 ToolBarManager::dispose();
205 }
206
MenuItemAllowed(sal_uInt16 nId) const207 bool AddonsToolBarManager::MenuItemAllowed( sal_uInt16 nId ) const
208 {
209 if (( nId == MENUITEM_TOOLBAR_VISIBLEBUTTON ) ||
210 ( nId == MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR ))
211 return false;
212 else
213 return true;
214 }
215
RefreshImages()216 void AddonsToolBarManager::RefreshImages()
217 {
218 sal_Bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
219 for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); nPos++ )
220 {
221 sal_uInt16 nId( m_pToolBar->GetItemId( nPos ) );
222
223 if ( nId > 0 )
224 {
225 ::rtl::OUString aCommandURL = m_pToolBar->GetItemCommand( nId );
226 ::rtl::OUString aImageId;
227 AddonsParams* pRuntimeItemData = (AddonsParams*)m_pToolBar->GetItemData( nId );
228 if ( pRuntimeItemData )
229 aImageId = pRuntimeItemData->aImageId;
230
231 m_pToolBar->SetItemImage( nId, RetrieveImage( m_xFrame,
232 aImageId,
233 aCommandURL,
234 bBigImages,
235 m_bIsHiContrast ));
236 }
237 }
238 }
239
FillToolbar(const Sequence<Sequence<PropertyValue>> & rAddonToolbar)240 void AddonsToolBarManager::FillToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar )
241 {
242 ResetableGuard aGuard( m_aLock );
243
244 if ( m_bDisposed )
245 return;
246
247 sal_uInt16 nId( 1 );
248
249 RemoveControllers();
250
251 m_pToolBar->Clear();
252 m_aControllerMap.clear();
253
254 ::rtl::OUString aModuleIdentifier;
255 try
256 {
257 Reference< XModuleManager > xModuleManager(
258 m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
259 aModuleIdentifier = xModuleManager->identify( m_xFrame );
260 }
261 catch ( Exception& )
262 {
263 }
264
265 Reference< XComponentContext > xComponentContext;
266 Reference< XPropertySet > xProps( m_xServiceManager, UNO_QUERY );
267
268 if ( xProps.is() )
269 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComponentContext;
270
271 sal_uInt32 nElements( 0 );
272 sal_Bool bAppendSeparator( sal_False );
273 Reference< XWindow > xToolbarWindow = VCLUnoHelper::GetInterface( m_pToolBar );
274 for ( sal_uInt32 n = 0; n < (sal_uInt32)rAddonToolbar.getLength(); n++ )
275 {
276 rtl::OUString aValueName;
277
278 rtl::OUString aURL;
279 rtl::OUString aTitle;
280 rtl::OUString aImageId;
281 rtl::OUString aContext;
282 rtl::OUString aTarget;
283 rtl::OUString aControlType;
284 sal_uInt16 nWidth( 0 );
285
286 const Sequence< PropertyValue >& rSeq = rAddonToolbar[n];
287
288 ToolBarMerger::ConvertSequenceToValues( rSeq, aURL, aTitle, aImageId, aTarget, aContext, aControlType, nWidth );
289
290 if ( IsCorrectContext( aModuleIdentifier, aContext ))
291 {
292 if ( aURL.equalsAsciiL( TOOLBOXITEM_SEPARATOR_STR, TOOLBOXITEM_SEPARATOR_STR_LEN ))
293 {
294 sal_uInt16 nCount = m_pToolBar->GetItemCount();
295 if ( nCount > 0 && ( m_pToolBar->GetItemType( nCount-1 ) != TOOLBOXITEM_SEPARATOR ) && nElements > 0 )
296 {
297 nElements = 0;
298 m_pToolBar->InsertSeparator();
299 }
300 }
301 else
302 {
303 sal_uInt16 nCount = m_pToolBar->GetItemCount();
304 if ( bAppendSeparator && nCount > 0 && ( m_pToolBar->GetItemType( nCount-1 ) != TOOLBOXITEM_SEPARATOR ))
305 {
306 // We have to append a separator first if the last item is not a separator
307 m_pToolBar->InsertSeparator();
308 }
309 bAppendSeparator = sal_False;
310
311 m_pToolBar->InsertItem( nId, aTitle );
312
313 Image aImage = RetrieveImage( m_xFrame, aImageId, aURL, !m_bSmallSymbols, m_bIsHiContrast );
314 if ( !!aImage )
315 m_pToolBar->SetItemImage( nId, aImage );
316
317 // Create TbRuntimeItemData to hold additional information we will need in the future
318 AddonsParams* pRuntimeItemData = new AddonsParams;
319 pRuntimeItemData->aImageId = aImageId;
320 pRuntimeItemData->aTarget = aTarget;
321 m_pToolBar->SetItemData( nId, pRuntimeItemData );
322 m_pToolBar->SetItemCommand( nId, aURL );
323
324 Reference< XStatusListener > xController;
325
326 sal_Bool bMustBeInit( sal_True );
327
328 // Support external toolbar controller for add-ons!
329 if ( m_xToolbarControllerFactory.is() &&
330 m_xToolbarControllerFactory->hasController( aURL, m_aModuleIdentifier ))
331 {
332 Sequence< Any > aArgs(5);
333 PropertyValue aPropValue;
334
335 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
336 aPropValue.Value <<= m_aModuleIdentifier;
337 aArgs[0] <<= aPropValue;
338 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
339 aPropValue.Value <<= m_xFrame;
340 aArgs[1] <<= aPropValue;
341 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
342 aPropValue.Value <<= m_xServiceManager;
343 aArgs[2] <<= aPropValue;
344 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
345 aPropValue.Value <<= xToolbarWindow;
346 aArgs[3] <<= aPropValue;
347 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ItemId" ));
348 aPropValue.Value = makeAny( sal_Int32( nId ));
349 aArgs[4] <<= aPropValue;
350
351 try
352 {
353 xController = Reference< XStatusListener >( m_xToolbarControllerFactory->createInstanceWithArgumentsAndContext(
354 aURL, aArgs, xComponentContext ),
355 UNO_QUERY );
356 }
357 catch ( uno::Exception& )
358 {
359 }
360 bMustBeInit = sal_False; // factory called init already!
361 }
362 else
363 {
364 ::cppu::OWeakObject* pController = 0;
365
366 pController = ToolBarMerger::CreateController( m_xServiceManager, m_xFrame, m_pToolBar, aURL, nId, nWidth, aControlType );
367 xController = Reference< XStatusListener >( pController, UNO_QUERY );
368 }
369
370 // insert controller to the map
371 m_aControllerMap[nId] = xController;
372
373 Reference< XInitialization > xInit( xController, UNO_QUERY );
374 if ( xInit.is() && bMustBeInit )
375 {
376 PropertyValue aPropValue;
377 Sequence< Any > aArgs( 3 );
378 aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
379 aPropValue.Value <<= m_xFrame;
380 aArgs[0] <<= aPropValue;
381 aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
382 aPropValue.Value <<= aURL;
383 aArgs[1] <<= aPropValue;
384 aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
385 aPropValue.Value <<= m_xServiceManager;
386 aArgs[2] <<= aPropValue;
387 try
388 {
389 xInit->initialize( aArgs );
390 }
391 catch ( uno::Exception& )
392 {
393 }
394 }
395
396 // Request a item window from the toolbar controller and set it at the VCL toolbar
397 Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
398 if ( xTbxController.is() && xToolbarWindow.is() )
399 {
400 Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow );
401 if ( xWindow.is() )
402 {
403 Window* pItemWin = VCLUnoHelper::GetWindow( xWindow );
404 if ( pItemWin )
405 {
406 WindowType nType = pItemWin->GetType();
407 if ( nType == WINDOW_LISTBOX || nType == WINDOW_MULTILISTBOX || nType == WINDOW_COMBOBOX )
408 pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) );
409 m_pToolBar->SetItemWindow( nId, pItemWin );
410 }
411 }
412 }
413
414 // Notify controller implementation to its listeners. Controller is now useable from outside.
415 Reference< XUpdatable > xUpdatable( xController, UNO_QUERY );
416 if ( xUpdatable.is() )
417 {
418 try
419 {
420 xUpdatable->update();
421 }
422 catch ( uno::Exception& )
423 {
424 }
425 }
426
427 ++nId;
428 ++nElements;
429 }
430 }
431 }
432
433 AddFrameActionListener();
434 }
435
IMPL_LINK(AddonsToolBarManager,Click,ToolBox *,EMPTYARG)436 IMPL_LINK( AddonsToolBarManager, Click, ToolBox*, EMPTYARG )
437 {
438 if ( m_bDisposed )
439 return 1;
440
441 sal_uInt16 nId( m_pToolBar->GetCurItemId() );
442 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
443 if ( pIter != m_aControllerMap.end() )
444 {
445 Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
446
447 if ( xController.is() )
448 xController->click();
449 }
450
451 return 1;
452 }
453
IMPL_LINK(AddonsToolBarManager,DoubleClick,ToolBox *,EMPTYARG)454 IMPL_LINK( AddonsToolBarManager, DoubleClick, ToolBox*, EMPTYARG )
455 {
456 if ( m_bDisposed )
457 return 1;
458
459 sal_uInt16 nId( m_pToolBar->GetCurItemId() );
460 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
461 if ( pIter != m_aControllerMap.end() )
462 {
463 Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
464
465 if ( xController.is() )
466 xController->doubleClick();
467 }
468
469 return 1;
470 }
471
IMPL_LINK(AddonsToolBarManager,Command,CommandEvent *,EMPTYARG)472 IMPL_LINK( AddonsToolBarManager, Command, CommandEvent*, EMPTYARG )
473 {
474 ResetableGuard aGuard( m_aLock );
475
476 if ( m_bDisposed )
477 return 1;
478
479 return 0;
480 }
481
IMPL_LINK(AddonsToolBarManager,Select,ToolBox *,EMPTYARG)482 IMPL_LINK( AddonsToolBarManager, Select, ToolBox*, EMPTYARG )
483 {
484 if ( m_bDisposed )
485 return 1;
486
487 sal_Int16 nKeyModifier( (sal_Int16)m_pToolBar->GetModifier() );
488 sal_uInt16 nId( m_pToolBar->GetCurItemId() );
489 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
490 if ( pIter != m_aControllerMap.end() )
491 {
492 Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
493
494 if ( xController.is() )
495 xController->execute( nKeyModifier );
496 }
497
498 return 1;
499 }
500
IMPL_LINK(AddonsToolBarManager,Highlight,ToolBox *,EMPTYARG)501 IMPL_LINK( AddonsToolBarManager, Highlight, ToolBox*, EMPTYARG )
502 {
503 return 1;
504 }
505
IMPL_LINK(AddonsToolBarManager,Activate,ToolBox *,EMPTYARG)506 IMPL_LINK( AddonsToolBarManager, Activate, ToolBox*, EMPTYARG )
507 {
508 return 1;
509 }
510
IMPL_LINK(AddonsToolBarManager,Deactivate,ToolBox *,EMPTYARG)511 IMPL_LINK( AddonsToolBarManager, Deactivate, ToolBox*, EMPTYARG )
512 {
513 return 1;
514 }
515
IMPL_LINK(AddonsToolBarManager,StateChanged,StateChangedType *,pStateChangedType)516 IMPL_LINK( AddonsToolBarManager, StateChanged, StateChangedType*, pStateChangedType )
517 {
518 if ( *pStateChangedType == STATE_CHANGE_CONTROLBACKGROUND )
519 {
520 // Check if we need to get new images for normal/high contrast mode
521 CheckAndUpdateImages();
522 }
523 return 1;
524 }
525
IMPL_LINK(AddonsToolBarManager,DataChanged,DataChangedEvent *,pDataChangedEvent)526 IMPL_LINK( AddonsToolBarManager, DataChanged, DataChangedEvent*, pDataChangedEvent )
527 {
528 if ((( pDataChangedEvent->GetType() == DATACHANGED_SETTINGS ) ||
529 ( pDataChangedEvent->GetType() == DATACHANGED_DISPLAY )) &&
530 ( pDataChangedEvent->GetFlags() & SETTINGS_STYLE ))
531 {
532 // Check if we need to get new images for normal/high contrast mode
533 CheckAndUpdateImages();
534 }
535
536 for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
537 {
538 const sal_uInt16 nId = m_pToolBar->GetItemId(nPos);
539 Window* pWindow = m_pToolBar->GetItemWindow( nId );
540 if ( pWindow )
541 {
542 const DataChangedEvent& rDCEvt( *pDataChangedEvent );
543 pWindow->DataChanged( rDCEvt );
544 }
545 }
546
547 return 1;
548 }
549
550 }
551
552