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