Bump version to 4.1-6
[LibreOffice.git] / sfx2 / source / view / sfxbasecontroller.cxx
blob9816437de6b1ce5434cee9d3cd6837f964ee9cc9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <time.h>
21 #include <sfx2/sfxbasecontroller.hxx>
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>
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>
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>
77 #include <boost/unordered_map.hpp>
79 #include <sfx2/event.hxx>
80 #include "sfx2/viewfac.hxx"
82 #define TIMEOUT_START_RESCHEDULE 10L /* 10th s */
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;
105 struct GroupIDToCommandGroup
107 sal_Int16 nGroupID;
108 sal_Int16 nCommandGroup;
111 // Please update when a new command group is added
112 const sal_Int16 MAX_COMMANDGROUP = frame::CommandGroup::CONTROLS;
114 static sal_Bool bGroupIDMapInitialized = sal_False;
115 static GroupIDToCommandGroup GroupIDCommandGroupMap[] =
117 { GID_INTERN , frame::CommandGroup::INTERNAL },
118 { GID_APPLICATION , frame::CommandGroup::APPLICATION },
119 { GID_DOCUMENT , frame::CommandGroup::DOCUMENT },
120 { GID_VIEW , frame::CommandGroup::VIEW },
121 { GID_EDIT , frame::CommandGroup::EDIT },
122 { GID_MACRO , frame::CommandGroup::MACRO },
123 { GID_OPTIONS , frame::CommandGroup::OPTIONS },
124 { GID_MATH , frame::CommandGroup::MATH },
125 { GID_NAVIGATOR , frame::CommandGroup::NAVIGATOR },
126 { GID_INSERT , frame::CommandGroup::INSERT },
127 { GID_FORMAT , frame::CommandGroup::FORMAT },
128 { GID_TEMPLATE , frame::CommandGroup::TEMPLATE },
129 { GID_TEXT , frame::CommandGroup::TEXT },
130 { GID_FRAME , frame::CommandGroup::FRAME },
131 { GID_GRAPHIC , frame::CommandGroup::GRAPHIC },
132 { GID_TABLE , frame::CommandGroup::TABLE },
133 { GID_ENUMERATION , frame::CommandGroup::ENUMERATION },
134 { GID_DATA , frame::CommandGroup::DATA },
135 { GID_SPECIAL , frame::CommandGroup::SPECIAL },
136 { GID_IMAGE , frame::CommandGroup::IMAGE },
137 { GID_CHART , frame::CommandGroup::CHART },
138 { GID_EXPLORER , frame::CommandGroup::EXPLORER },
139 { GID_CONNECTOR , frame::CommandGroup::CONNECTOR },
140 { GID_MODIFY , frame::CommandGroup::MODIFY },
141 { GID_DRAWING , frame::CommandGroup::DRAWING },
142 { GID_CONTROLS , frame::CommandGroup::CONTROLS },
143 { 0 , 0 }
146 typedef boost::unordered_map< sal_Int16, sal_Int16 > GroupHashMap;
149 sal_Int16 MapGroupIDToCommandGroup( sal_Int16 nGroupID )
151 static GroupHashMap mHashMap;
153 if ( !bGroupIDMapInitialized )
155 sal_Int32 i = 0;
156 while ( GroupIDCommandGroupMap[i].nGroupID != 0 )
158 mHashMap.insert( GroupHashMap::value_type(
159 GroupIDCommandGroupMap[i].nGroupID,
160 GroupIDCommandGroupMap[i].nCommandGroup ));
161 ++i;
163 bGroupIDMapInitialized = sal_True;
166 GroupHashMap::const_iterator pIter = mHashMap.find( nGroupID );
167 if ( pIter != mHashMap.end() )
168 return pIter->second;
169 else
170 return frame::CommandGroup::INTERNAL;
173 sal_uInt32 Get10ThSec()
175 sal_uInt32 n10Ticks = 10 * (sal_uInt32)clock();
176 return n10Ticks / CLOCKS_PER_SEC;
179 sal_Int32 m_nInReschedule = 0; /// static counter for rescheduling
181 void reschedule()
183 if ( m_nInReschedule == 0 )
185 ++m_nInReschedule;
186 Application::Reschedule();
187 --m_nInReschedule;
191 class SfxStatusIndicator : public ::cppu::WeakImplHelper2< task::XStatusIndicator, lang::XEventListener >
193 friend class SfxBaseController;
194 Reference < XController > xOwner;
195 Reference < task::XStatusIndicator > xProgress;
196 SfxWorkWindow* pWorkWindow;
197 sal_Int32 _nRange;
198 sal_Int32 _nValue;
199 long _nStartTime;
200 public:
201 SfxStatusIndicator(SfxBaseController* pController, SfxWorkWindow* pWork)
202 : xOwner( pController )
203 , pWorkWindow( pWork )
205 ++m_refCount;
206 Reference< lang::XComponent > xComponent(
207 (static_cast< ::cppu::OWeakObject* >(pController)), uno::UNO_QUERY );
208 if (xComponent.is())
209 xComponent->addEventListener(this);
210 --m_refCount;
213 virtual void SAL_CALL start(const OUString& aText, sal_Int32 nRange) throw(RuntimeException);
214 virtual void SAL_CALL end(void) throw(RuntimeException);
215 virtual void SAL_CALL setText(const OUString& aText) throw(RuntimeException);
216 virtual void SAL_CALL setValue(sal_Int32 nValue) throw(RuntimeException);
217 virtual void SAL_CALL reset() throw(RuntimeException);
219 virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw(RuntimeException);
222 void SAL_CALL SfxStatusIndicator::start(const OUString& aText, sal_Int32 nRange) throw(RuntimeException)
224 SolarMutexGuard aGuard;
225 if ( xOwner.is() )
227 _nRange = nRange;
228 _nValue = 0;
230 if ( !xProgress.is() )
231 xProgress = pWorkWindow->GetStatusIndicator();
233 if ( xProgress.is() )
234 xProgress->start( aText, nRange );
236 _nStartTime = Get10ThSec();
237 reschedule();
241 void SAL_CALL SfxStatusIndicator::end(void) throw(RuntimeException)
243 SolarMutexGuard aGuard;
244 if ( xOwner.is() )
246 if ( !xProgress.is() )
247 xProgress = pWorkWindow->GetStatusIndicator();
249 if ( xProgress.is() )
250 xProgress->end();
252 reschedule();
256 void SAL_CALL SfxStatusIndicator::setText(const OUString& aText) throw(RuntimeException)
258 SolarMutexGuard aGuard;
259 if ( xOwner.is() )
261 if ( !xProgress.is() )
262 xProgress = pWorkWindow->GetStatusIndicator();
264 if ( xProgress.is() )
265 xProgress->setText( aText );
267 reschedule();
271 void SAL_CALL SfxStatusIndicator::setValue( sal_Int32 nValue ) throw(RuntimeException)
273 SolarMutexGuard aGuard;
274 if ( xOwner.is() )
276 _nValue = nValue;
278 if ( !xProgress.is() )
279 xProgress = pWorkWindow->GetStatusIndicator();
281 if ( xProgress.is() )
282 xProgress->setValue( nValue );
284 sal_Bool bReschedule = (( Get10ThSec() - _nStartTime ) > TIMEOUT_START_RESCHEDULE );
285 if ( bReschedule )
286 reschedule();
290 void SAL_CALL SfxStatusIndicator::reset() throw(RuntimeException)
292 SolarMutexGuard aGuard;
293 if ( xOwner.is() )
295 if ( !xProgress.is() )
296 xProgress = pWorkWindow->GetStatusIndicator();
298 if ( xProgress.is() )
299 xProgress->reset();
301 reschedule();
305 void SAL_CALL SfxStatusIndicator::disposing( const lang::EventObject& /*Source*/ ) throw(RuntimeException)
307 SolarMutexGuard aGuard;
308 xOwner = 0;
309 xProgress.clear();
312 //________________________________________________________________________________________________________
313 // declaration IMPL_SfxBaseController_ListenerHelper
314 //________________________________________________________________________________________________________
316 class IMPL_SfxBaseController_ListenerHelper : public ::cppu::WeakImplHelper1< frame::XFrameActionListener >
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) ;
322 virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw (RuntimeException) ;
324 private:
326 SfxBaseController* m_pController ;
328 } ; // class IMPL_SfxBaseController_ListenerContainer
330 class IMPL_SfxBaseController_CloseListenerHelper : public ::cppu::WeakImplHelper1< util::XCloseListener >
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) ;
337 virtual void SAL_CALL notifyClosing( const lang::EventObject& aEvent ) throw (RuntimeException) ;
338 virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw (RuntimeException) ;
340 private:
342 SfxBaseController* m_pController;
344 } ; // class IMPL_SfxBaseController_ListenerContainer
346 IMPL_SfxBaseController_CloseListenerHelper::IMPL_SfxBaseController_CloseListenerHelper( SfxBaseController* pController )
347 : m_pController ( pController )
351 IMPL_SfxBaseController_CloseListenerHelper::~IMPL_SfxBaseController_CloseListenerHelper()
355 void SAL_CALL IMPL_SfxBaseController_CloseListenerHelper::disposing( const lang::EventObject& /*aEvent*/ ) throw( RuntimeException )
359 void SAL_CALL IMPL_SfxBaseController_CloseListenerHelper::queryClosing( const lang::EventObject& aEvent, sal_Bool bDeliverOwnership )
360 throw (RuntimeException, util::CloseVetoException)
362 SolarMutexGuard aGuard;
363 SfxViewShell* pShell = m_pController->GetViewShell_Impl();
364 if ( m_pController != NULL && pShell )
366 sal_Bool bCanClose = (sal_Bool) pShell->PrepareClose( sal_False );
367 if ( !bCanClose )
369 if ( bDeliverOwnership && ( !pShell->GetWindow() || !pShell->GetWindow()->IsReallyVisible() ) )
371 // ignore Ownership in case of visible frame (will be closed by user)
372 Reference < frame::XModel > xModel( aEvent.Source, uno::UNO_QUERY );
373 if ( xModel.is() )
374 pShell->TakeOwnership_Impl();
375 else
376 pShell->TakeFrameOwnership_Impl();
379 throw util::CloseVetoException(OUString("Controller disagree ..."),static_cast< ::cppu::OWeakObject*>(this));
384 void SAL_CALL IMPL_SfxBaseController_CloseListenerHelper::notifyClosing( const lang::EventObject& /*aEvent*/ ) throw (RuntimeException)
388 //________________________________________________________________________________________________________
389 // declaration IMPL_SfxBaseController_DataContainer
390 //________________________________________________________________________________________________________
392 struct IMPL_SfxBaseController_DataContainer
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 sal_Bool m_bDisposing ;
404 sal_Bool m_bSuspendState ;
405 Reference< XTitle > m_xTitleHelper ;
406 Sequence< PropertyValue > m_aCreationArgs ;
408 IMPL_SfxBaseController_DataContainer( ::osl::Mutex& aMutex ,
409 SfxViewShell* pViewShell ,
410 SfxBaseController* pController )
411 : m_xListener ( new IMPL_SfxBaseController_ListenerHelper( pController ) )
412 , 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 ( sal_False )
419 , m_bSuspendState ( sal_False )
423 } ; // struct IMPL_SfxBaseController_DataContainer
425 //________________________________________________________________________________________________________
426 // IMPL_SfxBaseController_ListenerHelper constructor
427 //________________________________________________________________________________________________________
429 IMPL_SfxBaseController_ListenerHelper::IMPL_SfxBaseController_ListenerHelper( SfxBaseController* pController )
430 : m_pController ( pController )
434 //________________________________________________________________________________________________________
435 // IMPL_SfxBaseController_ListenerHelper destructor
436 //________________________________________________________________________________________________________
438 IMPL_SfxBaseController_ListenerHelper::~IMPL_SfxBaseController_ListenerHelper()
442 void SAL_CALL IMPL_SfxBaseController_ListenerHelper::frameAction( const frame::FrameActionEvent& aEvent ) throw( RuntimeException )
444 SolarMutexGuard aGuard;
445 if (
446 ( m_pController != NULL ) &&
447 ( aEvent.Frame == m_pController->getFrame() ) &&
448 ( m_pController->GetViewShell_Impl() && m_pController->GetViewShell_Impl()->GetWindow() != NULL )
451 if ( aEvent.Action == frame::FrameAction_FRAME_UI_ACTIVATED )
453 if ( !m_pController->GetViewShell_Impl()->GetUIActiveIPClient_Impl() )
454 m_pController->GetViewShell_Impl()->GetViewFrame()->MakeActive_Impl( sal_False );
456 else if ( aEvent.Action == frame::FrameAction_CONTEXT_CHANGED )
458 m_pController->GetViewShell_Impl()->GetViewFrame()->GetBindings().ContextChanged_Impl();
463 //________________________________________________________________________________________________________
464 // IMPL_SfxBaseController_ListenerHelper -> XEventListener
465 //________________________________________________________________________________________________________
467 void SAL_CALL IMPL_SfxBaseController_ListenerHelper::disposing( const lang::EventObject& /*aEvent*/ ) throw( RuntimeException )
469 SolarMutexGuard aGuard;
470 if ( m_pController && m_pController->getFrame().is() )
471 m_pController->getFrame()->removeFrameActionListener( this ) ;
474 //________________________________________________________________________________________________________
475 // SfxBaseController -> constructor
476 //________________________________________________________________________________________________________
477 DBG_NAME(sfx2_SfxBaseController)
478 SfxBaseController::SfxBaseController( SfxViewShell* pViewShell )
479 : m_pData ( new IMPL_SfxBaseController_DataContainer( m_aMutex, pViewShell, this ))
481 DBG_CTOR(sfx2_SfxBaseController,NULL);
482 m_pData->m_pViewShell->SetController( this );
485 //________________________________________________________________________________________________________
486 // SfxBaseController -> destructor
487 //________________________________________________________________________________________________________
489 SfxBaseController::~SfxBaseController()
491 DBG_DTOR(sfx2_SfxBaseController,NULL);
492 delete m_pData;
495 //________________________________________________________________________________________________________
496 // SfxBaseController -> XController2
497 //________________________________________________________________________________________________________
499 Reference< XWindow > SAL_CALL SfxBaseController::getComponentWindow() throw (RuntimeException)
501 SolarMutexGuard aGuard;
502 if ( !m_pData->m_pViewShell )
503 throw DisposedException();
505 return Reference< XWindow >( GetViewFrame_Impl().GetFrame().GetWindow().GetComponentInterface(), UNO_QUERY_THROW );
508 OUString SAL_CALL SfxBaseController::getViewControllerName() throw (RuntimeException)
510 SolarMutexGuard aGuard;
511 if ( !m_pData->m_pViewShell || !m_pData->m_pViewShell->GetObjectShell() )
512 throw DisposedException();
514 const SfxObjectFactory& rDocFac( m_pData->m_pViewShell->GetObjectShell()->GetFactory() );
515 sal_uInt16 nViewNo = rDocFac.GetViewNo_Impl( GetViewFrame_Impl().GetCurViewId(), rDocFac.GetViewFactoryCount() );
516 OSL_ENSURE( nViewNo < rDocFac.GetViewFactoryCount(), "SfxBaseController::getViewControllerName: view ID not found in view factories!" );
518 OUString sViewName;
519 if ( nViewNo < rDocFac.GetViewFactoryCount() )
520 sViewName = rDocFac.GetViewFactory( nViewNo ).GetAPIViewName();
522 return sViewName;
525 Sequence< PropertyValue > SAL_CALL SfxBaseController::getCreationArguments() throw (RuntimeException)
527 SolarMutexGuard aGuard;
528 if ( !m_pData->m_pViewShell || !m_pData->m_pViewShell->GetObjectShell() )
529 throw DisposedException();
531 return m_pData->m_aCreationArgs;
534 void SfxBaseController::SetCreationArguments_Impl( const Sequence< PropertyValue >& i_rCreationArgs )
536 OSL_ENSURE( m_pData->m_aCreationArgs.getLength() == 0, "SfxBaseController::SetCreationArguments_Impl: not intended to be called twice!" );
537 m_pData->m_aCreationArgs = i_rCreationArgs;
540 SfxViewFrame& SfxBaseController::GetViewFrame_Impl() const
542 ENSURE_OR_THROW( m_pData->m_pViewShell, "not to be called without a view shell" );
543 SfxViewFrame* pActFrame = m_pData->m_pViewShell->GetFrame();
544 ENSURE_OR_THROW( pActFrame, "a view shell without a view frame is pretty pathological" );
545 return *pActFrame;
548 //________________________________________________________________________________________________________
549 // SfxBaseController -> XController2 -> XController
550 //________________________________________________________________________________________________________
552 void SAL_CALL SfxBaseController::attachFrame( const Reference< frame::XFrame >& xFrame ) throw( RuntimeException )
554 Reference< frame::XFrame > xTemp( getFrame() ) ;
556 SolarMutexGuard aGuard;
557 if ( xTemp.is() )
559 xTemp->removeFrameActionListener( m_pData->m_xListener ) ;
560 Reference < util::XCloseBroadcaster > xCloseable( xTemp, uno::UNO_QUERY );
561 if ( xCloseable.is() )
562 xCloseable->removeCloseListener( m_pData->m_xCloseListener );
565 m_pData->m_xFrame = xFrame;
567 if ( xFrame.is() )
569 xFrame->addFrameActionListener( m_pData->m_xListener ) ;
570 Reference < util::XCloseBroadcaster > xCloseable( xFrame, uno::UNO_QUERY );
571 if ( xCloseable.is() )
572 xCloseable->addCloseListener( m_pData->m_xCloseListener );
574 if ( m_pData->m_pViewShell )
576 ConnectSfxFrame_Impl( E_CONNECT );
577 ShowInfoBars( );
579 // attaching the frame to the controller is the last step in the creation of a new view, so notify this
580 SfxViewEventHint aHint( SFX_EVENT_VIEWCREATED, GlobalEventConfig::GetEventName( STR_EVENT_VIEWCREATED ), m_pData->m_pViewShell->GetObjectShell(), Reference< frame::XController2 >( this ) );
581 SFX_APP()->NotifyEvent( aHint );
586 //________________________________________________________________________________________________________
587 // SfxBaseController -> XController
588 //________________________________________________________________________________________________________
590 sal_Bool SAL_CALL SfxBaseController::attachModel( const Reference< frame::XModel >& xModel ) throw( RuntimeException )
592 if ( m_pData->m_pViewShell && xModel.is() && xModel != m_pData->m_pViewShell->GetObjectShell()->GetModel() )
594 // don't allow to reattach a model!
595 OSL_FAIL("Can't reattach model!");
596 return sal_False;
599 Reference < util::XCloseBroadcaster > xCloseable( xModel, uno::UNO_QUERY );
600 if ( xCloseable.is() )
601 xCloseable->addCloseListener( m_pData->m_xCloseListener );
602 return sal_True;
605 //________________________________________________________________________________________________________
606 // SfxBaseController -> XController
607 //________________________________________________________________________________________________________
609 sal_Bool SAL_CALL SfxBaseController::suspend( sal_Bool bSuspend ) throw( RuntimeException )
611 SolarMutexGuard aGuard;
613 // ignore dublicate calls, which doesnt change anything real
614 if (bSuspend == m_pData->m_bSuspendState)
615 return sal_True;
617 if ( bSuspend == sal_True )
619 if ( !m_pData->m_pViewShell )
621 m_pData->m_bSuspendState = sal_True;
622 return sal_True;
625 if ( !m_pData->m_pViewShell->PrepareClose() )
626 return sal_False;
628 if ( getFrame().is() )
629 getFrame()->removeFrameActionListener( m_pData->m_xListener ) ;
630 SfxViewFrame* pActFrame = m_pData->m_pViewShell->GetFrame() ;
632 // More Views on the same document?
633 SfxObjectShell* pDocShell = m_pData->m_pViewShell->GetObjectShell() ;
634 sal_Bool bOther = sal_False ;
636 for ( const SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell ); !bOther && pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ) )
637 bOther = (pFrame != pActFrame);
639 sal_Bool bRet = bOther || pDocShell->PrepareClose();
640 if ( bRet )
642 ConnectSfxFrame_Impl( E_DISCONNECT );
643 m_pData->m_bSuspendState = sal_True;
646 return bRet;
648 else
650 if ( getFrame().is() )
651 getFrame()->addFrameActionListener( m_pData->m_xListener ) ;
653 if ( m_pData->m_pViewShell )
655 ConnectSfxFrame_Impl( E_RECONNECT );
658 m_pData->m_bSuspendState = sal_False;
659 return sal_True ;
663 //________________________________________________________________________________________________________
664 // SfxBaseController -> XController
665 //________________________________________________________________________________________________________
667 uno::Any SfxBaseController::getViewData() throw( RuntimeException )
669 uno::Any aAny;
670 String sData1;
671 SolarMutexGuard aGuard;
672 if ( m_pData->m_pViewShell )
674 m_pData->m_pViewShell->WriteUserData( sData1 ) ;
675 OUString sData( sData1 );
676 aAny <<= sData ;
679 return aAny ;
682 //________________________________________________________________________________________________________
683 // SfxBaseController -> XController
684 //________________________________________________________________________________________________________
686 void SAL_CALL SfxBaseController::restoreViewData( const uno::Any& aValue ) throw( RuntimeException )
688 SolarMutexGuard aGuard;
689 if ( m_pData->m_pViewShell )
691 OUString sData;
692 aValue >>= sData ;
693 m_pData->m_pViewShell->ReadUserData( sData ) ;
697 //________________________________________________________________________________________________________
698 // SfxBaseController -> XController
699 //________________________________________________________________________________________________________
701 Reference< frame::XFrame > SAL_CALL SfxBaseController::getFrame() throw( RuntimeException )
703 SolarMutexGuard aGuard;
704 return m_pData->m_xFrame;
707 //________________________________________________________________________________________________________
708 // SfxBaseController -> XController
709 //________________________________________________________________________________________________________
711 Reference< frame::XModel > SAL_CALL SfxBaseController::getModel() throw( RuntimeException )
713 SolarMutexGuard aGuard;
714 return m_pData->m_pViewShell ? m_pData->m_pViewShell->GetObjectShell()->GetModel() : Reference < frame::XModel > () ;
717 //________________________________________________________________________________________________________
718 // SfxBaseController -> XDispatchProvider
719 //________________________________________________________________________________________________________
721 Reference< frame::XDispatch > SAL_CALL SfxBaseController::queryDispatch( const util::URL& aURL ,
722 const OUString& sTargetFrameName,
723 sal_Int32 eSearchFlags ) throw( RuntimeException )
725 SolarMutexGuard aGuard;
726 Reference< frame::XDispatch > xDisp;
727 if ( m_pData->m_pViewShell )
729 SfxViewFrame* pAct = m_pData->m_pViewShell->GetViewFrame() ;
730 if ( !m_pData->m_bDisposing )
732 if ( sTargetFrameName == "_beamer" )
734 SfxViewFrame *pFrame = m_pData->m_pViewShell->GetViewFrame();
735 if ( eSearchFlags & ( frame::FrameSearchFlag::CREATE ))
736 pFrame->SetChildWindow( SID_BROWSER, sal_True );
737 SfxChildWindow* pChildWin = pFrame->GetChildWindow( SID_BROWSER );
738 Reference < frame::XFrame > xFrame;
739 if ( pChildWin )
740 xFrame = ( pChildWin->GetFrame() );
741 if ( xFrame.is() )
742 xFrame->setName( sTargetFrameName );
744 Reference< XDispatchProvider > xProv( xFrame, uno::UNO_QUERY );
745 if ( xProv.is() )
746 return xProv->queryDispatch( aURL, sTargetFrameName, frame::FrameSearchFlag::SELF );
749 if ( aURL.Protocol == ".uno:" )
751 OUString aMasterCommand = SfxOfficeDispatch::GetMasterUnoCommand( aURL );
752 sal_Bool bMasterCommand( !aMasterCommand.isEmpty() );
754 pAct = m_pData->m_pViewShell->GetViewFrame() ;
755 SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( pAct );
757 const SfxSlot* pSlot( 0 );
758 if ( bMasterCommand )
759 pSlot = rSlotPool.GetUnoSlot( aMasterCommand );
760 else
761 pSlot = rSlotPool.GetUnoSlot( aURL.Path );
762 if ( pSlot && ( !pAct->GetFrame().IsInPlace() || !pSlot->IsMode( SFX_SLOT_CONTAINER ) ) )
763 return pAct->GetBindings().GetDispatch( pSlot, aURL, bMasterCommand );
764 else
766 // try to find parent SfxViewFrame
767 Reference< frame::XFrame > xParentFrame;
768 Reference< frame::XFrame > xOwnFrame = pAct->GetFrame().GetFrameInterface();
769 if ( xOwnFrame.is() )
770 xParentFrame = Reference< frame::XFrame >( xOwnFrame->getCreator(), uno::UNO_QUERY );
772 if ( xParentFrame.is() )
774 // TODO/LATER: in future probably SfxViewFrame hirarchy should be the same as XFrame hirarchy
775 // SfxViewFrame* pParentFrame = pAct->GetParentViewFrame();
777 // search the related SfxViewFrame
778 SfxViewFrame* pParentFrame = NULL;
779 for ( SfxViewFrame* pFrame = SfxViewFrame::GetFirst();
780 pFrame;
781 pFrame = SfxViewFrame::GetNext( *pFrame ) )
783 if ( pFrame->GetFrame().GetFrameInterface() == xParentFrame )
785 pParentFrame = pFrame;
786 break;
790 if ( pParentFrame )
792 SfxSlotPool& rFrameSlotPool = SfxSlotPool::GetSlotPool( pParentFrame );
793 const SfxSlot* pSlot2( 0 );
794 if ( bMasterCommand )
795 pSlot2 = rFrameSlotPool.GetUnoSlot( aMasterCommand );
796 else
797 pSlot2 = rFrameSlotPool.GetUnoSlot( aURL.Path );
799 if ( pSlot2 )
800 return pParentFrame->GetBindings().GetDispatch( pSlot2, aURL, bMasterCommand );
805 else if ( aURL.Protocol == "slot:" )
807 sal_uInt16 nId = (sal_uInt16) aURL.Path.toInt32();
809 pAct = m_pData->m_pViewShell->GetViewFrame() ;
810 if (nId >= SID_VERB_START && nId <= SID_VERB_END)
812 const SfxSlot* pSlot = m_pData->m_pViewShell->GetVerbSlot_Impl(nId);
813 if ( pSlot )
814 return pAct->GetBindings().GetDispatch( pSlot, aURL, sal_False );
817 SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( pAct );
818 const SfxSlot* pSlot = rSlotPool.GetSlot( nId );
819 if ( pSlot && ( !pAct->GetFrame().IsInPlace() || !pSlot->IsMode( SFX_SLOT_CONTAINER ) ) )
820 return pAct->GetBindings().GetDispatch( pSlot, aURL, sal_False );
821 else
823 // try to find parent SfxViewFrame
824 Reference< frame::XFrame > xParentFrame;
825 Reference< frame::XFrame > xOwnFrame = pAct->GetFrame().GetFrameInterface();
826 if ( xOwnFrame.is() )
827 xParentFrame = Reference< frame::XFrame >( xOwnFrame->getCreator(), uno::UNO_QUERY );
829 if ( xParentFrame.is() )
831 // TODO/LATER: in future probably SfxViewFrame hirarchy should be the same as XFrame hirarchy
832 // SfxViewFrame* pParentFrame = pAct->GetParentViewFrame();
834 // search the related SfxViewFrame
835 SfxViewFrame* pParentFrame = NULL;
836 for ( SfxViewFrame* pFrame = SfxViewFrame::GetFirst();
837 pFrame;
838 pFrame = SfxViewFrame::GetNext( *pFrame ) )
840 if ( pFrame->GetFrame().GetFrameInterface() == xParentFrame )
842 pParentFrame = pFrame;
843 break;
847 if ( pParentFrame )
849 SfxSlotPool& rSlotPool2 = SfxSlotPool::GetSlotPool( pParentFrame );
850 const SfxSlot* pSlot2 = rSlotPool2.GetUnoSlot( aURL.Path );
851 if ( pSlot2 )
852 return pParentFrame->GetBindings().GetDispatch( pSlot2, aURL, sal_False );
857 else if( sTargetFrameName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("_self")) || sTargetFrameName.isEmpty() )
859 // check for already loaded URL ... but with additional jumpmark!
860 Reference< frame::XModel > xModel = getModel();
861 if( xModel.is() && !aURL.Mark.isEmpty() )
863 SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( pAct );
864 const SfxSlot* pSlot = rSlotPool.GetSlot( SID_JUMPTOMARK );
865 if( !aURL.Main.isEmpty() && aURL.Main == xModel->getURL() && pSlot )
866 return Reference< frame::XDispatch >( new SfxOfficeDispatch( pAct->GetBindings(), pAct->GetDispatcher(), pSlot, aURL) );
872 return xDisp;
875 //________________________________________________________________________________________________________
876 // SfxBaseController -> XDispatchProvider
877 //________________________________________________________________________________________________________
879 uno::Sequence< Reference< frame::XDispatch > > SAL_CALL SfxBaseController::queryDispatches( const uno::Sequence< frame::DispatchDescriptor >& seqDescripts ) throw( RuntimeException )
881 // Create return list - which must have same size then the given descriptor
882 // It's not allowed to pack it!
883 sal_Int32 nCount = seqDescripts.getLength();
884 uno::Sequence< Reference< frame::XDispatch > > lDispatcher( nCount );
886 for( sal_Int32 i=0; i<nCount; ++i )
888 lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL ,
889 seqDescripts[i].FrameName ,
890 seqDescripts[i].SearchFlags );
893 return lDispatcher;
896 //________________________________________________________________________________________________________
897 // SfxBaseController -> XControllerBorder
898 //________________________________________________________________________________________________________
900 frame::BorderWidths SAL_CALL SfxBaseController::getBorder()
901 throw ( RuntimeException )
903 frame::BorderWidths aResult;
905 SolarMutexGuard aGuard;
906 if ( m_pData->m_pViewShell )
908 SvBorder aBorder = m_pData->m_pViewShell->GetBorderPixel();
909 aResult.Left = aBorder.Left();
910 aResult.Top = aBorder.Top();
911 aResult.Right = aBorder.Right();
912 aResult.Bottom = aBorder.Bottom();
915 return aResult;
918 void SAL_CALL SfxBaseController::addBorderResizeListener( const Reference< frame::XBorderResizeListener >& xListener )
919 throw ( RuntimeException )
921 m_pData->m_aListenerContainer.addInterface( ::getCppuType((const Reference< frame::XBorderResizeListener >*)0),
922 xListener );
925 void SAL_CALL SfxBaseController::removeBorderResizeListener( const Reference< frame::XBorderResizeListener >& xListener )
926 throw ( RuntimeException )
928 m_pData->m_aListenerContainer.removeInterface( ::getCppuType((const Reference< frame::XBorderResizeListener >*)0),
929 xListener );
932 awt::Rectangle SAL_CALL SfxBaseController::queryBorderedArea( const awt::Rectangle& aPreliminaryRectangle )
933 throw ( RuntimeException )
935 SolarMutexGuard aGuard;
936 if ( m_pData->m_pViewShell )
938 Rectangle aTmpRect = VCLRectangle( aPreliminaryRectangle );
939 m_pData->m_pViewShell->QueryObjAreaPixel( aTmpRect );
940 return AWTRectangle( aTmpRect );
943 return aPreliminaryRectangle;
946 void SfxBaseController::BorderWidthsChanged_Impl()
948 ::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aListenerContainer.getContainer(
949 ::getCppuType( ( const Reference< frame::XBorderResizeListener >*) NULL ) );
950 if ( pContainer )
952 frame::BorderWidths aBWidths = getBorder();
953 Reference< uno::XInterface > xThis( static_cast< ::cppu::OWeakObject* >(this), uno::UNO_QUERY );
955 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
956 while (pIterator.hasMoreElements())
960 ((frame::XBorderResizeListener*)pIterator.next())->borderWidthsChanged( xThis, aBWidths );
962 catch (const RuntimeException&)
964 pIterator.remove();
970 //________________________________________________________________________________________________________
971 // SfxBaseController -> XComponent
972 //________________________________________________________________________________________________________
974 void SAL_CALL SfxBaseController::dispose() throw( RuntimeException )
976 SolarMutexGuard aGuard;
977 Reference< XController > xTmp( this );
978 m_pData->m_bDisposing = sal_True ;
980 lang::EventObject aEventObject;
981 aEventObject.Source = *this ;
982 m_pData->m_aListenerContainer.disposeAndClear( aEventObject ) ;
984 if ( m_pData->m_pController && m_pData->m_pController->getFrame().is() )
985 m_pData->m_pController->getFrame()->removeFrameActionListener( m_pData->m_xListener ) ;
987 if ( m_pData->m_pViewShell )
989 SfxViewFrame* pFrame = m_pData->m_pViewShell->GetViewFrame() ;
990 if ( pFrame && pFrame->GetViewShell() == m_pData->m_pViewShell )
991 pFrame->GetFrame().SetIsClosing_Impl();
992 m_pData->m_pViewShell->DiscardClients_Impl();
993 m_pData->m_pViewShell->pImp->m_bControllerSet = false;
995 if ( pFrame )
997 lang::EventObject aObject;
998 aObject.Source = *this ;
1000 SfxObjectShell* pDoc = pFrame->GetObjectShell() ;
1001 SfxViewFrame *pView = SfxViewFrame::GetFirst(pDoc);
1002 while( pView )
1004 // if there is another ViewFrame or currently the ViewShell in my ViewFrame is switched (PagePreview)
1005 if ( pView != pFrame || pView->GetViewShell() != m_pData->m_pViewShell )
1006 break;
1007 pView = SfxViewFrame::GetNext( *pView, pDoc );
1010 SFX_APP()->NotifyEvent( SfxViewEventHint(SFX_EVENT_CLOSEVIEW, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEVIEW ), pDoc, Reference< frame::XController2 >( this ) ) );
1011 if ( !pView )
1012 SFX_APP()->NotifyEvent( SfxEventHint(SFX_EVENT_CLOSEDOC, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ), pDoc) );
1014 Reference< frame::XModel > xModel = pDoc->GetModel();
1015 Reference < util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
1016 if ( xModel.is() )
1018 xModel->disconnectController( this );
1019 if ( xCloseable.is() )
1020 xCloseable->removeCloseListener( m_pData->m_xCloseListener );
1023 Reference < frame::XFrame > aXFrame;
1024 attachFrame( aXFrame );
1026 m_pData->m_xListener->disposing( aObject );
1027 SfxViewShell *pShell = m_pData->m_pViewShell;
1028 m_pData->m_pViewShell = NULL;
1029 if ( pFrame->GetViewShell() == pShell )
1031 // Enter registrations only allowed if we are the owner!
1032 if ( pFrame->GetFrame().OwnsBindings_Impl() )
1033 pFrame->GetBindings().ENTERREGISTRATIONS();
1034 pFrame->GetFrame().SetFrameInterface_Impl( aXFrame );
1035 pFrame->GetFrame().DoClose_Impl();
1041 //________________________________________________________________________________________________________
1042 // SfxBaseController -> XComponent
1043 //________________________________________________________________________________________________________
1045 void SAL_CALL SfxBaseController::addEventListener( const Reference< lang::XEventListener >& aListener ) throw( RuntimeException )
1047 m_pData->m_aListenerContainer.addInterface( ::getCppuType((const Reference< lang::XEventListener >*)0), aListener );
1050 //________________________________________________________________________________________________________
1051 // SfxBaseController -> XComponent
1052 //________________________________________________________________________________________________________
1054 void SAL_CALL SfxBaseController::removeEventListener( const Reference< lang::XEventListener >& aListener ) throw( RuntimeException )
1056 m_pData->m_aListenerContainer.removeInterface( ::getCppuType((const Reference< lang::XEventListener >*)0), aListener );
1059 void SfxBaseController::ReleaseShell_Impl()
1061 SolarMutexGuard aGuard;
1062 if ( m_pData->m_pViewShell )
1064 SfxObjectShell* pDoc = m_pData->m_pViewShell->GetObjectShell() ;
1065 Reference< frame::XModel > xModel = pDoc->GetModel();
1066 Reference < util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
1067 if ( xModel.is() )
1069 xModel->disconnectController( this );
1070 if ( xCloseable.is() )
1071 xCloseable->removeCloseListener( m_pData->m_xCloseListener );
1073 m_pData->m_pViewShell = 0;
1075 Reference < frame::XFrame > aXFrame;
1076 attachFrame( aXFrame );
1080 SfxViewShell* SfxBaseController::GetViewShell_Impl() const
1082 return m_pData->m_pViewShell;
1085 Reference< task::XStatusIndicator > SAL_CALL SfxBaseController::getStatusIndicator( ) throw (RuntimeException)
1087 SolarMutexGuard aGuard;
1088 if ( m_pData->m_pViewShell && !m_pData->m_xIndicator.is() )
1089 m_pData->m_xIndicator = new SfxStatusIndicator( this, m_pData->m_pViewShell->GetViewFrame()->GetFrame().GetWorkWindow_Impl() );
1090 return m_pData->m_xIndicator;
1093 void SAL_CALL SfxBaseController::registerContextMenuInterceptor( const Reference< ui::XContextMenuInterceptor >& xInterceptor ) throw( RuntimeException )
1096 m_pData->m_aInterceptorContainer.addInterface( xInterceptor );
1098 SolarMutexGuard aGuard;
1099 if ( m_pData->m_pViewShell )
1100 m_pData->m_pViewShell->AddContextMenuInterceptor_Impl( xInterceptor );
1103 void SAL_CALL SfxBaseController::releaseContextMenuInterceptor( const Reference< ui::XContextMenuInterceptor >& xInterceptor ) throw( RuntimeException )
1106 m_pData->m_aInterceptorContainer.removeInterface( xInterceptor );
1108 SolarMutexGuard aGuard;
1109 if ( m_pData->m_pViewShell )
1110 m_pData->m_pViewShell->RemoveContextMenuInterceptor_Impl( xInterceptor );
1113 void SAL_CALL SfxBaseController::addKeyHandler( const Reference< awt::XKeyHandler >& xHandler ) throw (RuntimeException)
1115 SolarMutexGuard aGuard;
1116 m_pData->m_aUserInputInterception.addKeyHandler( xHandler );
1119 void SAL_CALL SfxBaseController::removeKeyHandler( const Reference< awt::XKeyHandler >& xHandler ) throw (RuntimeException)
1121 SolarMutexGuard aGuard;
1122 m_pData->m_aUserInputInterception.removeKeyHandler( xHandler );
1125 void SAL_CALL SfxBaseController::addMouseClickHandler( const Reference< awt::XMouseClickHandler >& xHandler ) throw (RuntimeException)
1127 SolarMutexGuard aGuard;
1128 m_pData->m_aUserInputInterception.addMouseClickHandler( xHandler );
1131 void SAL_CALL SfxBaseController::removeMouseClickHandler( const Reference< awt::XMouseClickHandler >& xHandler ) throw (RuntimeException)
1133 SolarMutexGuard aGuard;
1134 m_pData->m_aUserInputInterception.removeMouseClickHandler( xHandler );
1137 uno::Sequence< sal_Int16 > SAL_CALL SfxBaseController::getSupportedCommandGroups()
1138 throw (RuntimeException)
1140 SolarMutexGuard aGuard;
1142 std::list< sal_Int16 > aGroupList;
1143 SfxViewFrame* pViewFrame( m_pData->m_pViewShell->GetFrame() );
1144 SfxSlotPool* pPool = &SfxSlotPool::GetSlotPool( pViewFrame );
1146 SfxSlotPool* pSlotPool = pPool ? pPool : &SFX_SLOTPOOL();
1147 const sal_uIntPtr nMode( SFX_SLOT_TOOLBOXCONFIG|SFX_SLOT_ACCELCONFIG|SFX_SLOT_MENUCONFIG );
1149 // Select Group ( Group 0 is internal )
1150 for ( sal_uInt16 i=0; i<pSlotPool->GetGroupCount(); i++ )
1152 pSlotPool->SeekGroup( i );
1153 const SfxSlot* pSfxSlot = pSlotPool->FirstSlot();
1154 while ( pSfxSlot )
1156 if ( pSfxSlot->GetMode() & nMode )
1158 sal_Int16 nCommandGroup = MapGroupIDToCommandGroup( pSfxSlot->GetGroupId() );
1159 aGroupList.push_back( nCommandGroup );
1160 break;
1162 pSfxSlot = pSlotPool->NextSlot();
1166 uno::Sequence< sal_Int16 > aSeq =
1167 comphelper::containerToSequence< sal_Int16 >( aGroupList );
1168 return aSeq;
1171 uno::Sequence< frame::DispatchInformation > SAL_CALL SfxBaseController::getConfigurableDispatchInformation( sal_Int16 nCmdGroup )
1172 throw (RuntimeException)
1174 std::list< frame::DispatchInformation > aCmdList;
1176 SolarMutexGuard aGuard;
1177 if ( m_pData->m_pViewShell )
1179 const sal_uIntPtr nMode( SFX_SLOT_TOOLBOXCONFIG|SFX_SLOT_ACCELCONFIG|SFX_SLOT_MENUCONFIG );
1181 SfxViewFrame* pViewFrame( m_pData->m_pViewShell->GetFrame() );
1182 SfxSlotPool* pPool( &SfxSlotPool::GetSlotPool( pViewFrame ));
1183 OUString aCmdPrefix( ".uno:" );
1185 SfxSlotPool* pSlotPool = pPool ? pPool : &SFX_SLOTPOOL();
1186 for ( sal_uInt16 i=0; i<pSlotPool->GetGroupCount(); i++ )
1188 pSlotPool->SeekGroup( i );
1189 const SfxSlot* pSfxSlot = pSlotPool->FirstSlot();
1190 if ( pSfxSlot )
1192 sal_Int16 nCommandGroup = MapGroupIDToCommandGroup( pSfxSlot->GetGroupId() );
1193 if ( nCommandGroup == nCmdGroup )
1195 while ( pSfxSlot )
1197 if ( pSfxSlot->GetMode() & nMode )
1199 frame::DispatchInformation aCmdInfo;
1200 OUStringBuffer aBuf( aCmdPrefix );
1201 aBuf.appendAscii( pSfxSlot->GetUnoName() );
1202 aCmdInfo.Command = aBuf.makeStringAndClear();
1203 aCmdInfo.GroupId = nCommandGroup;
1204 aCmdList.push_back( aCmdInfo );
1206 pSfxSlot = pSlotPool->NextSlot();
1213 uno::Sequence< frame::DispatchInformation > aSeq =
1214 comphelper::containerToSequence< frame::DispatchInformation, std::list< frame::DispatchInformation > >( aCmdList );
1216 return aSeq;
1219 sal_Bool SfxBaseController::HandleEvent_Impl( NotifyEvent& rEvent )
1221 return m_pData->m_aUserInputInterception.handleNotifyEvent( rEvent );
1224 sal_Bool SfxBaseController::HasKeyListeners_Impl()
1226 return m_pData->m_aUserInputInterception.hasKeyHandlers();
1229 sal_Bool SfxBaseController::HasMouseClickListeners_Impl()
1231 return m_pData->m_aUserInputInterception.hasMouseClickListeners();
1234 void SfxBaseController::ConnectSfxFrame_Impl( const ConnectSfxFrame i_eConnect )
1236 ENSURE_OR_THROW( m_pData->m_pViewShell, "not to be called without a view shell" );
1237 SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame();
1238 ENSURE_OR_THROW( pViewFrame, "a view shell without a view frame is pretty pathological" );
1240 const bool bConnect = ( i_eConnect != E_DISCONNECT );
1242 // disable window and dispatcher
1243 pViewFrame->Enable( bConnect );
1244 pViewFrame->GetDispatcher()->Lock( !bConnect );
1246 if ( bConnect )
1248 if ( i_eConnect == E_CONNECT )
1250 if ( ( m_pData->m_pViewShell->GetObjectShell() != NULL )
1251 && ( m_pData->m_pViewShell->GetObjectShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
1254 SfxViewFrame* pViewFrm = m_pData->m_pViewShell->GetViewFrame();
1255 if ( !pViewFrm->GetFrame().IsInPlace() )
1257 // for outplace embedded objects, we want the layout manager to keep the content window
1258 // size constant, if possible
1261 Reference< beans::XPropertySet > xFrameProps( m_pData->m_xFrame, uno::UNO_QUERY_THROW );
1262 Reference< beans::XPropertySet > xLayouterProps(
1263 xFrameProps->getPropertyValue( OUString( "LayoutManager" ) ), uno::UNO_QUERY_THROW );
1264 xLayouterProps->setPropertyValue( OUString( "PreserveContentSize" ), uno::makeAny( sal_True ) );
1266 catch (const uno::Exception&)
1268 DBG_UNHANDLED_EXCEPTION();
1274 // upon DISCONNECT, we did *not* pop the shells from the stack (this is done elsewhere), so upon
1275 // RECONNECT, we're not allowed to push them
1276 if ( i_eConnect != E_RECONNECT )
1278 pViewFrame->GetDispatcher()->Push( *m_pData->m_pViewShell );
1279 if ( m_pData->m_pViewShell->GetSubShell() )
1280 pViewFrame->GetDispatcher()->Push( *m_pData->m_pViewShell->GetSubShell() );
1281 m_pData->m_pViewShell->PushSubShells_Impl();
1282 pViewFrame->GetDispatcher()->Flush();
1285 Window* pEditWin = m_pData->m_pViewShell->GetWindow();
1286 if ( pEditWin && m_pData->m_pViewShell->IsShowView_Impl() )
1287 pEditWin->Show();
1289 if ( SfxViewFrame::Current() == pViewFrame )
1290 pViewFrame->GetDispatcher()->Update_Impl( sal_True );
1292 Window* pFrameWin = &pViewFrame->GetWindow();
1293 if ( pFrameWin != &pViewFrame->GetFrame().GetWindow() )
1294 pFrameWin->Show();
1296 if ( i_eConnect == E_CONNECT )
1298 ::comphelper::NamedValueCollection aDocumentArgs( getModel()->getArgs() );
1300 const sal_Int16 nPluginMode = aDocumentArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) );
1301 const bool bHasPluginMode = ( nPluginMode != 0 );
1303 SfxFrame& rFrame = pViewFrame->GetFrame();
1304 SfxObjectShell& rDoc = *m_pData->m_pViewShell->GetObjectShell();
1305 if ( !rFrame.IsMarkedHidden_Impl() )
1307 if ( rDoc.IsHelpDocument() || ( nPluginMode == 2 ) )
1308 pViewFrame->GetDispatcher()->HideUI( sal_True );
1309 else
1310 pViewFrame->GetDispatcher()->HideUI( sal_False );
1312 if ( rFrame.IsInPlace() )
1313 pViewFrame->LockAdjustPosSizePixel();
1315 if ( nPluginMode == 3 )
1316 rFrame.GetWorkWindow_Impl()->SetInternalDockingAllowed( sal_False );
1318 if ( !rFrame.IsInPlace() )
1319 pViewFrame->GetDispatcher()->Update_Impl();
1320 pViewFrame->Show();
1321 rFrame.GetWindow().Show();
1322 if ( !rFrame.IsInPlace() || ( nPluginMode == 3 ) )
1323 pViewFrame->MakeActive_Impl( rFrame.GetFrameInterface()->isActive() );
1325 if ( rFrame.IsInPlace() )
1327 pViewFrame->UnlockAdjustPosSizePixel();
1328 // force resize for OLE server to fix layout problems of writer and math
1329 // see i53651
1330 if ( nPluginMode == 3 )
1331 pViewFrame->Resize( sal_True );
1334 else
1336 DBG_ASSERT( !rFrame.IsInPlace() && !bHasPluginMode, "Special modes not compatible with hidden mode!" );
1337 rFrame.GetWindow().Show();
1340 // UpdateTitle now, hidden TopFrames have otherwise no Name!
1341 pViewFrame->UpdateTitle();
1343 if ( !rFrame.IsInPlace() )
1344 pViewFrame->Resize( sal_True );
1346 // if there's a JumpMark given, then, well, jump to it
1347 ::comphelper::NamedValueCollection aViewArgs( getCreationArguments() );
1348 const OUString sJumpMark = aViewArgs.getOrDefault( "JumpMark", OUString() );
1349 const bool bHasJumpMark = !sJumpMark.isEmpty();
1350 OSL_ENSURE( ( !m_pData->m_pViewShell->GetObjectShell()->IsLoading() )
1351 || ( sJumpMark.isEmpty() ),
1352 "SfxBaseController::ConnectSfxFrame_Impl: so this code wasn't dead?" );
1353 // Before CWS autorecovery, there was code which postponed jumping to the Mark to a later time
1354 // (SfxObjectShell::PositionView_Impl), but it seems this branch was never used, since this method
1355 // here is never called before the load process finished. At least not with a non-empty jump mark
1356 if ( !sJumpMark.isEmpty() )
1357 m_pData->m_pViewShell->JumpToMark( sJumpMark );
1359 // if no plugin mode and no jump mark was supplied, check whether the document itself can provide view data, and
1360 // if so, forward it to the view/shell.
1361 if ( !bHasPluginMode && !bHasJumpMark )
1363 // Note that this might not be the ideal place here. Restoring view data should, IMO, be the
1364 // responsibility of the loader, not an implementation detail burried here deep within the controller's
1365 // implementation.
1366 // What I think should be done to replace the below code:
1367 // - change SfxBaseController::restoreViewData to also accept a PropertyValue[] (it currently accepts
1368 // a string only), and forward it to its ViewShell's ReadUserDataSequence
1369 // - change the frame loader so that when a new document is loaded (as opposed to an existing
1370 // document being loaded into a new frame), the model's view data is examine the very same
1371 // way as below, and the proper view data is set via XController::restoreViewData
1372 // - extend SfxViewFrame::SwitchToViewShell_Impl. Currently, it cares for the case where a non-PrintPreview
1373 // view is exchanged, and sets the old view's data at the model. It should also care for the other
1374 // way, were the PrintPreview view is left: in this case, the new view should also be initialized
1375 // with the model's view data
1378 Reference< XViewDataSupplier > xViewDataSupplier( getModel(), UNO_QUERY_THROW );
1379 Reference< XIndexAccess > xViewData( xViewDataSupplier->getViewData() );
1381 // find the view data item whose ViewId matches the ID of the view we're just connecting to
1382 const SfxObjectFactory& rDocFactory( rDoc.GetFactory() );
1383 const sal_Int32 nCount = xViewData.is() ? xViewData->getCount() : 0;
1384 sal_Int32 nViewDataIndex = 0;
1385 for ( sal_Int32 i=0; i<nCount; ++i )
1387 const ::comphelper::NamedValueCollection aViewData( xViewData->getByIndex(i) );
1388 OUString sViewId( aViewData.getOrDefault( "ViewId", OUString() ) );
1389 if ( sViewId.isEmpty() )
1390 continue;
1392 const SfxViewFactory* pViewFactory = rDocFactory.GetViewFactoryByViewName( sViewId );
1393 if ( pViewFactory == NULL )
1394 continue;
1396 if ( pViewFactory->GetOrdinal() == pViewFrame->GetCurViewId() )
1398 nViewDataIndex = i;
1399 break;
1402 if ( nViewDataIndex < nCount )
1404 Sequence< PropertyValue > aViewData;
1405 OSL_VERIFY( xViewData->getByIndex( nViewDataIndex ) >>= aViewData );
1406 if ( aViewData.getLength() > 0 )
1407 m_pData->m_pViewShell->ReadUserDataSequence( aViewData, sal_True );
1410 catch (const Exception&)
1412 DBG_UNHANDLED_EXCEPTION();
1418 // invalidate slot corresponding to the view shell
1419 const sal_uInt16 nViewNo = m_pData->m_pViewShell->GetObjectShell()->GetFactory().GetViewNo_Impl( pViewFrame->GetCurViewId(), USHRT_MAX );
1420 DBG_ASSERT( nViewNo != USHRT_MAX, "view shell id not found" );
1421 if ( nViewNo != USHRT_MAX )
1422 pViewFrame->GetBindings().Invalidate( nViewNo + SID_VIEWSHELL0 );
1425 void SfxBaseController::ShowInfoBars( )
1427 if ( m_pData->m_pViewShell )
1429 // CMIS verifications
1430 Reference< document::XCmisDocument > xCmisDoc( m_pData->m_pViewShell->GetObjectShell()->GetModel(), uno::UNO_QUERY );
1431 if ( xCmisDoc.is( ) && xCmisDoc->canCheckOut( ) )
1433 beans::PropertyValues aCmisProperties = xCmisDoc->getCmisPropertiesValues( );
1435 if ( xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( ) )
1437 // Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
1438 bool bFoundCheckedout = false;
1439 sal_Bool bCheckedOut = sal_False;
1440 for ( sal_Int32 i = 0; i < aCmisProperties.getLength() && !bFoundCheckedout; ++i )
1442 if ( aCmisProperties[i].Name == "cmis:isVersionSeriesCheckedOut" )
1444 bFoundCheckedout = true;
1445 aCmisProperties[i].Value >>= bCheckedOut;
1449 if ( !bCheckedOut )
1451 // Get the Frame and show the InfoBar if not checked out
1452 SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame();
1453 std::vector< PushButton* > aButtons;
1454 PushButton* pBtn = new PushButton( &pViewFrame->GetWindow(), SfxResId( BT_CHECKOUT ) );
1455 pBtn->SetClickHdl( LINK( this, SfxBaseController, CheckOutHandler ) );
1456 aButtons.push_back( pBtn );
1457 pViewFrame->AppendInfoBar( "checkout", SfxResId( STR_NONCHECKEDOUT_DOCUMENT ), aButtons );
1464 IMPL_LINK_NOARG ( SfxBaseController, CheckOutHandler )
1466 if ( m_pData->m_pViewShell )
1467 m_pData->m_pViewShell->GetObjectShell()->CheckOut( );
1468 return 0;
1472 //=============================================================================
1473 Reference< frame::XTitle > SfxBaseController::impl_getTitleHelper ()
1475 SolarMutexGuard aGuard;
1477 if ( ! m_pData->m_xTitleHelper.is ())
1479 Reference< frame::XModel > xModel = getModel ();
1480 Reference< frame::XUntitledNumbers > xUntitledProvider(xModel , uno::UNO_QUERY );
1481 Reference< frame::XController > xThis (static_cast< frame::XController* >(this), uno::UNO_QUERY_THROW);
1483 ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(::comphelper::getProcessComponentContext());
1484 m_pData->m_xTitleHelper = Reference< frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pHelper), uno::UNO_QUERY_THROW);
1486 pHelper->setOwner (xThis );
1487 pHelper->connectWithUntitledNumbers (xUntitledProvider);
1490 return m_pData->m_xTitleHelper;
1493 //=============================================================================
1494 // frame::XTitle
1495 OUString SAL_CALL SfxBaseController::getTitle()
1496 throw (RuntimeException)
1498 return impl_getTitleHelper()->getTitle ();
1501 //=============================================================================
1502 // frame::XTitle
1503 void SAL_CALL SfxBaseController::setTitle(const OUString& sTitle)
1504 throw (RuntimeException)
1506 impl_getTitleHelper()->setTitle (sTitle);
1509 //=============================================================================
1510 // frame::XTitleChangeBroadcaster
1511 void SAL_CALL SfxBaseController::addTitleChangeListener(const Reference< frame::XTitleChangeListener >& xListener)
1512 throw (RuntimeException)
1514 Reference< frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), uno::UNO_QUERY);
1515 if (xBroadcaster.is ())
1516 xBroadcaster->addTitleChangeListener (xListener);
1519 //=============================================================================
1520 // frame::XTitleChangeBroadcaster
1521 void SAL_CALL SfxBaseController::removeTitleChangeListener(const Reference< frame::XTitleChangeListener >& xListener)
1522 throw (RuntimeException)
1524 Reference< frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), uno::UNO_QUERY);
1525 if (xBroadcaster.is ())
1526 xBroadcaster->removeTitleChangeListener (xListener);
1529 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */