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