1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sfx2.hxx"
30 
31 //________________________________________________________________________________________________________
32 //	my own includes
33 //________________________________________________________________________________________________________
34 
35 #include <time.h>
36 #include <sfx2/sfxbasecontroller.hxx>
37 
38 //________________________________________________________________________________________________________
39 //	include of other projects
40 //________________________________________________________________________________________________________
41 #include <com/sun/star/awt/KeyEvent.hpp>
42 #include <com/sun/star/awt/KeyModifier.hpp>
43 #include <com/sun/star/awt/MouseEvent.hpp>
44 #include <com/sun/star/awt/MouseButton.hpp>
45 #include <com/sun/star/util/XCloseable.hpp>
46 #include <com/sun/star/util/XCloseBroadcaster.hpp>
47 #include <com/sun/star/util/XCloseListener.hpp>
48 #include <com/sun/star/util/CloseVetoException.hpp>
49 #include <com/sun/star/document/XViewDataSupplier.hpp>
50 #include <cppuhelper/implbase1.hxx>
51 #include <cppuhelper/implbase2.hxx>
52 #include <com/sun/star/frame/FrameActionEvent.hpp>
53 #include <com/sun/star/frame/FrameAction.hpp>
54 #include <com/sun/star/frame/CommandGroup.hpp>
55 #include <com/sun/star/frame/XFrame.hpp>
56 #include <com/sun/star/frame/XBorderResizeListener.hpp>
57 #include <com/sun/star/lang/DisposedException.hpp>
58 #include <com/sun/star/lang/EventObject.hpp>
59 #include <com/sun/star/lang/XEventListener.hpp>
60 #include <com/sun/star/lang/XComponent.hpp>
61 #include <com/sun/star/container/XIndexAccess.hpp>
62 #include <cppuhelper/interfacecontainer.hxx>
63 #include <cppuhelper/typeprovider.hxx>
64 #include <cppuhelper/implbase1.hxx>
65 #include <basic/sbstar.hxx>
66 #include <uno/mapping.hxx>
67 #include <sfx2/viewsh.hxx>
68 #include <sfx2/docfac.hxx>
69 #include <sfx2/viewfrm.hxx>
70 #include <sfx2/objsh.hxx>
71 #include <sfx2/app.hxx>
72 #include <sfx2/msgpool.hxx>
73 #include <sfx2/dispatch.hxx>
74 #include <sfx2/userinputinterception.hxx>
75 
76 #include <viewimp.hxx>
77 #include <sfx2/unoctitm.hxx>
78 #include <sfx2/childwin.hxx>
79 #include <sfx2/sfxsids.hrc>
80 #include <workwin.hxx>
81 #include <sfx2/objface.hxx>
82 
83 #include <vos/mutex.hxx>
84 #include <osl/mutex.hxx>
85 #include <tools/diagnose_ex.h>
86 #include <comphelper/sequence.hxx>
87 #include <rtl/ustrbuf.hxx>
88 #include <toolkit/helper/convert.hxx>
89 #include <framework/titlehelper.hxx>
90 #include <comphelper/processfactory.hxx>
91 #include <tools/diagnose_ex.h>
92 
93 #include <hash_map>
94 
95 #include <sfx2/event.hxx>
96 #include "sfx2/viewfac.hxx"
97 
98 #define	OMULTITYPEINTERFACECONTAINERHELPER		::cppu::OMultiTypeInterfaceContainerHelper
99 #define OINTERFACECONTAINERHELPER               ::cppu::OInterfaceContainerHelper
100 #define	XFRAMEACTIONLISTENER					::com::sun::star::frame::XFrameActionListener
101 #define	XCLOSELISTENER							::com::sun::star::util::XCloseListener
102 #define	FRAMEACTIONEVENT						::com::sun::star::frame::FrameActionEvent
103 #define	EVENTOBJECT								::com::sun::star::lang::EventObject
104 #define OTYPECOLLECTION							::cppu::OTypeCollection
105 #define OIMPLEMENTATIONID						::cppu::OImplementationId
106 #define	MUTEXGUARD								::osl::MutexGuard
107 #define	UNOQUERY								::com::sun::star::uno::UNO_QUERY
108 #define	MAPPING									::com::sun::star::uno::Mapping
109 #define XSTATUSINDICATORSUPPLIER                ::com::sun::star::task::XStatusIndicatorSupplier
110 #define XCOMPONENT                              ::com::sun::star::lang::XComponent
111 #define	XINTERFACE								::com::sun::star::uno::XInterface
112 #define XKEYHANDLER								::com::sun::star::awt::XKeyHandler
113 #define XMOUSECLICKHANDLER						::com::sun::star::awt::XMouseClickHandler
114 
115 #define TIMEOUT_START_RESCHEDULE	10L	/* 10th s */
116 
117 using namespace ::com::sun::star;
118 using ::com::sun::star::uno::Reference;
119 using ::com::sun::star::uno::RuntimeException;
120 using ::com::sun::star::uno::UNO_QUERY_THROW;
121 using ::com::sun::star::uno::UNO_SET_THROW;
122 using ::com::sun::star::lang::DisposedException;
123 using ::com::sun::star::awt::XWindow;
124 using ::com::sun::star::frame::XController;
125 using ::com::sun::star::frame::XDispatchProvider;
126 using ::com::sun::star::document::XViewDataSupplier;
127 using ::com::sun::star::container::XIndexAccess;
128 using ::com::sun::star::beans::PropertyValue;
129 using ::com::sun::star::uno::Sequence;
130 using ::com::sun::star::uno::UNO_QUERY;
131 using ::com::sun::star::uno::Exception;
132 using ::com::sun::star::frame::XFrame;
133 using ::com::sun::star::frame::XFrameActionListener;
134 using ::com::sun::star::util::XCloseListener;
135 using ::com::sun::star::task::XStatusIndicator;
136 using ::com::sun::star::frame::XTitle;
137 namespace css = ::com::sun::star;
138 
139 struct GroupIDToCommandGroup
140 {
141     sal_Int16   nGroupID;
142     sal_Int16   nCommandGroup;
143 };
144 
145 // Please update when a new command group is added
146 const sal_Int16 MAX_COMMANDGROUP = com::sun::star::frame::CommandGroup::CONTROLS;
147 
148 static sal_Bool                 bGroupIDMapInitialized = sal_False;
149 static GroupIDToCommandGroup    GroupIDCommandGroupMap[] =
150 {
151     { GID_INTERN        ,   com::sun::star::frame::CommandGroup::INTERNAL       },
152     { GID_APPLICATION   ,   com::sun::star::frame::CommandGroup::APPLICATION    },
153     { GID_DOCUMENT      ,   com::sun::star::frame::CommandGroup::DOCUMENT       },
154     { GID_VIEW		    ,   com::sun::star::frame::CommandGroup::VIEW           },
155     { GID_EDIT          ,   com::sun::star::frame::CommandGroup::EDIT           },
156     { GID_MACRO         ,   com::sun::star::frame::CommandGroup::MACRO          },
157     { GID_OPTIONS       ,   com::sun::star::frame::CommandGroup::OPTIONS        },
158     { GID_MATH  		,   com::sun::star::frame::CommandGroup::MATH           },
159     { GID_NAVIGATOR	    ,   com::sun::star::frame::CommandGroup::NAVIGATOR      },
160     { GID_INSERT		,   com::sun::star::frame::CommandGroup::INSERT         },
161     { GID_FORMAT        ,   com::sun::star::frame::CommandGroup::FORMAT         },
162     { GID_TEMPLATE      ,   com::sun::star::frame::CommandGroup::TEMPLATE       },
163     { GID_TEXT          ,   com::sun::star::frame::CommandGroup::TEXT           },
164     { GID_FRAME         ,   com::sun::star::frame::CommandGroup::FRAME          },
165     { GID_GRAPHIC       ,   com::sun::star::frame::CommandGroup::GRAPHIC        },
166     { GID_TABLE         ,   com::sun::star::frame::CommandGroup::TABLE          },
167     { GID_ENUMERATION   ,   com::sun::star::frame::CommandGroup::ENUMERATION    },
168     { GID_DATA          ,   com::sun::star::frame::CommandGroup::DATA           },
169     { GID_SPECIAL       ,   com::sun::star::frame::CommandGroup::SPECIAL        },
170     { GID_IMAGE         ,   com::sun::star::frame::CommandGroup::IMAGE          },
171     { GID_CHART         ,   com::sun::star::frame::CommandGroup::CHART          },
172     { GID_EXPLORER      ,   com::sun::star::frame::CommandGroup::EXPLORER       },
173     { GID_CONNECTOR     ,   com::sun::star::frame::CommandGroup::CONNECTOR      },
174     { GID_MODIFY        ,   com::sun::star::frame::CommandGroup::MODIFY         },
175     { GID_DRAWING       ,   com::sun::star::frame::CommandGroup::DRAWING        },
176     { GID_CONTROLS      ,   com::sun::star::frame::CommandGroup::CONTROLS       },
177     { 0                 ,   0                                                   }
178 };
179 
180 typedef std::hash_map< sal_Int16, sal_Int16 > GroupHashMap;
181 
182 
183 sal_Int16 MapGroupIDToCommandGroup( sal_Int16 nGroupID )
184 {
185     static GroupHashMap mHashMap;
186 
187     if ( !bGroupIDMapInitialized )
188     {
189         sal_Int32 i = 0;
190         while ( GroupIDCommandGroupMap[i].nGroupID != 0 )
191         {
192             mHashMap.insert( GroupHashMap::value_type(
193                 GroupIDCommandGroupMap[i].nGroupID,
194                 GroupIDCommandGroupMap[i].nCommandGroup ));
195             ++i;
196         }
197     }
198 
199     GroupHashMap::const_iterator pIter = mHashMap.find( nGroupID );
200     if ( pIter != mHashMap.end() )
201         return pIter->second;
202     else
203         return com::sun::star::frame::CommandGroup::INTERNAL;
204 }
205 
206 sal_Int16 MapCommandGroupToGroupID( sal_Int16 nCommandGroup )
207 {
208     sal_Int32 i = 0;
209     while ( GroupIDCommandGroupMap[i].nGroupID != 0 )
210     {
211         if ( GroupIDCommandGroupMap[i].nCommandGroup == nCommandGroup )
212             return GroupIDCommandGroupMap[i].nGroupID;
213         ++i;
214     }
215 
216     return -1;
217 }
218 
219 sal_Bool SupportsCommandGroup( sal_Int16 nCommandGroup )
220 {
221     if (( nCommandGroup >= 0 ) && ( nCommandGroup <= MAX_COMMANDGROUP ))
222         return sal_True;
223     else
224         return sal_False;
225 }
226 
227 sal_uInt32 Get10ThSec()
228 {
229 	sal_uInt32 n10Ticks = 10 * (sal_uInt32)clock();
230 	return n10Ticks / CLOCKS_PER_SEC;
231 }
232 
233 sal_Int32 m_nInReschedule = 0;	///	static counter for rescheduling
234 
235 void reschedule()
236 {
237 	if ( m_nInReschedule == 0 )
238 	{
239 		++m_nInReschedule;
240 		Application::Reschedule();
241 		--m_nInReschedule;
242 	}
243 }
244 
245 class SfxStatusIndicator : public ::cppu::WeakImplHelper2< ::com::sun::star::task::XStatusIndicator, ::com::sun::star::lang::XEventListener >
246 {
247 friend class SfxBaseController;
248     ::com::sun::star::uno::Reference < XController > xOwner;
249     ::com::sun::star::uno::Reference < ::com::sun::star::task::XStatusIndicator > xProgress;
250     SfxWorkWindow*          pWorkWindow;
251     sal_Int32               _nRange;
252     sal_Int32               _nValue;
253 	long					_nStartTime;
254 public:
255                             SfxStatusIndicator(SfxBaseController* pController, SfxWorkWindow* pWork)
256                                 : xOwner( pController )
257                                 , pWorkWindow( pWork )
258                             {
259 								++m_refCount;
260 								::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComponent(
261 									SAL_STATIC_CAST(::cppu::OWeakObject*, pController ), ::com::sun::star::uno::UNO_QUERY );
262 								if (xComponent.is())
263 									xComponent->addEventListener(this);
264 								--m_refCount;
265 							}
266 
267     virtual void SAL_CALL   start(const ::rtl::OUString& aText, sal_Int32 nRange) throw(::com::sun::star::uno::RuntimeException);
268     virtual void SAL_CALL   end(void) throw(::com::sun::star::uno::RuntimeException);
269     virtual void SAL_CALL   setText(const ::rtl::OUString& aText) throw(::com::sun::star::uno::RuntimeException);
270     virtual void SAL_CALL   setValue(sal_Int32 nValue) throw(::com::sun::star::uno::RuntimeException);
271     virtual void SAL_CALL   reset() throw(::com::sun::star::uno::RuntimeException);
272 
273 	virtual void SAL_CALL	disposing( const com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
274 };
275 
276 void SAL_CALL SfxStatusIndicator::start(const ::rtl::OUString& aText, sal_Int32 nRange) throw(::com::sun::star::uno::RuntimeException)
277 {
278     ::vos::OGuard aGuard( Application::GetSolarMutex() );
279     if ( xOwner.is() )
280 	{
281 		_nRange = nRange;
282 		_nValue = 0;
283 
284         if ( !xProgress.is() )
285             xProgress = pWorkWindow->GetStatusIndicator();
286 
287         if ( xProgress.is() )
288             xProgress->start( aText, nRange );
289 
290 		_nStartTime = Get10ThSec();
291     	reschedule();
292 	}
293 }
294 
295 void SAL_CALL SfxStatusIndicator::end(void) throw(::com::sun::star::uno::RuntimeException)
296 {
297     ::vos::OGuard aGuard( Application::GetSolarMutex() );
298     if ( xOwner.is() )
299 	{
300         if ( !xProgress.is() )
301             xProgress = pWorkWindow->GetStatusIndicator();
302 
303         if ( xProgress.is() )
304             xProgress->end();
305 
306         reschedule();
307 	}
308 }
309 
310 void SAL_CALL SfxStatusIndicator::setText(const ::rtl::OUString& aText) throw(::com::sun::star::uno::RuntimeException)
311 {
312     ::vos::OGuard aGuard( Application::GetSolarMutex() );
313     if ( xOwner.is() )
314 	{
315         if ( !xProgress.is() )
316             xProgress = pWorkWindow->GetStatusIndicator();
317 
318         if ( xProgress.is() )
319             xProgress->setText( aText );
320 
321     	reschedule();
322 	}
323 }
324 
325 void SAL_CALL SfxStatusIndicator::setValue( sal_Int32 nValue ) throw(::com::sun::star::uno::RuntimeException)
326 {
327     ::vos::OGuard aGuard( Application::GetSolarMutex() );
328     if ( xOwner.is() )
329 	{
330 		_nValue = nValue;
331 
332         if ( !xProgress.is() )
333             xProgress = pWorkWindow->GetStatusIndicator();
334 
335         if ( xProgress.is() )
336             xProgress->setValue( nValue );
337 
338         sal_Bool bReschedule = (( Get10ThSec() - _nStartTime ) > TIMEOUT_START_RESCHEDULE );
339 		if ( bReschedule )
340 			reschedule();
341 	}
342 }
343 
344 void SAL_CALL SfxStatusIndicator::reset() throw(::com::sun::star::uno::RuntimeException)
345 {
346     ::vos::OGuard aGuard( Application::GetSolarMutex() );
347     if ( xOwner.is() )
348 	{
349         if ( !xProgress.is() )
350             xProgress = pWorkWindow->GetStatusIndicator();
351 
352         if ( xProgress.is() )
353             xProgress->reset();
354 
355         reschedule();
356 	}
357 }
358 
359 void SAL_CALL SfxStatusIndicator::disposing( const com::sun::star::lang::EventObject& /*Source*/ ) throw(::com::sun::star::uno::RuntimeException)
360 {
361     ::vos::OGuard aGuard( Application::GetSolarMutex() );
362 	xOwner = 0;
363     xProgress.clear();
364 }
365 
366 //________________________________________________________________________________________________________
367 //________________________________________________________________________________________________________
368 //	declaration IMPL_SfxBaseController_ListenerHelper
369 //________________________________________________________________________________________________________
370 
371 class IMPL_SfxBaseController_ListenerHelper : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XFrameActionListener >
372 {
373 public:
374 	IMPL_SfxBaseController_ListenerHelper(	MUTEX&				aMutex		,
375 											SfxBaseController*	pController	) ;
376 	virtual ~IMPL_SfxBaseController_ListenerHelper() ;
377     virtual void SAL_CALL frameAction( const FRAMEACTIONEVENT& aEvent ) throw (RUNTIMEEXCEPTION) ;
378 	virtual void SAL_CALL disposing( const EVENTOBJECT& aEvent ) throw (RUNTIMEEXCEPTION) ;
379 
380 private:
381 
382 	MUTEX&					m_aMutex		;
383 	SfxBaseController*		m_pController	;
384 
385 } ;	// class IMPL_SfxBaseController_ListenerContainer
386 
387 class IMPL_SfxBaseController_CloseListenerHelper : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
388 {
389 public:
390 	IMPL_SfxBaseController_CloseListenerHelper(	MUTEX&				aMutex		,
391 											SfxBaseController*	pController	) ;
392 	virtual ~IMPL_SfxBaseController_CloseListenerHelper() ;
393     virtual void SAL_CALL queryClosing( const EVENTOBJECT& aEvent, sal_Bool bDeliverOwnership )
394         throw (RUNTIMEEXCEPTION, com::sun::star::util::CloseVetoException) ;
395     virtual void SAL_CALL notifyClosing( const EVENTOBJECT& aEvent ) throw (RUNTIMEEXCEPTION) ;
396 	virtual void SAL_CALL disposing( const EVENTOBJECT& aEvent ) throw (RUNTIMEEXCEPTION) ;
397 
398 private:
399 
400 	MUTEX&					m_aMutex;
401 	SfxBaseController*		m_pController;
402 
403 } ;	// class IMPL_SfxBaseController_ListenerContainer
404 
405 IMPL_SfxBaseController_CloseListenerHelper::IMPL_SfxBaseController_CloseListenerHelper(	MUTEX&				aMutex		,
406 																				SfxBaseController*	pController	)
407 		: m_aMutex		( aMutex		)
408 		, m_pController	( pController	)
409 {
410 }
411 
412 IMPL_SfxBaseController_CloseListenerHelper::~IMPL_SfxBaseController_CloseListenerHelper()
413 {
414 }
415 
416 void SAL_CALL IMPL_SfxBaseController_CloseListenerHelper::disposing( const EVENTOBJECT& /*aEvent*/ ) throw( ::com::sun::star::uno::RuntimeException )
417 {
418 }
419 
420 void SAL_CALL IMPL_SfxBaseController_CloseListenerHelper::queryClosing( const EVENTOBJECT& aEvent, sal_Bool bDeliverOwnership )
421     throw (RUNTIMEEXCEPTION, com::sun::star::util::CloseVetoException)
422 {
423 	::vos::OGuard aGuard( Application::GetSolarMutex() );
424     SfxViewShell* pShell = m_pController->GetViewShell_Impl();
425     if  ( m_pController !=  NULL &&  pShell )
426 	{
427         sal_Bool bCanClose = (sal_Bool) pShell->PrepareClose( sal_False );
428 		if ( !bCanClose )
429 		{
430             if ( bDeliverOwnership && ( !pShell->GetWindow() || !pShell->GetWindow()->IsReallyVisible() ) )
431             {
432                 // ignore OwnerShip in case of visible frame (will be closed by user)
433                 uno::Reference < frame::XModel > xModel( aEvent.Source, uno::UNO_QUERY );
434                 if ( xModel.is() )
435                     pShell->TakeOwnerShip_Impl();
436                 else
437                     pShell->TakeFrameOwnerShip_Impl();
438             }
439 
440 			throw com::sun::star::util::CloseVetoException(::rtl::OUString::createFromAscii("Controller disagree ..."),static_cast< ::cppu::OWeakObject*>(this));
441 		}
442 	}
443 }
444 
445 void SAL_CALL IMPL_SfxBaseController_CloseListenerHelper::notifyClosing( const EVENTOBJECT& /*aEvent*/ ) throw (RUNTIMEEXCEPTION)
446 {
447 }
448 
449 //________________________________________________________________________________________________________
450 //	declaration IMPL_SfxBaseController_DataContainer
451 //________________________________________________________________________________________________________
452 
453 struct IMPL_SfxBaseController_DataContainer
454 {
455     Reference< XFrame >                     m_xFrame                ;
456     Reference< XFrameActionListener >       m_xListener             ;
457     Reference< XCloseListener >             m_xCloseListener        ;
458     ::sfx2::UserInputInterception           m_aUserInputInterception;
459 	OMULTITYPEINTERFACECONTAINERHELPER		m_aListenerContainer	;
460     OINTERFACECONTAINERHELPER               m_aInterceptorContainer ;
461     Reference< XStatusIndicator >           m_xIndicator            ;
462 	SfxViewShell*							m_pViewShell			;
463 	SfxBaseController*						m_pController			;
464 	sal_Bool								m_bDisposing			;
465 	sal_Bool                                m_bSuspendState         ;
466     Reference< XTitle >                     m_xTitleHelper          ;
467     Sequence< PropertyValue >               m_aCreationArgs         ;
468 
469 	IMPL_SfxBaseController_DataContainer(	MUTEX&				aMutex		,
470 											SfxViewShell*		pViewShell	,
471 											SfxBaseController*	pController	)
472             :   m_xListener                     ( new IMPL_SfxBaseController_ListenerHelper( aMutex, pController ) )
473             ,   m_xCloseListener                ( new IMPL_SfxBaseController_CloseListenerHelper( aMutex, pController ) )
474             ,   m_aUserInputInterception        ( *pController, aMutex                                  )
475             ,   m_aListenerContainer            ( aMutex												)
476             ,   m_aInterceptorContainer         ( aMutex                                                )
477             ,   m_pViewShell			( pViewShell											)
478             ,   m_pController			( pController											)
479             ,   m_bDisposing			( sal_False												)
480             ,   m_bSuspendState                 ( sal_False                                              )
481 	{
482 	}
483 
484 } ;	// struct IMPL_SfxBaseController_DataContainer
485 
486 //________________________________________________________________________________________________________
487 //	IMPL_SfxBaseController_ListenerHelper constructor
488 //________________________________________________________________________________________________________
489 
490 IMPL_SfxBaseController_ListenerHelper::IMPL_SfxBaseController_ListenerHelper(	MUTEX&				aMutex		,
491 																				SfxBaseController*	pController	)
492 		: m_aMutex		( aMutex		)
493 		, m_pController	( pController	)
494 {
495 }
496 
497 //________________________________________________________________________________________________________
498 //	IMPL_SfxBaseController_ListenerHelper destructor
499 //________________________________________________________________________________________________________
500 
501 IMPL_SfxBaseController_ListenerHelper::~IMPL_SfxBaseController_ListenerHelper()
502 {
503 }
504 
505 void SAL_CALL IMPL_SfxBaseController_ListenerHelper::frameAction( const FRAMEACTIONEVENT& aEvent ) throw( RUNTIMEEXCEPTION )
506 {
507 	::vos::OGuard aGuard( Application::GetSolarMutex() );
508 	if	(
509 			( m_pController	!=	NULL ) &&
510 			( aEvent.Frame	==	m_pController->getFrame() )	&&
511             ( m_pController->GetViewShell_Impl() && m_pController->GetViewShell_Impl()->GetWindow() !=  NULL                                                    )
512 		)
513 	{
514         if ( aEvent.Action == ::com::sun::star::frame::FrameAction_FRAME_UI_ACTIVATED )
515 		{
516             if ( !m_pController->GetViewShell_Impl()->GetUIActiveIPClient_Impl() )
517                 m_pController->GetViewShell_Impl()->GetViewFrame()->MakeActive_Impl( sal_False );
518 		}
519         else if ( aEvent.Action == ::com::sun::star::frame::FrameAction_CONTEXT_CHANGED )
520 		{
521 			m_pController->GetViewShell_Impl()->GetViewFrame()->GetBindings().ContextChanged_Impl();
522 		}
523 	}
524 }
525 
526 //________________________________________________________________________________________________________
527 //	IMPL_SfxBaseController_ListenerHelper -> XEventListener
528 //________________________________________________________________________________________________________
529 
530 void SAL_CALL IMPL_SfxBaseController_ListenerHelper::disposing( const EVENTOBJECT& /*aEvent*/ ) throw( ::com::sun::star::uno::RuntimeException )
531 {
532 	::vos::OGuard aGuard( Application::GetSolarMutex() );
533     if ( m_pController && m_pController->getFrame().is() )
534 		m_pController->getFrame()->removeFrameActionListener( this ) ;
535 }
536 
537 //________________________________________________________________________________________________________
538 //	SfxBaseController -> constructor
539 //________________________________________________________________________________________________________
540 DBG_NAME(sfx2_SfxBaseController)
541 SfxBaseController::SfxBaseController( SfxViewShell* pViewShell )
542     :   m_pData ( new IMPL_SfxBaseController_DataContainer( m_aMutex, pViewShell, this ))
543 {
544     DBG_CTOR(sfx2_SfxBaseController,NULL);
545     m_pData->m_pViewShell->SetController( this );
546 }
547 
548 //________________________________________________________________________________________________________
549 //	SfxBaseController -> destructor
550 //________________________________________________________________________________________________________
551 
552 SfxBaseController::~SfxBaseController()
553 {
554     DBG_DTOR(sfx2_SfxBaseController,NULL);
555 	delete m_pData;
556 }
557 
558 //________________________________________________________________________________________________________
559 //	SfxBaseController -> XController2
560 //________________________________________________________________________________________________________
561 
562 Reference< XWindow > SAL_CALL SfxBaseController::getComponentWindow() throw (RuntimeException)
563 {
564 	::vos::OGuard aGuard( Application::GetSolarMutex() );
565     if ( !m_pData->m_pViewShell )
566         throw DisposedException();
567 
568     return Reference< XWindow >( GetViewFrame_Impl().GetFrame().GetWindow().GetComponentInterface(), UNO_QUERY_THROW );
569 }
570 
571 ::rtl::OUString SAL_CALL SfxBaseController::getViewControllerName() throw (RuntimeException)
572 {
573 	::vos::OGuard aGuard( Application::GetSolarMutex() );
574     if ( !m_pData->m_pViewShell || !m_pData->m_pViewShell->GetObjectShell() )
575         throw DisposedException();
576 
577     const SfxObjectFactory& rDocFac( m_pData->m_pViewShell->GetObjectShell()->GetFactory() );
578     sal_uInt16 nViewNo = rDocFac.GetViewNo_Impl( GetViewFrame_Impl().GetCurViewId(), rDocFac.GetViewFactoryCount() );
579     OSL_ENSURE( nViewNo < rDocFac.GetViewFactoryCount(), "SfxBaseController::getViewControllerName: view ID not found in view factories!" );
580 
581     ::rtl::OUString sViewName;
582     if ( nViewNo < rDocFac.GetViewFactoryCount() )
583         sViewName = rDocFac.GetViewFactory( nViewNo ).GetAPIViewName();
584 
585     return sViewName;
586 }
587 
588 Sequence< PropertyValue > SAL_CALL SfxBaseController::getCreationArguments() throw (RuntimeException)
589 {
590 	::vos::OGuard aGuard( Application::GetSolarMutex() );
591     if ( !m_pData->m_pViewShell || !m_pData->m_pViewShell->GetObjectShell() )
592         throw DisposedException();
593 
594     return m_pData->m_aCreationArgs;
595 }
596 
597 void SfxBaseController::SetCreationArguments_Impl( const Sequence< PropertyValue >& i_rCreationArgs )
598 {
599     OSL_ENSURE( m_pData->m_aCreationArgs.getLength() == 0, "SfxBaseController::SetCreationArguments_Impl: not intended to be called twice!" );
600     m_pData->m_aCreationArgs = i_rCreationArgs;
601 }
602 
603 SfxViewFrame& SfxBaseController::GetViewFrame_Impl() const
604 {
605     ENSURE_OR_THROW( m_pData->m_pViewShell, "not to be called without a view shell" );
606     SfxViewFrame* pActFrame = m_pData->m_pViewShell->GetFrame();
607     ENSURE_OR_THROW( pActFrame, "a view shell without a view frame is pretty pathological" );
608     return *pActFrame;
609 }
610 
611 //________________________________________________________________________________________________________
612 //	SfxBaseController -> XController2 -> XController
613 //________________________________________________________________________________________________________
614 
615 void SAL_CALL SfxBaseController::attachFrame( const REFERENCE< XFRAME >& xFrame ) throw( ::com::sun::star::uno::RuntimeException )
616 {
617     REFERENCE< XFRAME > xTemp( getFrame() ) ;
618 
619 	::vos::OGuard aGuard( Application::GetSolarMutex() );
620 	if ( xTemp.is() )
621 	{
622         xTemp->removeFrameActionListener( m_pData->m_xListener ) ;
623 		REFERENCE < ::com::sun::star::util::XCloseBroadcaster > xCloseable( xTemp, com::sun::star::uno::UNO_QUERY );
624 		if ( xCloseable.is() )
625 			xCloseable->removeCloseListener( m_pData->m_xCloseListener );
626 	}
627 
628     m_pData->m_xFrame = xFrame;
629 
630 	if ( xFrame.is() )
631 	{
632         xFrame->addFrameActionListener( m_pData->m_xListener ) ;
633 		REFERENCE < ::com::sun::star::util::XCloseBroadcaster > xCloseable( xFrame, com::sun::star::uno::UNO_QUERY );
634 		if ( xCloseable.is() )
635 			xCloseable->addCloseListener( m_pData->m_xCloseListener );
636 
637 		if ( m_pData->m_pViewShell )
638 		{
639             ConnectSfxFrame_Impl( E_CONNECT );
640 
641             // attaching the frame to the controller is the last step in the creation of a new view, so notify this
642             SfxViewEventHint aHint( SFX_EVENT_VIEWCREATED, GlobalEventConfig::GetEventName( STR_EVENT_VIEWCREATED ), m_pData->m_pViewShell->GetObjectShell(), uno::Reference< frame::XController2 >( this ) );
643             SFX_APP()->NotifyEvent( aHint );
644 		}
645 	}
646 }
647 
648 //________________________________________________________________________________________________________
649 //	SfxBaseController -> XController
650 //________________________________________________________________________________________________________
651 
652 sal_Bool SAL_CALL SfxBaseController::attachModel( const REFERENCE< XMODEL >& xModel ) throw( ::com::sun::star::uno::RuntimeException )
653 {
654 	if ( m_pData->m_pViewShell && xModel.is() && xModel != m_pData->m_pViewShell->GetObjectShell()->GetModel() )
655 	{
656 		// don't allow to reattach a model!
657 		DBG_ERROR("Can't reattach model!");
658 		return sal_False;
659 	}
660 
661 	REFERENCE < ::com::sun::star::util::XCloseBroadcaster > xCloseable( xModel, com::sun::star::uno::UNO_QUERY );
662 	if ( xCloseable.is() )
663 		xCloseable->addCloseListener( m_pData->m_xCloseListener );
664 	return sal_True;
665 }
666 
667 //________________________________________________________________________________________________________
668 //	SfxBaseController -> XController
669 //________________________________________________________________________________________________________
670 
671 sal_Bool SAL_CALL SfxBaseController::suspend( sal_Bool bSuspend ) throw( ::com::sun::star::uno::RuntimeException )
672 {
673 	::vos::OGuard aGuard( Application::GetSolarMutex() );
674 
675 	// ignore dublicate calls, which doesnt change anything real
676 	if (bSuspend == m_pData->m_bSuspendState)
677 	   return sal_True;
678 
679 	if ( bSuspend == sal_True )
680 	{
681         if ( !m_pData->m_pViewShell )
682         {
683             m_pData->m_bSuspendState = sal_True;
684             return sal_True;
685         }
686 
687 		if ( !m_pData->m_pViewShell->PrepareClose() )
688             return sal_False;
689 
690         if ( getFrame().is() )
691             getFrame()->removeFrameActionListener( m_pData->m_xListener ) ;
692         SfxViewFrame* pActFrame = m_pData->m_pViewShell->GetFrame() ;
693 
694         // weitere View auf dasselbe Doc?
695         SfxObjectShell*	pDocShell	=	m_pData->m_pViewShell->GetObjectShell()	;
696         sal_Bool		bOther		=	sal_False								;
697 
698         for ( const SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );	!bOther && pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ) )
699             bOther = (pFrame != pActFrame);
700 
701         sal_Bool bRet = bOther || pDocShell->PrepareClose();
702         if ( bRet )
703         {
704             ConnectSfxFrame_Impl( E_DISCONNECT );
705             m_pData->m_bSuspendState = sal_True;
706         }
707 
708         return bRet;
709 	}
710 	else
711 	{
712 		if ( getFrame().is() )
713         	getFrame()->addFrameActionListener( m_pData->m_xListener ) ;
714 
715 		if ( m_pData->m_pViewShell )
716 		{
717             ConnectSfxFrame_Impl( E_RECONNECT );
718 		}
719 
720         m_pData->m_bSuspendState = sal_False;
721 		return sal_True ;
722 	}
723 }
724 
725 //________________________________________________________________________________________________________
726 //	SfxBaseController -> XController
727 //________________________________________________________________________________________________________
728 
729 ANY SfxBaseController::getViewData() throw( ::com::sun::star::uno::RuntimeException )
730 {
731     ANY         aAny;
732 	String		sData1;
733 	::vos::OGuard aGuard( Application::GetSolarMutex() );
734     if ( m_pData->m_pViewShell )
735     {
736         m_pData->m_pViewShell->WriteUserData( sData1 ) ;
737         ::rtl::OUString    sData( sData1 );
738         aAny <<= sData ;
739     }
740 
741 	return aAny ;
742 }
743 
744 //________________________________________________________________________________________________________
745 //	SfxBaseController -> XController
746 //________________________________________________________________________________________________________
747 
748 void SAL_CALL SfxBaseController::restoreViewData( const ANY& aValue ) throw( ::com::sun::star::uno::RuntimeException )
749 {
750 	::vos::OGuard aGuard( Application::GetSolarMutex() );
751     if ( m_pData->m_pViewShell )
752     {
753         ::rtl::OUString sData;
754         aValue >>= sData ;
755         m_pData->m_pViewShell->ReadUserData( sData ) ;
756     }
757 }
758 
759 //________________________________________________________________________________________________________
760 //	SfxBaseController -> XController
761 //________________________________________________________________________________________________________
762 
763 REFERENCE< XFRAME > SAL_CALL SfxBaseController::getFrame() throw( ::com::sun::star::uno::RuntimeException )
764 {
765 	::vos::OGuard aGuard( Application::GetSolarMutex() );
766     return m_pData->m_xFrame;
767 }
768 
769 //________________________________________________________________________________________________________
770 //	SfxBaseController -> XController
771 //________________________________________________________________________________________________________
772 
773 REFERENCE< XMODEL > SAL_CALL SfxBaseController::getModel() throw( ::com::sun::star::uno::RuntimeException )
774 {
775 	::vos::OGuard aGuard( Application::GetSolarMutex() );
776     return m_pData->m_pViewShell ? m_pData->m_pViewShell->GetObjectShell()->GetModel() : REFERENCE < XMODEL > () ;
777 }
778 
779 //________________________________________________________________________________________________________
780 //	SfxBaseController -> XDispatchProvider
781 //________________________________________________________________________________________________________
782 
783 REFERENCE< XDISPATCH > SAL_CALL SfxBaseController::queryDispatch(	const	UNOURL&				aURL			,
784 																	const	::rtl::OUString&			sTargetFrameName,
785 																			sal_Int32			eSearchFlags	) throw( RUNTIMEEXCEPTION )
786 {
787 	::vos::OGuard aGuard( Application::GetSolarMutex() );
788     REFERENCE< XDISPATCH >  xDisp;
789     if ( m_pData->m_pViewShell )
790     {
791         SfxViewFrame*           pAct    = m_pData->m_pViewShell->GetViewFrame() ;
792         if ( !m_pData->m_bDisposing )
793         {
794             if ( sTargetFrameName.compareToAscii( "_beamer" ) == COMPARE_EQUAL )
795             {
796                 SfxViewFrame *pFrame = m_pData->m_pViewShell->GetViewFrame();
797                 if ( eSearchFlags & ( ::com::sun::star::frame::FrameSearchFlag::CREATE ))
798                     pFrame->SetChildWindow( SID_BROWSER, sal_True );
799                 SfxChildWindow* pChildWin = pFrame->GetChildWindow( SID_BROWSER );
800                 REFERENCE < XFRAME > xFrame;
801                 if ( pChildWin )
802                     xFrame = ( pChildWin->GetFrame() );
803                 if ( xFrame.is() )
804                     xFrame->setName( sTargetFrameName );
805 
806                 Reference< XDispatchProvider > xProv( xFrame, ::com::sun::star::uno::UNO_QUERY );
807                 if ( xProv.is() )
808                     return xProv->queryDispatch( aURL, sTargetFrameName, ::com::sun::star::frame::FrameSearchFlag::SELF );
809             }
810 
811             if ( aURL.Protocol.compareToAscii( ".uno:" ) == COMPARE_EQUAL )
812             {
813                 rtl::OUString aMasterCommand = SfxOfficeDispatch::GetMasterUnoCommand( aURL );
814                 sal_Bool      bMasterCommand( aMasterCommand.getLength() > 0 );
815 
816                 pAct = m_pData->m_pViewShell->GetViewFrame() ;
817                 SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( pAct );
818 
819                 const SfxSlot* pSlot( 0 );
820                 if ( bMasterCommand )
821                     pSlot = rSlotPool.GetUnoSlot( aMasterCommand );
822                 else
823                     pSlot = rSlotPool.GetUnoSlot( aURL.Path );
824                 if ( pSlot && ( !pAct->GetFrame().IsInPlace() || !pSlot->IsMode( SFX_SLOT_CONTAINER ) ) )
825                     return pAct->GetBindings().GetDispatch( pSlot, aURL, bMasterCommand );
826 				else
827 				{
828 					// try to find parent SfxViewFrame
829 					uno::Reference< frame::XFrame > xParentFrame;
830 					uno::Reference< frame::XFrame > xOwnFrame = pAct->GetFrame().GetFrameInterface();
831 					if ( xOwnFrame.is() )
832 						xParentFrame = uno::Reference< frame::XFrame >( xOwnFrame->getCreator(), uno::UNO_QUERY );
833 
834 					if ( xParentFrame.is() )
835 					{
836 						// TODO/LATER: in future probably SfxViewFrame hirarchy should be the same as XFrame hirarchy
837 						// SfxViewFrame* pParentFrame = pAct->GetParentViewFrame();
838 
839 						// search the related SfxViewFrame
840 						SfxViewFrame* pParentFrame = NULL;
841 						for ( SfxViewFrame* pFrame = SfxViewFrame::GetFirst();
842 								pFrame;
843 								pFrame = SfxViewFrame::GetNext( *pFrame ) )
844 						{
845 							if ( pFrame->GetFrame().GetFrameInterface() == xParentFrame )
846 							{
847 								pParentFrame = pFrame;
848 								break;
849 							}
850 						}
851 
852 						if ( pParentFrame )
853 						{
854                             SfxSlotPool& rFrameSlotPool = SfxSlotPool::GetSlotPool( pParentFrame );
855                             const SfxSlot* pSlot2( 0 );
856                             if ( bMasterCommand )
857                                 pSlot2 = rFrameSlotPool.GetUnoSlot( aMasterCommand );
858                             else
859                                 pSlot2 = rFrameSlotPool.GetUnoSlot( aURL.Path );
860 
861                             if ( pSlot2 )
862                                 return pParentFrame->GetBindings().GetDispatch( pSlot2, aURL, bMasterCommand );
863 						}
864 					}
865 				}
866             }
867             else if ( aURL.Protocol.compareToAscii( "slot:" ) == COMPARE_EQUAL )
868             {
869                 sal_uInt16 nId = (sal_uInt16) aURL.Path.toInt32();
870 
871                 pAct = m_pData->m_pViewShell->GetViewFrame() ;
872                 if (nId >= SID_VERB_START && nId <= SID_VERB_END)
873                 {
874                     const SfxSlot* pSlot = m_pData->m_pViewShell->GetVerbSlot_Impl(nId);
875                     if ( pSlot )
876                         return pAct->GetBindings().GetDispatch( pSlot, aURL, sal_False );
877                 }
878 
879                 SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( pAct );
880                 const SfxSlot* pSlot = rSlotPool.GetSlot( nId );
881                 if ( pSlot && ( !pAct->GetFrame().IsInPlace() || !pSlot->IsMode( SFX_SLOT_CONTAINER ) ) )
882                     return pAct->GetBindings().GetDispatch( pSlot, aURL, sal_False );
883 				else
884 				{
885 					// try to find parent SfxViewFrame
886 					uno::Reference< frame::XFrame > xParentFrame;
887 					uno::Reference< frame::XFrame > xOwnFrame = pAct->GetFrame().GetFrameInterface();
888 					if ( xOwnFrame.is() )
889 						xParentFrame = uno::Reference< frame::XFrame >( xOwnFrame->getCreator(), uno::UNO_QUERY );
890 
891 					if ( xParentFrame.is() )
892 					{
893 						// TODO/LATER: in future probably SfxViewFrame hirarchy should be the same as XFrame hirarchy
894 						// SfxViewFrame* pParentFrame = pAct->GetParentViewFrame();
895 
896 						// search the related SfxViewFrame
897 						SfxViewFrame* pParentFrame = NULL;
898 						for ( SfxViewFrame* pFrame = SfxViewFrame::GetFirst();
899 								pFrame;
900 								pFrame = SfxViewFrame::GetNext( *pFrame ) )
901 						{
902 							if ( pFrame->GetFrame().GetFrameInterface() == xParentFrame )
903 							{
904 								pParentFrame = pFrame;
905 								break;
906 							}
907 						}
908 
909 						if ( pParentFrame )
910 						{
911                             SfxSlotPool& rSlotPool2 = SfxSlotPool::GetSlotPool( pParentFrame );
912                 			const SfxSlot* pSlot2 = rSlotPool2.GetUnoSlot( aURL.Path );
913                 			if ( pSlot2 )
914                                 return pParentFrame->GetBindings().GetDispatch( pSlot2, aURL, sal_False );
915 						}
916 					}
917 				}
918             }
919             else if( sTargetFrameName.compareToAscii( "_self" )==COMPARE_EQUAL || sTargetFrameName.getLength()==0 )
920             {
921                 // check for already loaded URL ... but with additional jumpmark!
922                 REFERENCE< XMODEL > xModel = getModel();
923                 if( xModel.is() && aURL.Mark.getLength() )
924                 {
925                     SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( pAct );
926                     const SfxSlot* pSlot = rSlotPool.GetSlot( SID_JUMPTOMARK );
927                     if( aURL.Main.getLength() && aURL.Main == xModel->getURL() && pSlot )
928                         return REFERENCE< XDISPATCH >( new SfxOfficeDispatch( pAct->GetBindings(), pAct->GetDispatcher(), pSlot, aURL) );
929                 }
930             }
931         }
932     }
933 
934 	return xDisp;
935 }
936 
937 //________________________________________________________________________________________________________
938 //	SfxBaseController -> XDispatchProvider
939 //________________________________________________________________________________________________________
940 
941 uno::Sequence< REFERENCE< XDISPATCH > > SAL_CALL SfxBaseController::queryDispatches( const uno::Sequence< DISPATCHDESCRIPTOR >& seqDescripts ) throw( ::com::sun::star::uno::RuntimeException )
942 {
943     // Create return list - which must have same size then the given descriptor
944     // It's not allowed to pack it!
945     sal_Int32 nCount = seqDescripts.getLength();
946     uno::Sequence< REFERENCE< XDISPATCH > > lDispatcher( nCount );
947 
948     for( sal_Int32 i=0; i<nCount; ++i )
949     {
950         lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL  ,
951                                         seqDescripts[i].FrameName   ,
952                                         seqDescripts[i].SearchFlags );
953     }
954 
955     return lDispatcher;
956 }
957 
958 //________________________________________________________________________________________________________
959 //	SfxBaseController -> XControllerBorder
960 //________________________________________________________________________________________________________
961 
962 frame::BorderWidths SAL_CALL SfxBaseController::getBorder()
963 	throw ( uno::RuntimeException )
964 {
965 	frame::BorderWidths aResult;
966 
967 	::vos::OGuard aGuard( Application::GetSolarMutex() );
968     if ( m_pData->m_pViewShell )
969 	{
970 		SvBorder aBorder = m_pData->m_pViewShell->GetBorderPixel();
971 		aResult.Left = aBorder.Left();
972 		aResult.Top = aBorder.Top();
973 		aResult.Right = aBorder.Right();
974 		aResult.Bottom = aBorder.Bottom();
975 	}
976 
977 	return aResult;
978 }
979 
980 void SAL_CALL SfxBaseController::addBorderResizeListener( const uno::Reference< frame::XBorderResizeListener >& xListener )
981 	throw ( uno::RuntimeException )
982 {
983 	m_pData->m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< frame::XBorderResizeListener >*)0),
984 												xListener );
985 }
986 
987 void SAL_CALL SfxBaseController::removeBorderResizeListener( const uno::Reference< frame::XBorderResizeListener >& xListener )
988 	throw ( uno::RuntimeException )
989 {
990 	m_pData->m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< frame::XBorderResizeListener >*)0),
991 												xListener );
992 }
993 
994 awt::Rectangle SAL_CALL SfxBaseController::queryBorderedArea( const awt::Rectangle& aPreliminaryRectangle )
995 	throw ( uno::RuntimeException )
996 {
997 	::vos::OGuard aGuard( Application::GetSolarMutex() );
998     if ( m_pData->m_pViewShell )
999 	{
1000 		Rectangle aTmpRect = VCLRectangle( aPreliminaryRectangle );
1001 		m_pData->m_pViewShell->QueryObjAreaPixel( aTmpRect );
1002 		return AWTRectangle( aTmpRect );
1003 	}
1004 
1005 	return aPreliminaryRectangle;
1006 }
1007 
1008 void SfxBaseController::BorderWidthsChanged_Impl()
1009 {
1010    	::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aListenerContainer.getContainer(
1011 						::getCppuType( ( const uno::Reference< frame::XBorderResizeListener >*) NULL ) );
1012     if ( pContainer )
1013 	{
1014 		frame::BorderWidths aBWidths = getBorder();
1015 		uno::Reference< uno::XInterface > xThis( static_cast< ::cppu::OWeakObject* >(this), uno::UNO_QUERY );
1016 
1017 	    ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
1018 	    while (pIterator.hasMoreElements())
1019 	    {
1020 	        try
1021 	        {
1022 	            ((frame::XBorderResizeListener*)pIterator.next())->borderWidthsChanged( xThis, aBWidths );
1023 	        }
1024 	        catch( uno::RuntimeException& )
1025 	        {
1026 	            pIterator.remove();
1027 	        }
1028 	    }
1029 	}
1030 }
1031 
1032 //________________________________________________________________________________________________________
1033 //	SfxBaseController -> XComponent
1034 //________________________________________________________________________________________________________
1035 
1036 void SAL_CALL SfxBaseController::dispose() throw( ::com::sun::star::uno::RuntimeException )
1037 {
1038 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1039     Reference< XController > xTmp( this );
1040 	m_pData->m_bDisposing = sal_True ;
1041 
1042 	EVENTOBJECT aEventObject;
1043     aEventObject.Source = *this ;
1044 	m_pData->m_aListenerContainer.disposeAndClear( aEventObject ) ;
1045 
1046     if ( m_pData->m_pController && m_pData->m_pController->getFrame().is() )
1047         m_pData->m_pController->getFrame()->removeFrameActionListener( m_pData->m_xListener ) ;
1048 
1049     if ( m_pData->m_pViewShell )
1050     {
1051         SfxViewFrame* pFrame = m_pData->m_pViewShell->GetViewFrame() ;
1052         if ( pFrame && pFrame->GetViewShell() == m_pData->m_pViewShell )
1053             pFrame->GetFrame().SetIsClosing_Impl();
1054         m_pData->m_pViewShell->DiscardClients_Impl();
1055         m_pData->m_pViewShell->pImp->m_bControllerSet = false;
1056 
1057         if ( pFrame )
1058         {
1059             EVENTOBJECT aObject;
1060             aObject.Source = *this ;
1061 
1062             SfxObjectShell* pDoc = pFrame->GetObjectShell() ;
1063             SfxViewFrame *pView = SfxViewFrame::GetFirst(pDoc);
1064             while( pView )
1065             {
1066                 // if there is another ViewFrame or currently the ViewShell in my ViewFrame is switched (PagePreview)
1067                 if ( pView != pFrame || pView->GetViewShell() != m_pData->m_pViewShell )
1068                     break;
1069                 pView = SfxViewFrame::GetNext( *pView, pDoc );
1070             }
1071 
1072             SFX_APP()->NotifyEvent( SfxViewEventHint(SFX_EVENT_CLOSEVIEW, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEVIEW ), pDoc, uno::Reference< frame::XController2 >( this ) ) );
1073             if ( !pView )
1074                 SFX_APP()->NotifyEvent( SfxEventHint(SFX_EVENT_CLOSEDOC, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ), pDoc) );
1075 
1076             REFERENCE< XMODEL > xModel = pDoc->GetModel();
1077 			REFERENCE < ::com::sun::star::util::XCloseable > xCloseable( xModel, com::sun::star::uno::UNO_QUERY );
1078             if ( xModel.is() )
1079 			{
1080                 xModel->disconnectController( this );
1081 				if ( xCloseable.is() )
1082 					xCloseable->removeCloseListener( m_pData->m_xCloseListener );
1083 			}
1084 
1085             REFERENCE < XFRAME > aXFrame;
1086 			attachFrame( aXFrame );
1087 
1088             m_pData->m_xListener->disposing( aObject );
1089             SfxViewShell *pShell = m_pData->m_pViewShell;
1090             m_pData->m_pViewShell = NULL;
1091             if ( pFrame->GetViewShell() == pShell )
1092             {
1093                 // Enter registrations only allowed if we are the owner!
1094                 if ( pFrame->GetFrame().OwnsBindings_Impl() )
1095                     pFrame->GetBindings().ENTERREGISTRATIONS();
1096                 pFrame->GetFrame().SetFrameInterface_Impl(  aXFrame );
1097                 pFrame->GetFrame().DoClose_Impl();
1098             }
1099         }
1100     }
1101 }
1102 
1103 //________________________________________________________________________________________________________
1104 //	SfxBaseController -> XComponent
1105 //________________________________________________________________________________________________________
1106 
1107 void SAL_CALL SfxBaseController::addEventListener( const REFERENCE< XEVENTLISTENER >& aListener ) throw( ::com::sun::star::uno::RuntimeException )
1108 {
1109 	m_pData->m_aListenerContainer.addInterface( ::getCppuType((const REFERENCE< XEVENTLISTENER >*)0), aListener );
1110 }
1111 
1112 //________________________________________________________________________________________________________
1113 //	SfxBaseController -> XComponent
1114 //________________________________________________________________________________________________________
1115 
1116 void SAL_CALL SfxBaseController::removeEventListener( const REFERENCE< XEVENTLISTENER >& aListener ) throw( ::com::sun::star::uno::RuntimeException )
1117 {
1118 	m_pData->m_aListenerContainer.removeInterface( ::getCppuType((const REFERENCE< XEVENTLISTENER >*)0), aListener );
1119 }
1120 
1121 void SfxBaseController::ReleaseShell_Impl()
1122 {
1123 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1124     if ( m_pData->m_pViewShell )
1125     {
1126         SfxObjectShell* pDoc = m_pData->m_pViewShell->GetObjectShell() ;
1127         REFERENCE< XMODEL > xModel = pDoc->GetModel();
1128         REFERENCE < ::com::sun::star::util::XCloseable > xCloseable( xModel, com::sun::star::uno::UNO_QUERY );
1129         if ( xModel.is() )
1130         {
1131             xModel->disconnectController( this );
1132             if ( xCloseable.is() )
1133                 xCloseable->removeCloseListener( m_pData->m_xCloseListener );
1134         }
1135         m_pData->m_pViewShell = 0;
1136 
1137         REFERENCE < XFRAME > aXFrame;
1138 		attachFrame( aXFrame );
1139     }
1140 }
1141 
1142 SfxViewShell* SfxBaseController::GetViewShell_Impl() const
1143 {
1144     return m_pData->m_pViewShell;
1145 }
1146 
1147 ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > SAL_CALL SfxBaseController::getStatusIndicator(  ) throw (::com::sun::star::uno::RuntimeException)
1148 {
1149 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1150     if ( m_pData->m_pViewShell && !m_pData->m_xIndicator.is() )
1151         m_pData->m_xIndicator = new SfxStatusIndicator( this, m_pData->m_pViewShell->GetViewFrame()->GetFrame().GetWorkWindow_Impl() );
1152     return m_pData->m_xIndicator;
1153 }
1154 
1155 void SAL_CALL SfxBaseController::registerContextMenuInterceptor( const REFERENCE< XCONTEXTMENUINTERCEPTOR >& xInterceptor ) throw( RUNTIMEEXCEPTION )
1156 
1157 {
1158     m_pData->m_aInterceptorContainer.addInterface( xInterceptor );
1159 
1160 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1161     if ( m_pData->m_pViewShell )
1162         m_pData->m_pViewShell->AddContextMenuInterceptor_Impl( xInterceptor );
1163 }
1164 
1165 void SAL_CALL SfxBaseController::releaseContextMenuInterceptor( const REFERENCE< XCONTEXTMENUINTERCEPTOR >& xInterceptor ) throw( RUNTIMEEXCEPTION )
1166 
1167 {
1168     m_pData->m_aInterceptorContainer.removeInterface( xInterceptor );
1169 
1170 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1171     if ( m_pData->m_pViewShell )
1172         m_pData->m_pViewShell->RemoveContextMenuInterceptor_Impl( xInterceptor );
1173 }
1174 
1175 void SAL_CALL SfxBaseController::addKeyHandler( const ::com::sun::star::uno::Reference< XKEYHANDLER >& xHandler ) throw (::com::sun::star::uno::RuntimeException)
1176 {
1177 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1178     m_pData->m_aUserInputInterception.addKeyHandler( xHandler );
1179 }
1180 
1181 void SAL_CALL SfxBaseController::removeKeyHandler( const ::com::sun::star::uno::Reference< XKEYHANDLER >& xHandler ) throw (::com::sun::star::uno::RuntimeException)
1182 {
1183 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1184     m_pData->m_aUserInputInterception.removeKeyHandler( xHandler );
1185 }
1186 
1187 void SAL_CALL SfxBaseController::addMouseClickHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseClickHandler >& xHandler ) throw (::com::sun::star::uno::RuntimeException)
1188 {
1189 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1190     m_pData->m_aUserInputInterception.addMouseClickHandler( xHandler );
1191 }
1192 
1193 void SAL_CALL SfxBaseController::removeMouseClickHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseClickHandler >& xHandler ) throw (::com::sun::star::uno::RuntimeException)
1194 {
1195 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1196     m_pData->m_aUserInputInterception.removeMouseClickHandler( xHandler );
1197 }
1198 
1199 ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL SfxBaseController::getSupportedCommandGroups()
1200 throw (::com::sun::star::uno::RuntimeException)
1201 {
1202     ::vos::OGuard aGuard( Application::GetSolarMutex() );
1203 
1204     std::list< sal_Int16 > aGroupList;
1205     SfxViewFrame* pViewFrame( m_pData->m_pViewShell->GetFrame() );
1206     SfxSlotPool*  pPool = &SfxSlotPool::GetSlotPool( pViewFrame );
1207 
1208     SfxSlotPool* pSlotPool = pPool ? pPool : &SFX_SLOTPOOL();
1209     const sal_uIntPtr nMode( SFX_SLOT_TOOLBOXCONFIG|SFX_SLOT_ACCELCONFIG|SFX_SLOT_MENUCONFIG );
1210 
1211     // Gruppe anw"ahlen ( Gruppe 0 ist intern )
1212     for ( sal_uInt16 i=0; i<pSlotPool->GetGroupCount(); i++ )
1213 	{
1214 		String aName = pSlotPool->SeekGroup( i );
1215         const SfxSlot* pSfxSlot = pSlotPool->FirstSlot();
1216         while ( pSfxSlot )
1217 		{
1218             if ( pSfxSlot->GetMode() & nMode )
1219 			{
1220                 sal_Int16 nCommandGroup = MapGroupIDToCommandGroup( pSfxSlot->GetGroupId() );
1221                 aGroupList.push_back( nCommandGroup );
1222                 break;
1223 			}
1224 			pSfxSlot = pSlotPool->NextSlot();
1225 		}
1226     }
1227 
1228     ::com::sun::star::uno::Sequence< sal_Int16 > aSeq =
1229         comphelper::containerToSequence< sal_Int16 >( aGroupList );
1230     return aSeq;
1231 }
1232 
1233 ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchInformation > SAL_CALL SfxBaseController::getConfigurableDispatchInformation( sal_Int16 nCmdGroup )
1234 throw (::com::sun::star::uno::RuntimeException)
1235 {
1236     std::list< ::com::sun::star::frame::DispatchInformation > aCmdList;
1237 
1238     ::vos::OGuard aGuard( Application::GetSolarMutex() );
1239     if ( m_pData->m_pViewShell )
1240     {
1241         const sal_uIntPtr nMode( SFX_SLOT_TOOLBOXCONFIG|SFX_SLOT_ACCELCONFIG|SFX_SLOT_MENUCONFIG );
1242 
1243         SfxViewFrame* pViewFrame( m_pData->m_pViewShell->GetFrame() );
1244         SfxSlotPool*  pPool( &SfxSlotPool::GetSlotPool( pViewFrame ));
1245         rtl::OUString aCmdPrefix( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
1246 
1247         SfxSlotPool* pSlotPool = pPool ? pPool : &SFX_SLOTPOOL();
1248         for ( sal_uInt16 i=0; i<pSlotPool->GetGroupCount(); i++ )
1249 		{
1250 			String aName = pSlotPool->SeekGroup( i );
1251 			const SfxSlot* pSfxSlot = pSlotPool->FirstSlot();
1252 			if ( pSfxSlot )
1253 			{
1254                 sal_Int16 nCommandGroup = MapGroupIDToCommandGroup( pSfxSlot->GetGroupId() );
1255                 if ( nCommandGroup == nCmdGroup )
1256                 {
1257                     while ( pSfxSlot )
1258 				    {
1259                         if ( pSfxSlot->GetMode() & nMode )
1260 					    {
1261                             ::com::sun::star::frame::DispatchInformation aCmdInfo;
1262                             ::rtl::OUStringBuffer aBuf( aCmdPrefix );
1263                             aBuf.appendAscii( pSfxSlot->GetUnoName() );
1264                             aCmdInfo.Command = aBuf.makeStringAndClear();
1265                             aCmdInfo.GroupId = nCommandGroup;
1266                             aCmdList.push_back( aCmdInfo );
1267 					    }
1268 					    pSfxSlot = pSlotPool->NextSlot();
1269 				    }
1270                 }
1271 		    }
1272         }
1273     }
1274 
1275     ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchInformation > aSeq =
1276         comphelper::containerToSequence< ::com::sun::star::frame::DispatchInformation, std::list< ::com::sun::star::frame::DispatchInformation > >( aCmdList );
1277 
1278     return aSeq;
1279 }
1280 
1281 sal_Bool SfxBaseController::HandleEvent_Impl( NotifyEvent& rEvent )
1282 {
1283     return m_pData->m_aUserInputInterception.handleNotifyEvent( rEvent );
1284 }
1285 
1286 sal_Bool SfxBaseController::HasKeyListeners_Impl()
1287 {
1288     return m_pData->m_aUserInputInterception.hasKeyHandlers();
1289 }
1290 
1291 sal_Bool SfxBaseController::HasMouseClickListeners_Impl()
1292 {
1293     return m_pData->m_aUserInputInterception.hasMouseClickListeners();
1294 }
1295 
1296 void SfxBaseController::ConnectSfxFrame_Impl( const ConnectSfxFrame i_eConnect )
1297 {
1298     ENSURE_OR_THROW( m_pData->m_pViewShell, "not to be called without a view shell" );
1299     SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame();
1300     ENSURE_OR_THROW( pViewFrame, "a view shell without a view frame is pretty pathological" );
1301 
1302     const bool bConnect = ( i_eConnect != E_DISCONNECT );
1303 
1304     // disable window and dispatcher
1305     pViewFrame->Enable( bConnect );
1306     pViewFrame->GetDispatcher()->Lock( !bConnect );
1307 
1308     if ( bConnect )
1309     {
1310         if ( i_eConnect == E_CONNECT )
1311         {
1312             if  (   ( m_pData->m_pViewShell->GetObjectShell() != NULL )
1313                 &&  ( m_pData->m_pViewShell->GetObjectShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
1314                 )
1315             {
1316                 SfxViewFrame* pViewFrm = m_pData->m_pViewShell->GetViewFrame();
1317                 if ( !pViewFrm->GetFrame().IsInPlace() )
1318                 {
1319                     // for outplace embedded objects, we want the layout manager to keep the content window
1320                     // size constant, if possible
1321                     try
1322                     {
1323                         uno::Reference< beans::XPropertySet > xFrameProps( m_pData->m_xFrame, uno::UNO_QUERY_THROW );
1324                         uno::Reference< beans::XPropertySet > xLayouterProps(
1325                             xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ), uno::UNO_QUERY_THROW );
1326                         xLayouterProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PreserveContentSize" ) ), uno::makeAny( sal_True ) );
1327                     }
1328                     catch( const uno::Exception& )
1329                     {
1330                 	    DBG_UNHANDLED_EXCEPTION();
1331                     }
1332                 }
1333             }
1334         }
1335 
1336         // upon DISCONNECT, we did *not* pop the shells from the stack (this is done elsewhere), so upon
1337         // RECONNECT, we're not allowed to push them
1338         if ( i_eConnect != E_RECONNECT )
1339         {
1340             pViewFrame->GetDispatcher()->Push( *m_pData->m_pViewShell );
1341             if ( m_pData->m_pViewShell->GetSubShell() )
1342                 pViewFrame->GetDispatcher()->Push( *m_pData->m_pViewShell->GetSubShell() );
1343 	        m_pData->m_pViewShell->PushSubShells_Impl();
1344             pViewFrame->GetDispatcher()->Flush();
1345         }
1346 
1347         Window* pEditWin = m_pData->m_pViewShell->GetWindow();
1348         if ( pEditWin && m_pData->m_pViewShell->IsShowView_Impl() )
1349             pEditWin->Show();
1350 
1351         if ( SfxViewFrame::Current() == pViewFrame )
1352             pViewFrame->GetDispatcher()->Update_Impl( sal_True );
1353 
1354         Window* pFrameWin = &pViewFrame->GetWindow();
1355         if ( pFrameWin != &pViewFrame->GetFrame().GetWindow() )
1356 	        pFrameWin->Show();
1357 
1358         if ( i_eConnect == E_CONNECT )
1359         {
1360             ::comphelper::NamedValueCollection aDocumentArgs( getModel()->getArgs() );
1361 
1362             const sal_Int16 nPluginMode = aDocumentArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) );
1363             const bool bHasPluginMode = ( nPluginMode != 0 );
1364 
1365             SfxFrame& rFrame = pViewFrame->GetFrame();
1366             SfxObjectShell& rDoc = *m_pData->m_pViewShell->GetObjectShell();
1367             if ( !rFrame.IsMarkedHidden_Impl() )
1368 	        {
1369                 if ( rDoc.IsHelpDocument() || ( nPluginMode == 2 ) )
1370                     pViewFrame->GetDispatcher()->HideUI( sal_True );
1371                 else
1372                     pViewFrame->GetDispatcher()->HideUI( sal_False );
1373 
1374                 if ( rFrame.IsInPlace() )
1375                     pViewFrame->LockAdjustPosSizePixel();
1376 
1377                 if ( nPluginMode == 3 )
1378                     rFrame.GetWorkWindow_Impl()->SetInternalDockingAllowed( sal_False );
1379 
1380                 if ( !rFrame.IsInPlace() )
1381 			        pViewFrame->GetDispatcher()->Update_Impl();
1382 		        pViewFrame->Show();
1383                 rFrame.GetWindow().Show();
1384                 if ( !rFrame.IsInPlace() || ( nPluginMode == 3 ) )
1385                     pViewFrame->MakeActive_Impl( rFrame.GetFrameInterface()->isActive() );
1386 
1387                 if ( rFrame.IsInPlace() )
1388                 {
1389                     pViewFrame->UnlockAdjustPosSizePixel();
1390                     // force resize for OLE server to fix layout problems of writer and math
1391                     // see i53651
1392                     if ( nPluginMode == 3 )
1393                         pViewFrame->Resize( sal_True );
1394                 }
1395 	        }
1396             else
1397             {
1398                 DBG_ASSERT( !rFrame.IsInPlace() && !bHasPluginMode, "Special modes not compatible with hidden mode!" );
1399                 rFrame.GetWindow().Show();
1400             }
1401 
1402 	        // Jetzt UpdateTitle, hidden TopFrames haben sonst keinen Namen!
1403 	        pViewFrame->UpdateTitle();
1404 
1405             if ( !rFrame.IsInPlace() )
1406                 pViewFrame->Resize( sal_True );
1407 
1408             // if there's a JumpMark given, then, well, jump to it
1409             ::comphelper::NamedValueCollection aViewArgs( getCreationArguments() );
1410             const ::rtl::OUString sJumpMark = aViewArgs.getOrDefault( "JumpMark", ::rtl::OUString() );
1411             const bool bHasJumpMark = ( sJumpMark.getLength() > 0 );
1412             OSL_ENSURE( ( !m_pData->m_pViewShell->GetObjectShell()->IsLoading() )
1413                     ||  ( !sJumpMark.getLength() ),
1414                 "SfxBaseController::ConnectSfxFrame_Impl: so this code wasn't dead?" );
1415                 // Before CWS autorecovery, there was code which postponed jumping to the Mark to a later time
1416                 // (SfxObjectShell::PositionView_Impl), but it seems this branch was never used, since this method
1417                 // here is never called before the load process finished. At least not with a non-empty jump mark
1418             if ( sJumpMark.getLength() )
1419 		        m_pData->m_pViewShell->JumpToMark( sJumpMark );
1420 
1421             // if no plugin mode and no jump mark was supplied, check whether the document itself can provide view data, and
1422             // if so, forward it to the view/shell.
1423             if ( !bHasPluginMode && !bHasJumpMark )
1424             {
1425                 // Note that this might not be the ideal place here. Restoring view data should, IMO, be the
1426                 // responsibility of the loader, not an implementation detail burried here deep within the controller's
1427                 // implementation.
1428                 // What I think should be done to replace the below code:
1429                 // - change SfxBaseController::restoreViewData to also accept a PropertyValue[] (it currently accepts
1430                 //   a string only), and forward it to its ViewShell's ReadUserDataSequence
1431                 // - change the frame loader so that when a new document is loaded (as opposed to an existing
1432                 //   document being loaded into a new frame), the model's view data is examine the very same
1433                 //   way as below, and the proper view data is set via XController::restoreViewData
1434                 // - extend SfxViewFrame::SwitchToViewShell_Impl. Currently, it cares for the case where a non-PrintPreview
1435                 //   view is exchanged, and sets the old view's data at the model. It should also care for the other
1436                 //   way, were the PrintPreview view is left: in this case, the new view should also be initialized
1437                 //   with the model's view data
1438                 try
1439                 {
1440                     Reference< XViewDataSupplier > xViewDataSupplier( getModel(), UNO_QUERY_THROW );
1441                     Reference< XIndexAccess > xViewData( xViewDataSupplier->getViewData() );
1442 
1443                     // find the view data item whose ViewId matches the ID of the view we're just connecting to
1444                     const SfxObjectFactory& rDocFactory( rDoc.GetFactory() );
1445                     const sal_Int32 nCount = xViewData.is() ? xViewData->getCount() : 0;
1446                     sal_Int32 nViewDataIndex = 0;
1447                     for ( sal_Int32 i=0; i<nCount; ++i )
1448                     {
1449                         const ::comphelper::NamedValueCollection aViewData( xViewData->getByIndex(i) );
1450                         ::rtl::OUString sViewId( aViewData.getOrDefault( "ViewId", ::rtl::OUString() ) );
1451                         if ( sViewId.getLength() == 0 )
1452                             continue;
1453 
1454                         const SfxViewFactory* pViewFactory = rDocFactory.GetViewFactoryByViewName( sViewId );
1455                         if ( pViewFactory == NULL )
1456                             continue;
1457 
1458                         if ( pViewFactory->GetOrdinal() == pViewFrame->GetCurViewId() )
1459                         {
1460                             nViewDataIndex = i;
1461                             break;
1462                         }
1463                     }
1464                     if ( nViewDataIndex < nCount )
1465                     {
1466                         Sequence< PropertyValue > aViewData;
1467                         OSL_VERIFY( xViewData->getByIndex( nViewDataIndex ) >>= aViewData );
1468                         if ( aViewData.getLength() > 0 )
1469                             m_pData->m_pViewShell->ReadUserDataSequence( aViewData, sal_True );
1470                     }
1471                 }
1472                 catch( const Exception& )
1473                 {
1474         	        DBG_UNHANDLED_EXCEPTION();
1475                 }
1476             }
1477         }
1478     }
1479 
1480     // invalidate slot corresponding to the view shell
1481     const sal_uInt16 nViewNo = m_pData->m_pViewShell->GetObjectShell()->GetFactory().GetViewNo_Impl( pViewFrame->GetCurViewId(), USHRT_MAX );
1482     DBG_ASSERT( nViewNo != USHRT_MAX, "view shell id not found" );
1483     if ( nViewNo != USHRT_MAX )
1484         pViewFrame->GetBindings().Invalidate( nViewNo + SID_VIEWSHELL0 );
1485 }
1486 
1487 //=============================================================================
1488 css::uno::Reference< css::frame::XTitle > SfxBaseController::impl_getTitleHelper ()
1489 {
1490     ::vos::OGuard aGuard( Application::GetSolarMutex() );
1491 
1492     if ( ! m_pData->m_xTitleHelper.is ())
1493     {
1494         css::uno::Reference< css::frame::XModel >           xModel           = getModel ();
1495         css::uno::Reference< css::frame::XUntitledNumbers > xUntitledProvider(xModel                                       , css::uno::UNO_QUERY      );
1496         css::uno::Reference< css::frame::XController >      xThis            (static_cast< css::frame::XController* >(this), css::uno::UNO_QUERY_THROW);
1497 
1498         ::framework::TitleHelper* pHelper                 = new ::framework::TitleHelper(::comphelper::getProcessServiceFactory());
1499                                   m_pData->m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
1500 
1501         pHelper->setOwner                   (xThis            );
1502         pHelper->connectWithUntitledNumbers (xUntitledProvider);
1503     }
1504 
1505     return m_pData->m_xTitleHelper;
1506 }
1507 
1508 //=============================================================================
1509 // css::frame::XTitle
1510 ::rtl::OUString SAL_CALL SfxBaseController::getTitle()
1511     throw (css::uno::RuntimeException)
1512 {
1513     return impl_getTitleHelper()->getTitle ();
1514 }
1515 
1516 //=============================================================================
1517 // css::frame::XTitle
1518 void SAL_CALL SfxBaseController::setTitle(const ::rtl::OUString& sTitle)
1519     throw (css::uno::RuntimeException)
1520 {
1521     impl_getTitleHelper()->setTitle (sTitle);
1522 }
1523 
1524 //=============================================================================
1525 // css::frame::XTitleChangeBroadcaster
1526 void SAL_CALL SfxBaseController::addTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
1527     throw (css::uno::RuntimeException)
1528 {
1529     css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY);
1530     if (xBroadcaster.is ())
1531         xBroadcaster->addTitleChangeListener (xListener);
1532 }
1533 
1534 //=============================================================================
1535 // css::frame::XTitleChangeBroadcaster
1536 void SAL_CALL SfxBaseController::removeTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
1537     throw (css::uno::RuntimeException)
1538 {
1539     css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY);
1540     if (xBroadcaster.is ())
1541         xBroadcaster->removeTitleChangeListener (xListener);
1542 }
1543