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