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 
27 #include <uielement/statusbarmanager.hxx>
28 #include <uielement/genericstatusbarcontroller.hxx>
29 
30 #include <threadhelp/threadhelpbase.hxx>
31 #include <threadhelp/resetableguard.hxx>
32 #include <framework/sfxhelperfunctions.hxx>
33 #include <framework/addonsoptions.hxx>
34 #include <uielement/statusbarmerger.hxx>
35 #include <uielement/statusbaritem.hxx>
36 #include <macros/generic.hxx>
37 #include <macros/xinterface.hxx>
38 #include <macros/xtypeprovider.hxx>
39 #include <stdtypes.h>
40 #include "services.h"
41 #include "general.h"
42 #include "properties.h"
43 #include <helper/mischelper.hxx>
44 
45 #include <com/sun/star/frame/XFrame.hpp>
46 #include <com/sun/star/frame/XStatusListener.hpp>
47 #include <com/sun/star/util/XUpdatable.hpp>
48 #include <com/sun/star/ui/ItemStyle.hpp>
49 #include <com/sun/star/ui/ItemType.hpp>
50 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
51 #include <com/sun/star/beans/XPropertySet.hpp>
52 #include <com/sun/star/awt/Command.hpp>
53 #include <com/sun/star/ui/XStatusbarItem.hdl>
54 #include <com/sun/star/lang/DisposedException.hpp>
55 
56 #include <toolkit/helper/vclunohelper.hxx>
57 
58 #include <svtools/statusbarcontroller.hxx>
59 
60 #include <vcl/status.hxx>
61 #include <vcl/svapp.hxx>
62 #include <rtl/logfile.hxx>
63 
64 #include <functional>
65 
66 using namespace ::com::sun::star;
67 #ifndef css
68 #define css ::com::sun::star
69 #endif
70 #ifndef css_ui
71 #define css_ui ::com::sun::star::ui
72 #endif
73 
74 const sal_Int32  HELPID_PREFIX_LENGTH    = 7;
75 static const char*      HELPID_PREFIX           = "helpid:";
76 
77 // Property names of a menu/menu item ItemDescriptor
78 static const char ITEM_DESCRIPTOR_COMMANDURL[]  = "CommandURL";
79 static const char ITEM_DESCRIPTOR_HELPURL[]     = "HelpURL";
80 static const char ITEM_DESCRIPTOR_OFFSET[]      = "Offset";
81 static const char ITEM_DESCRIPTOR_STYLE[]       = "Style";
82 static const char ITEM_DESCRIPTOR_WIDTH[]       = "Width";
83 static const char ITEM_DESCRIPTOR_TYPE[]        = "Type";
84 
85 namespace framework
86 {
87 
88 namespace
89 {
90 
91 template< class MAP >
92 struct lcl_UpdateController : public std::unary_function< typename MAP::value_type, void >
93 {
94     void operator()( typename MAP::value_type &rElement ) const
95     {
96         try
97         {
98             uno::Reference< util::XUpdatable > xUpdatable( rElement.second, uno::UNO_QUERY );
99             if ( xUpdatable.is() )
100                 xUpdatable->update();
101         }
102         catch ( uno::Exception& )
103         {
104         }
105     }
106 };
107 
108 template< class MAP >
109 struct lcl_RemoveController : public std::unary_function< typename MAP::value_type, void >
110 {
111     void operator()( typename MAP::value_type &rElement ) const
112     {
113         try
114         {
115             uno::Reference< lang::XComponent > xComponent( rElement.second, uno::UNO_QUERY );
116             if ( xComponent.is() )
117                 xComponent->dispose();
118         }
119         catch ( uno::Exception& )
120         {
121         }
122     }
123 };
124 
125 static sal_uInt16 impl_convertItemStyleToItemBits( sal_Int16 nStyle )
126 {
127     sal_uInt16 nItemBits( 0 );
128 
129     if (( nStyle & css_ui::ItemStyle::ALIGN_RIGHT ) == css_ui::ItemStyle::ALIGN_RIGHT )
130         nItemBits |= SIB_RIGHT;
131     else if ( nStyle & css_ui::ItemStyle::ALIGN_LEFT )
132         nItemBits |= SIB_LEFT;
133     else
134         nItemBits |= SIB_CENTER;
135 
136     if (( nStyle & css_ui::ItemStyle::DRAW_FLAT ) == css_ui::ItemStyle::DRAW_FLAT )
137         nItemBits |= SIB_FLAT;
138     else if ( nStyle & css_ui::ItemStyle::DRAW_OUT3D )
139         nItemBits |= SIB_OUT;
140     else
141         nItemBits |= SIB_IN;
142 
143     if (( nStyle & css_ui::ItemStyle::AUTO_SIZE ) == css_ui::ItemStyle::AUTO_SIZE )
144         nItemBits |= SIB_AUTOSIZE;
145     if ( nStyle & css_ui::ItemStyle::OWNER_DRAW )
146         nItemBits |= SIB_USERDRAW;
147 
148     return nItemBits;
149 }
150 
151 }
152 //*****************************************************************************************************************
153 //	XInterface, XTypeProvider, XServiceInfo
154 //*****************************************************************************************************************
155 DEFINE_XINTERFACE_5                     (   StatusBarManager                                                        ,
156                                             ::cppu::OWeakObject                                                     ,
157                                             DIRECT_INTERFACE( lang::XTypeProvider                                   ),
158                                             DIRECT_INTERFACE( lang::XComponent                                      ),
159 											DIRECT_INTERFACE( frame::XFrameActionListener                           ),
160                                             DIRECT_INTERFACE( css::ui::XUIConfigurationListener                    ),
161 											DERIVED_INTERFACE( lang::XEventListener, frame::XFrameActionListener    )
162 										)
163 
164 DEFINE_XTYPEPROVIDER_5                  (   StatusBarManager                    ,
165                                             lang::XTypeProvider		            ,
166                                             lang::XComponent                    ,
167                                             css::ui::XUIConfigurationListener  ,
168 											frame::XFrameActionListener         ,
169 											lang::XEventListener
170 										)
171 
172 StatusBarManager::StatusBarManager(
173     const uno::Reference< lang::XMultiServiceFactory >& rServiceManager,
174     const uno::Reference< frame::XFrame >& rFrame,
175     const rtl::OUString& rResourceName,
176     StatusBar* pStatusBar ) :
177     ThreadHelpBase( &Application::GetSolarMutex() ),
178     OWeakObject(),
179     m_bDisposed( sal_False ),
180     m_bFrameActionRegistered( sal_False ),
181     m_bUpdateControllers( sal_False ),
182     m_bModuleIdentified( sal_False ),
183     m_pStatusBar( pStatusBar ),
184     m_aResourceName( rResourceName ),
185     m_xFrame( rFrame ),
186     m_aListenerContainer( m_aLock.getShareableOslMutex() ),
187     m_xServiceManager( rServiceManager )
188 {
189     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::StatusBarManager" );
190 
191     if ( m_xServiceManager.is() )
192         m_xStatusbarControllerRegistration = uno::Reference< css::frame::XUIControllerRegistration >(
193                                                     m_xServiceManager->createInstance( SERVICENAME_STATUSBARCONTROLLERFACTORY ),
194                                                     uno::UNO_QUERY );
195 
196     m_pStatusBar->SetClickHdl( LINK( this, StatusBarManager, Click ) );
197     m_pStatusBar->SetDoubleClickHdl( LINK( this, StatusBarManager, DoubleClick ) );
198 }
199 
200 StatusBarManager::~StatusBarManager()
201 {
202 }
203 
204 StatusBar* StatusBarManager::GetStatusBar() const
205 {
206     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::GetStatusBar" );
207     ResetableGuard aGuard( m_aLock );
208     return m_pStatusBar;
209 }
210 
211 void StatusBarManager::frameAction( const frame::FrameActionEvent& Action )
212 throw ( uno::RuntimeException )
213 {
214     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::frameAction" );
215     ResetableGuard aGuard( m_aLock );
216     if ( Action.Action == frame::FrameAction_CONTEXT_CHANGED )
217         UpdateControllers();
218 }
219 
220 void SAL_CALL StatusBarManager::disposing( const lang::EventObject& Source ) throw ( uno::RuntimeException )
221 {
222     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::disposing" );
223     {
224         ResetableGuard aGuard( m_aLock );
225         if ( m_bDisposed )
226             return;
227     }
228 
229     RemoveControllers();
230 
231 	{
232 	    ResetableGuard aGuard( m_aLock );
233         if ( Source.Source == uno::Reference< uno::XInterface >( m_xFrame, uno::UNO_QUERY ))
234             m_xFrame.clear();
235 
236         m_xServiceManager.clear();
237     }
238 }
239 
240 // XComponent
241 void SAL_CALL StatusBarManager::dispose() throw( uno::RuntimeException )
242 {
243     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::dispose" );
244     uno::Reference< lang::XComponent > xThis(
245         static_cast< OWeakObject* >(this), uno::UNO_QUERY );
246 
247     lang::EventObject aEvent( xThis );
248     m_aListenerContainer.disposeAndClear( aEvent );
249 
250     {
251 	    ResetableGuard aGuard( m_aLock );
252         if ( !m_bDisposed )
253         {
254             RemoveControllers();
255 
256             // destroy the item data
257             for ( sal_uInt16 n = 0; n < m_pStatusBar->GetItemCount(); n++ )
258             {
259                 AddonStatusbarItemData *pUserData = static_cast< AddonStatusbarItemData *>(
260                     m_pStatusBar->GetItemData( m_pStatusBar->GetItemId( n ) ) );
261                 if ( pUserData )
262                     delete pUserData;
263             }
264 
265             delete m_pStatusBar;
266             m_pStatusBar = 0;
267 
268             if ( m_bFrameActionRegistered && m_xFrame.is() )
269             {
270                 try
271                 {
272                     m_xFrame->removeFrameActionListener( uno::Reference< frame::XFrameActionListener >(
273                                                             static_cast< ::cppu::OWeakObject *>( this ),
274                                                             uno::UNO_QUERY ));
275                 }
276                 catch ( uno::Exception& )
277                 {
278                 }
279             }
280 
281             m_xFrame.clear();
282             m_xServiceManager.clear();
283 
284             m_bDisposed = sal_True;
285         }
286     }
287 }
288 
289 void SAL_CALL StatusBarManager::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) throw( uno::RuntimeException )
290 {
291     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::addEventListener" );
292     ResetableGuard aGuard( m_aLock );
293 
294 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
295     if ( m_bDisposed )
296         throw lang::DisposedException();
297 
298     m_aListenerContainer.addInterface( ::getCppuType(
299         ( const uno::Reference< lang::XEventListener >* ) NULL ), xListener );
300 }
301 
302 void SAL_CALL StatusBarManager::removeEventListener( const uno::Reference< lang::XEventListener >& xListener ) throw( uno::RuntimeException )
303 {
304     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::removeEventListener" );
305     m_aListenerContainer.removeInterface( ::getCppuType(
306         ( const uno::Reference< lang::XEventListener >* ) NULL ), xListener );
307 }
308 
309 // XUIConfigurationListener
310 void SAL_CALL StatusBarManager::elementInserted( const css::ui::ConfigurationEvent& ) throw ( uno::RuntimeException )
311 {
312     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::elementInserted" );
313     ResetableGuard aGuard( m_aLock );
314 
315     if ( m_bDisposed )
316         return;
317 }
318 
319 void SAL_CALL StatusBarManager::elementRemoved( const css::ui::ConfigurationEvent& ) throw ( uno::RuntimeException )
320 {
321     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::elementRemoved" );
322     ResetableGuard aGuard( m_aLock );
323 
324     if ( m_bDisposed )
325         return;
326 }
327 
328 void SAL_CALL StatusBarManager::elementReplaced( const css::ui::ConfigurationEvent& ) throw ( uno::RuntimeException )
329 {
330     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::elementReplaced" );
331     ResetableGuard aGuard( m_aLock );
332 
333     if ( m_bDisposed )
334         return;
335 }
336 
337 void StatusBarManager::UpdateControllers()
338 {
339     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::UpdateControllers" );
340     if ( !m_bUpdateControllers )
341     {
342         m_bUpdateControllers = sal_True;
343         std::for_each( m_aControllerMap.begin(),
344                        m_aControllerMap.end(),
345                        lcl_UpdateController< StatusBarControllerMap >() );
346     }
347     m_bUpdateControllers = sal_False;
348 }
349 
350 void StatusBarManager::RemoveControllers()
351 {
352     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::RemoveControllers" );
353     ResetableGuard aGuard( m_aLock );
354 
355     if ( m_bDisposed )
356         return;
357 
358     std::for_each( m_aControllerMap.begin(),
359                    m_aControllerMap.end(),
360                    lcl_RemoveController< StatusBarControllerMap >() );
361     m_aControllerMap.clear();
362 }
363 
364 rtl::OUString StatusBarManager::RetrieveLabelFromCommand( const rtl::OUString& aCmdURL )
365 {
366     return framework::RetrieveLabelFromCommand(aCmdURL,m_xServiceManager,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Name");
367 }
368 
369 void StatusBarManager::CreateControllers()
370 {
371     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::CreateControllers" );
372     uno::Reference< lang::XMultiComponentFactory > xStatusbarControllerFactory( m_xStatusbarControllerRegistration, uno::UNO_QUERY );
373     uno::Reference< uno::XComponentContext > xComponentContext;
374     uno::Reference< beans::XPropertySet > xProps( m_xServiceManager, uno::UNO_QUERY );
375     uno::Reference< awt::XWindow > xStatusbarWindow = VCLUnoHelper::GetInterface( m_pStatusBar );
376 
377     if ( xProps.is() )
378         xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComponentContext;
379 
380     for ( sal_uInt16 i = 0; i < m_pStatusBar->GetItemCount(); i++ )
381     {
382         sal_uInt16 nId = m_pStatusBar->GetItemId( i );
383         if ( nId == 0 )
384             continue;
385 
386         rtl::OUString                            aCommandURL( m_pStatusBar->GetItemCommand( nId ));
387         sal_Bool                                 bInit( sal_True );
388         uno::Reference< frame::XStatusListener > xController;
389         AddonStatusbarItemData *pItemData = static_cast< AddonStatusbarItemData *>( m_pStatusBar->GetItemData( nId ) );
390         uno::Reference< ui::XStatusbarItem > xStatusbarItem(
391             static_cast< cppu::OWeakObject *>( new StatusbarItem( m_pStatusBar, pItemData, nId, aCommandURL ) ),
392             uno::UNO_QUERY );
393 
394         svt::StatusbarController* pController( 0 );
395 
396         // 1º) UNO Statusbar controllers, registered in Controllers.xcu
397         if ( m_xStatusbarControllerRegistration.is() &&
398              m_xStatusbarControllerRegistration->hasController( aCommandURL, m_aModuleIdentifier ))
399         {
400             if ( xStatusbarControllerFactory.is() )
401             {
402                 beans::PropertyValue aPropValue;
403                 std::vector< uno::Any > aPropVector;
404 
405                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
406                 aPropValue.Value    = uno::makeAny( m_aModuleIdentifier );
407                 aPropVector.push_back( uno::makeAny( aPropValue ) );
408 
409                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
410                 aPropValue.Value    = uno::makeAny( m_xFrame );
411                 aPropVector.push_back( uno::makeAny( aPropValue ) );
412 
413                 // TODO remove this
414                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
415                 aPropValue.Value    = uno::makeAny( m_xServiceManager );
416                 aPropVector.push_back( uno::makeAny( aPropValue ) );
417 
418                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
419                 aPropValue.Value    = uno::makeAny( xStatusbarWindow );
420                 aPropVector.push_back( uno::makeAny( aPropValue ) );
421 
422                 // TODO still needing with the css::ui::XStatusbarItem?
423                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Identifier" ));
424                 aPropValue.Value    = uno::makeAny( nId );
425                 aPropVector.push_back( uno::makeAny( aPropValue ) );
426 
427                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusbarItem" ));
428                 aPropValue.Value    <<= xStatusbarItem;
429                 aPropVector.push_back( uno::makeAny( aPropValue ) );
430 
431                 uno::Sequence< uno::Any > aArgs( comphelper::containerToSequence( aPropVector ) );
432                 xController = uno::Reference< frame::XStatusListener >(
433                                 xStatusbarControllerFactory->createInstanceWithArgumentsAndContext(
434                                     aCommandURL, aArgs, xComponentContext ),
435                                 uno::UNO_QUERY );
436                 bInit = sal_False; // Initialization is done through the factory service
437             }
438         }
439 
440         if ( !xController.is() )
441         {
442             // 2º) Old SFX2 Statusbar controllers
443             pController = CreateStatusBarController( m_xFrame, m_pStatusBar, nId, aCommandURL );
444             if ( !pController )
445             {
446                 // 3º) Is Add-on? Generic statusbar controller
447                 if ( pItemData )
448                 {
449                     pController = new GenericStatusbarController( m_xServiceManager,
450                                                                   m_xFrame,
451                                                                   xStatusbarItem,
452                                                                   pItemData );
453                 }
454                 else
455                 {
456                     // 4º) Default Statusbar controller
457                     pController = new svt::StatusbarController( m_xServiceManager, m_xFrame, aCommandURL, nId );
458                 }
459             }
460 
461             if ( pController )
462                 xController = uno::Reference< frame::XStatusListener >(
463                                 static_cast< ::cppu::OWeakObject *>( pController ),
464                                 uno::UNO_QUERY );
465         }
466 
467         m_aControllerMap[nId] = xController;
468         uno::Reference< lang::XInitialization > xInit( xController, uno::UNO_QUERY );
469 
470         if ( xInit.is() )
471         {
472             if ( bInit )
473             {
474                 beans::PropertyValue aPropValue;
475                 uno::Sequence< uno::Any > aArgs( 6 );
476                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
477                 aPropValue.Value    = uno::makeAny( m_xFrame );
478                 aArgs[0] = uno::makeAny( aPropValue );
479                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
480                 aPropValue.Value    = uno::makeAny( aCommandURL );
481                 aArgs[1] = uno::makeAny( aPropValue );
482                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
483                 aPropValue.Value    = uno::makeAny( m_xServiceManager );
484                 aArgs[2] = uno::makeAny( aPropValue );
485                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
486                 aPropValue.Value    = uno::makeAny( xStatusbarWindow );
487                 aArgs[3] = uno::makeAny( aPropValue );
488                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Identifier" ));
489                 aPropValue.Value    = uno::makeAny( nId );
490                 aArgs[4] = uno::makeAny( aPropValue );
491                 aPropValue.Name     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusbarItem" ));
492                 aPropValue.Value    <<= xStatusbarItem;
493                 aArgs[5] = uno::makeAny( aPropValue );
494                 xInit->initialize( aArgs );
495             }
496         }
497     }
498 
499     AddFrameActionListener();
500 }
501 
502 void StatusBarManager::AddFrameActionListener()
503 {
504     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::AddFrameActionListener" );
505     if ( !m_bFrameActionRegistered && m_xFrame.is() )
506     {
507         m_bFrameActionRegistered = sal_True;
508         m_xFrame->addFrameActionListener( uno::Reference< frame::XFrameActionListener >(
509             static_cast< ::cppu::OWeakObject *>( this ), uno::UNO_QUERY ));
510     }
511 }
512 
513 void StatusBarManager::FillStatusBar( const uno::Reference< container::XIndexAccess >& rItemContainer )
514 {
515     RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::StatusBarManager::FillStatusbar" );
516 
517     ResetableGuard aGuard( m_aLock );
518 
519     if ( m_bDisposed || !m_pStatusBar )
520         return;
521 
522     sal_uInt16         nId( 1 );
523     rtl::OUString  aHelpIdPrefix( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ));
524 
525     RemoveControllers();
526 
527     // reset and fill command map
528     m_pStatusBar->Clear();
529     m_aControllerMap.clear();// TODO already done in RemoveControllers
530 
531     for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
532     {
533         RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::FillStatusBar" );
534         uno::Sequence< beans::PropertyValue >   aProp;
535         rtl::OUString                           aCommandURL;
536         rtl::OUString                           aHelpURL;
537         sal_Int16                               nOffset( 0 );
538         sal_Int16                               nStyle( 0 );
539         sal_Int16                               nWidth( 0 );
540         sal_uInt16                              nType( css_ui::ItemType::DEFAULT );
541 
542         try
543         {
544             if ( rItemContainer->getByIndex( n ) >>= aProp )
545             {
546                 for ( int i = 0; i < aProp.getLength(); i++ )
547                 {
548                     if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
549                     {
550                         aProp[i].Value >>= aCommandURL;
551                     }
552                     else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL ))
553                     {
554                         aProp[i].Value >>= aHelpURL;
555                     }
556                     else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE ))
557                     {
558                         aProp[i].Value >>= nStyle;
559                     }
560                     else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE ))
561                     {
562                         aProp[i].Value >>= nType;
563                     }
564                     else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_WIDTH ))
565                     {
566                         aProp[i].Value >>= nWidth;
567                     }
568                     else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_OFFSET ))
569                     {
570                         aProp[i].Value >>= nOffset;
571                     }
572                 }
573 
574                 if (( nType == ::com::sun::star::ui::ItemType::DEFAULT ) && ( aCommandURL.getLength() > 0 ))
575                 {
576                     rtl::OUString aString( RetrieveLabelFromCommand( aCommandURL ));
577                     sal_uInt16        nItemBits( impl_convertItemStyleToItemBits( nStyle ));
578 
579                     m_pStatusBar->InsertItem( nId, nWidth, nItemBits, nOffset );
580                     m_pStatusBar->SetItemCommand( nId, aCommandURL );
581                     m_pStatusBar->SetAccessibleName( nId, aString );
582                     ++nId;
583                 }
584             }
585         }
586         catch ( ::com::sun::star::lang::IndexOutOfBoundsException& )
587         {
588             break;
589         }
590     }
591 
592     // Statusbar Merging
593     const sal_uInt16 STATUSBAR_ITEM_STARTID = 1000;
594     MergeStatusbarInstructionContainer aMergeInstructions = AddonsOptions().GetMergeStatusbarInstructions();
595     if ( !aMergeInstructions.empty() )
596     {
597         const sal_uInt32 nCount = aMergeInstructions.size();
598         sal_uInt16 nItemId( STATUSBAR_ITEM_STARTID );
599 
600         for ( sal_uInt32 i = 0; i < nCount; i++ )
601         {
602             MergeStatusbarInstruction &rInstruction = aMergeInstructions[i];
603             if ( !StatusbarMerger::IsCorrectContext( rInstruction.aMergeContext, m_aModuleIdentifier ) )
604                 continue;
605 
606             AddonStatusbarItemContainer aItems;
607             StatusbarMerger::ConvertSeqSeqToVector( rInstruction.aMergeStatusbarItems, aItems );
608 
609             sal_uInt16 nRefPos = StatusbarMerger::FindReferencePos( m_pStatusBar, rInstruction.aMergePoint );
610             if ( nRefPos != STATUSBAR_ITEM_NOTFOUND )
611             {
612                 StatusbarMerger::ProcessMergeOperation( m_pStatusBar,
613                                                         nRefPos,
614                                                         nItemId,
615                                                         m_aModuleIdentifier,
616                                                         rInstruction.aMergeCommand,
617                                                         rInstruction.aMergeCommandParameter,
618                                                         aItems );
619             }
620             else
621             {
622                 StatusbarMerger::ProcessMergeFallback( m_pStatusBar,
623                                                        nRefPos,
624                                                        nItemId,
625                                                        m_aModuleIdentifier,
626                                                        rInstruction.aMergeCommand,
627                                                        rInstruction.aMergeCommandParameter,
628                                                        aItems );
629             }
630         }
631     }
632 
633     // Create controllers
634     CreateControllers();
635 
636     // Notify controllers that they are now correctly initialized and can start listening
637     UpdateControllers();
638 }
639 
640 void StatusBarManager::StateChanged( StateChangedType )
641 {
642     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::StateChanged" );
643 }
644 
645 void StatusBarManager::DataChanged( const DataChangedEvent& rDCEvt )
646 {
647     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::DataChanged" );
648     ResetableGuard aGuard( m_aLock );
649 
650     if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS	        ) ||
651          ( rDCEvt.GetType() == DATACHANGED_FONTS            ) ||
652 		 ( rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION ) ||
653 		 ( rDCEvt.GetType() == DATACHANGED_DISPLAY	        ))	&&
654          ( rDCEvt.GetFlags() & SETTINGS_STYLE		        ))
655     {
656         css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
657         css::uno::Reference< css::beans::XPropertySet > xPropSet( m_xFrame, css::uno::UNO_QUERY );
658         if ( xPropSet.is() )
659             xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager;
660         if ( xLayoutManager.is() )
661         {
662             aGuard.unlock();
663             xLayoutManager->doLayout();
664         }
665     }
666 }
667 
668 void StatusBarManager::UserDraw( const UserDrawEvent& rUDEvt )
669 {
670     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::UserDraw" );
671     ResetableGuard aGuard( m_aLock );
672 
673     if ( m_bDisposed )
674         return;
675 
676     sal_uInt16 nId( rUDEvt.GetItemId() );
677     StatusBarControllerMap::const_iterator it = m_aControllerMap.find( nId );
678     if (( nId > 0 ) && ( it != m_aControllerMap.end() ))
679     {
680         uno::Reference< frame::XStatusbarController > xController( it->second, uno::UNO_QUERY );
681         if ( xController.is() && rUDEvt.GetDevice() )
682         {
683             uno::Reference< awt::XGraphics > xGraphics =
684                 rUDEvt.GetDevice()->CreateUnoGraphics();
685 
686             awt::Rectangle aRect( rUDEvt.GetRect().Left(),
687                                   rUDEvt.GetRect().Top(),
688                                   rUDEvt.GetRect().GetWidth(),
689                                   rUDEvt.GetRect().GetHeight() );
690             aGuard.unlock();
691             xController->paint( xGraphics, aRect, rUDEvt.GetStyle() );
692         }
693     }
694 }
695 
696 void StatusBarManager::Command( const CommandEvent& rEvt )
697 {
698     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::Command" );
699     ResetableGuard aGuard( m_aLock );
700 
701     if ( m_bDisposed )
702         return;
703 
704     if ( rEvt.GetCommand() == COMMAND_CONTEXTMENU )
705     {
706         sal_uInt16 nId = m_pStatusBar->GetItemId( rEvt.GetMousePosPixel() );
707         StatusBarControllerMap::const_iterator it = m_aControllerMap.find( nId );
708         if (( nId > 0 ) && ( it != m_aControllerMap.end() ))
709         {
710             uno::Reference< frame::XStatusbarController > xController( it->second, uno::UNO_QUERY );
711             if ( xController.is() )
712             {
713                 awt::Point aPos;
714                 aPos.X = rEvt.GetMousePosPixel().X();
715                 aPos.Y = rEvt.GetMousePosPixel().Y();
716                 xController->command( aPos, awt::Command::CONTEXTMENU, sal_True, uno::Any() );
717             }
718         }
719     }
720 }
721 
722 void StatusBarManager::MouseMove( const MouseEvent& rMEvt )
723 {
724     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::MouseMove" );
725     MouseButton(rMEvt,&frame::XStatusbarController::mouseMove);
726 }
727 
728 void StatusBarManager::MouseButton( const MouseEvent& rMEvt ,sal_Bool ( SAL_CALL frame::XStatusbarController::*_pMethod )(const ::com::sun::star::awt::MouseEvent&))
729 {
730     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::MouseButton" );
731     ResetableGuard aGuard( m_aLock );
732 
733     if ( !m_bDisposed )
734     {
735         sal_uInt16 nId = m_pStatusBar->GetItemId( rMEvt.GetPosPixel() );
736         StatusBarControllerMap::const_iterator it = m_aControllerMap.find( nId );
737         if (( nId > 0 ) && ( it != m_aControllerMap.end() ))
738         {
739             uno::Reference< frame::XStatusbarController > xController( it->second, uno::UNO_QUERY );
740             if ( xController.is() )
741             {
742                 ::com::sun::star::awt::MouseEvent aMouseEvent;
743                 aMouseEvent.Buttons = rMEvt.GetButtons();
744                 aMouseEvent.X = rMEvt.GetPosPixel().X();
745                 aMouseEvent.Y = rMEvt.GetPosPixel().Y();
746                 aMouseEvent.ClickCount = rMEvt.GetClicks();
747                 (xController.get()->*_pMethod)( aMouseEvent);
748             }
749         }
750     }
751 }
752 
753 void StatusBarManager::MouseButtonDown( const MouseEvent& rMEvt )
754 {
755     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::MouseButtonDown" );
756     MouseButton(rMEvt,&frame::XStatusbarController::mouseButtonDown);
757 }
758 
759 void StatusBarManager::MouseButtonUp( const MouseEvent& rMEvt )
760 {
761     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::MouseButtonUp" );
762     MouseButton(rMEvt,&frame::XStatusbarController::mouseButtonUp);
763 }
764 
765 IMPL_LINK( StatusBarManager, Click, StatusBar*, EMPTYARG )
766 {
767     ResetableGuard aGuard( m_aLock );
768 
769     if ( m_bDisposed )
770         return 1;
771 
772     sal_uInt16 nId = m_pStatusBar->GetCurItemId();
773     StatusBarControllerMap::const_iterator it = m_aControllerMap.find( nId );
774     if (( nId > 0 ) && ( it != m_aControllerMap.end() ))
775     {
776         uno::Reference< frame::XStatusbarController > xController( it->second, uno::UNO_QUERY );
777         if ( xController.is() )
778         {
779             const Point aVCLPos = m_pStatusBar->GetPointerPosPixel();
780             const awt::Point aAWTPoint( aVCLPos.X(), aVCLPos.Y() );
781             xController->click( aAWTPoint );
782         }
783     }
784 
785     return 1;
786 }
787 
788 IMPL_LINK( StatusBarManager, DoubleClick, StatusBar*, EMPTYARG )
789 {
790     ResetableGuard aGuard( m_aLock );
791 
792     if ( m_bDisposed )
793         return 1;
794 
795     sal_uInt16 nId = m_pStatusBar->GetCurItemId();
796     StatusBarControllerMap::const_iterator it = m_aControllerMap.find( nId );
797     if (( nId > 0 ) && ( it != m_aControllerMap.end() ))
798     {
799         uno::Reference< frame::XStatusbarController > xController( it->second, uno::UNO_QUERY );
800         if ( xController.is() )
801         {
802             const Point aVCLPos = m_pStatusBar->GetPointerPosPixel();
803             const awt::Point aAWTPoint( aVCLPos.X(), aVCLPos.Y() );
804             xController->doubleClick( aAWTPoint );
805         }
806     }
807 
808     return 1;
809 }
810 
811 }
812