1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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 <sfx2/event.hxx>
78 #include <sfx2/viewfac.hxx>
79 #include "sfxbasecontroller_internal.hxx"
81 #include <unordered_map>
83 #define TIMEOUT_START_RESCHEDULE 10L /* 10th s */
85 using namespace ::com::sun::star
;
86 using ::com::sun::star::uno::Reference
;
87 using ::com::sun::star::uno::RuntimeException
;
88 using ::com::sun::star::uno::UNO_QUERY_THROW
;
89 using ::com::sun::star::uno::UNO_SET_THROW
;
90 using ::com::sun::star::lang::DisposedException
;
91 using ::com::sun::star::awt::XWindow
;
92 using ::com::sun::star::frame::XController
;
93 using ::com::sun::star::frame::XDispatchProvider
;
94 using ::com::sun::star::document::XViewDataSupplier
;
95 using ::com::sun::star::container::XIndexAccess
;
96 using ::com::sun::star::beans::PropertyValue
;
97 using ::com::sun::star::uno::Sequence
;
98 using ::com::sun::star::uno::UNO_QUERY
;
99 using ::com::sun::star::uno::Exception
;
100 using ::com::sun::star::frame::XFrame
;
101 using ::com::sun::star::frame::XFrameActionListener
;
102 using ::com::sun::star::util::XCloseListener
;
103 using ::com::sun::star::task::XStatusIndicator
;
104 using ::com::sun::star::frame::XTitle
;
106 struct GroupIDToCommandGroup
109 sal_Int16 nCommandGroup
;
112 static bool bGroupIDMapInitialized
= false;
113 static const GroupIDToCommandGroup GroupIDCommandGroupMap
[] =
115 { GID_INTERN
, frame::CommandGroup::INTERNAL
},
116 { GID_APPLICATION
, frame::CommandGroup::APPLICATION
},
117 { GID_DOCUMENT
, frame::CommandGroup::DOCUMENT
},
118 { GID_VIEW
, frame::CommandGroup::VIEW
},
119 { GID_EDIT
, frame::CommandGroup::EDIT
},
120 { GID_MACRO
, frame::CommandGroup::MACRO
},
121 { GID_OPTIONS
, frame::CommandGroup::OPTIONS
},
122 { GID_MATH
, frame::CommandGroup::MATH
},
123 { GID_NAVIGATOR
, frame::CommandGroup::NAVIGATOR
},
124 { GID_INSERT
, frame::CommandGroup::INSERT
},
125 { GID_FORMAT
, frame::CommandGroup::FORMAT
},
126 { GID_TEMPLATE
, frame::CommandGroup::TEMPLATE
},
127 { GID_TEXT
, frame::CommandGroup::TEXT
},
128 { GID_FRAME
, frame::CommandGroup::FRAME
},
129 { GID_GRAPHIC
, frame::CommandGroup::GRAPHIC
},
130 { GID_TABLE
, frame::CommandGroup::TABLE
},
131 { GID_ENUMERATION
, frame::CommandGroup::ENUMERATION
},
132 { GID_DATA
, frame::CommandGroup::DATA
},
133 { GID_SPECIAL
, frame::CommandGroup::SPECIAL
},
134 { GID_IMAGE
, frame::CommandGroup::IMAGE
},
135 { GID_CHART
, frame::CommandGroup::CHART
},
136 { GID_EXPLORER
, frame::CommandGroup::EXPLORER
},
137 { GID_CONNECTOR
, frame::CommandGroup::CONNECTOR
},
138 { GID_MODIFY
, frame::CommandGroup::MODIFY
},
139 { GID_DRAWING
, frame::CommandGroup::DRAWING
},
140 { GID_CONTROLS
, frame::CommandGroup::CONTROLS
},
144 typedef std::unordered_map
< sal_Int16
, sal_Int16
> GroupHashMap
;
146 sal_Int16
MapGroupIDToCommandGroup( sal_Int16 nGroupID
)
148 static GroupHashMap mHashMap
;
150 if ( !bGroupIDMapInitialized
)
153 while ( GroupIDCommandGroupMap
[i
].nGroupID
!= 0 )
155 mHashMap
.insert( GroupHashMap::value_type(
156 GroupIDCommandGroupMap
[i
].nGroupID
,
157 GroupIDCommandGroupMap
[i
].nCommandGroup
));
160 bGroupIDMapInitialized
= true;
163 GroupHashMap::const_iterator pIter
= mHashMap
.find( nGroupID
);
164 if ( pIter
!= mHashMap
.end() )
165 return pIter
->second
;
167 return frame::CommandGroup::INTERNAL
;
170 sal_uInt32
Get10ThSec()
172 sal_uInt32 n10Ticks
= 10 * (sal_uInt32
)clock();
173 return n10Ticks
/ CLOCKS_PER_SEC
;
176 sal_Int32 m_nInReschedule
= 0; /// static counter for rescheduling
180 if ( m_nInReschedule
== 0 )
183 Application::Reschedule();
188 class SfxStatusIndicator
: public ::cppu::WeakImplHelper2
< task::XStatusIndicator
, lang::XEventListener
>
190 friend class SfxBaseController
;
191 Reference
< XController
> xOwner
;
192 Reference
< task::XStatusIndicator
> xProgress
;
193 SfxWorkWindow
* pWorkWindow
;
198 SfxStatusIndicator(SfxBaseController
* pController
, SfxWorkWindow
* pWork
)
199 : xOwner( pController
)
200 , pWorkWindow( pWork
)
206 Reference
< lang::XComponent
> xComponent(
207 (static_cast< ::cppu::OWeakObject
* >(pController
)), uno::UNO_QUERY
);
209 xComponent
->addEventListener(this);
213 virtual void SAL_CALL
start(const OUString
& aText
, sal_Int32 nRange
) throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
214 virtual void SAL_CALL
end() 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
;
219 virtual void SAL_CALL
disposing( const lang::EventObject
& Source
) throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
222 void SAL_CALL
SfxStatusIndicator::start(const OUString
& aText
, sal_Int32 nRange
) throw(RuntimeException
, std::exception
)
224 SolarMutexGuard aGuard
;
230 if ( !xProgress
.is() )
231 xProgress
= pWorkWindow
->GetStatusIndicator();
233 if ( xProgress
.is() )
234 xProgress
->start( aText
, nRange
);
236 _nStartTime
= Get10ThSec();
241 void SAL_CALL
SfxStatusIndicator::end() throw(RuntimeException
, std::exception
)
243 SolarMutexGuard aGuard
;
246 if ( !xProgress
.is() )
247 xProgress
= pWorkWindow
->GetStatusIndicator();
249 if ( xProgress
.is() )
256 void SAL_CALL
SfxStatusIndicator::setText(const OUString
& aText
) throw(RuntimeException
, std::exception
)
258 SolarMutexGuard aGuard
;
261 if ( !xProgress
.is() )
262 xProgress
= pWorkWindow
->GetStatusIndicator();
264 if ( xProgress
.is() )
265 xProgress
->setText( aText
);
271 void SAL_CALL
SfxStatusIndicator::setValue( sal_Int32 nValue
) throw(RuntimeException
, std::exception
)
273 SolarMutexGuard aGuard
;
278 if ( !xProgress
.is() )
279 xProgress
= pWorkWindow
->GetStatusIndicator();
281 if ( xProgress
.is() )
282 xProgress
->setValue( nValue
);
284 bool bReschedule
= (( Get10ThSec() - _nStartTime
) > TIMEOUT_START_RESCHEDULE
);
290 void SAL_CALL
SfxStatusIndicator::reset() throw(RuntimeException
, std::exception
)
292 SolarMutexGuard aGuard
;
295 if ( !xProgress
.is() )
296 xProgress
= pWorkWindow
->GetStatusIndicator();
298 if ( xProgress
.is() )
305 void SAL_CALL
SfxStatusIndicator::disposing( const lang::EventObject
& /*Source*/ ) throw(RuntimeException
, std::exception
)
307 SolarMutexGuard aGuard
;
313 // declaration IMPL_SfxBaseController_ListenerHelper
316 class IMPL_SfxBaseController_ListenerHelper
: public ::cppu::WeakImplHelper1
< frame::XFrameActionListener
>
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
;
326 SfxBaseController
* m_pController
;
328 } ; // class IMPL_SfxBaseController_ListenerContainer
330 class IMPL_SfxBaseController_CloseListenerHelper
: public ::cppu::WeakImplHelper1
< util::XCloseListener
>
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
;
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
, std::exception
)
359 void SAL_CALL
IMPL_SfxBaseController_CloseListenerHelper::queryClosing( const lang::EventObject
& aEvent
, sal_Bool bDeliverOwnership
)
360 throw (RuntimeException
, util::CloseVetoException
, std::exception
)
362 SolarMutexGuard aGuard
;
363 SfxViewShell
* pShell
= m_pController
->GetViewShell_Impl();
366 bool bCanClose
= pShell
->PrepareClose( false );
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
);
374 pShell
->TakeOwnership_Impl();
376 pShell
->TakeFrameOwnership_Impl();
379 throw util::CloseVetoException("Controller disagree ...",static_cast< ::cppu::OWeakObject
*>(this));
384 void SAL_CALL
IMPL_SfxBaseController_CloseListenerHelper::notifyClosing( const lang::EventObject
& /*aEvent*/ ) throw (RuntimeException
, std::exception
)
389 // declaration IMPL_SfxBaseController_DataContainer
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
;
404 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 ( false )
419 , m_bSuspendState ( false )
423 } ; // struct IMPL_SfxBaseController_DataContainer
426 // IMPL_SfxBaseController_ListenerHelper constructor
429 IMPL_SfxBaseController_ListenerHelper::IMPL_SfxBaseController_ListenerHelper( SfxBaseController
* pController
)
430 : m_pController ( pController
)
435 // IMPL_SfxBaseController_ListenerHelper destructor
438 IMPL_SfxBaseController_ListenerHelper::~IMPL_SfxBaseController_ListenerHelper()
442 void SAL_CALL
IMPL_SfxBaseController_ListenerHelper::frameAction( const frame::FrameActionEvent
& aEvent
) throw( RuntimeException
, std::exception
)
444 SolarMutexGuard aGuard
;
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( false );
456 else if ( aEvent
.Action
== frame::FrameAction_CONTEXT_CHANGED
)
458 m_pController
->GetViewShell_Impl()->GetViewFrame()->GetBindings().ContextChanged_Impl();
464 // IMPL_SfxBaseController_ListenerHelper -> XEventListener
467 void SAL_CALL
IMPL_SfxBaseController_ListenerHelper::disposing( const lang::EventObject
& /*aEvent*/ ) throw( RuntimeException
, std::exception
)
469 SolarMutexGuard aGuard
;
470 if ( m_pController
&& m_pController
->getFrame().is() )
471 m_pController
->getFrame()->removeFrameActionListener( this ) ;
474 SfxBaseController::SfxBaseController( SfxViewShell
* pViewShell
)
475 : m_pData ( new IMPL_SfxBaseController_DataContainer( m_aMutex
, pViewShell
, this ))
477 m_pData
->m_pViewShell
->SetController( this );
481 // SfxBaseController -> destructor
484 SfxBaseController::~SfxBaseController()
490 // SfxBaseController -> XController2
493 Reference
< XWindow
> SAL_CALL
SfxBaseController::getComponentWindow() throw (RuntimeException
, std::exception
)
495 SolarMutexGuard aGuard
;
496 if ( !m_pData
->m_pViewShell
)
497 throw DisposedException();
499 return Reference
< XWindow
>( GetViewFrame_Impl().GetFrame().GetWindow().GetComponentInterface(), UNO_QUERY_THROW
);
502 OUString SAL_CALL
SfxBaseController::getViewControllerName() throw (RuntimeException
, std::exception
)
504 SolarMutexGuard aGuard
;
505 if ( !m_pData
->m_pViewShell
|| !m_pData
->m_pViewShell
->GetObjectShell() )
506 throw DisposedException();
508 const SfxObjectFactory
& rDocFac( m_pData
->m_pViewShell
->GetObjectShell()->GetFactory() );
509 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!" );
513 if ( nViewNo
< rDocFac
.GetViewFactoryCount() )
514 sViewName
= rDocFac
.GetViewFactory( nViewNo
).GetAPIViewName();
519 Sequence
< PropertyValue
> SAL_CALL
SfxBaseController::getCreationArguments() throw (RuntimeException
, std::exception
)
521 SolarMutexGuard aGuard
;
522 if ( !m_pData
->m_pViewShell
|| !m_pData
->m_pViewShell
->GetObjectShell() )
523 throw DisposedException();
525 return m_pData
->m_aCreationArgs
;
528 void SfxBaseController::SetCreationArguments_Impl( const Sequence
< PropertyValue
>& i_rCreationArgs
)
530 OSL_ENSURE( m_pData
->m_aCreationArgs
.getLength() == 0, "SfxBaseController::SetCreationArguments_Impl: not intended to be called twice!" );
531 m_pData
->m_aCreationArgs
= i_rCreationArgs
;
534 SfxViewFrame
& SfxBaseController::GetViewFrame_Impl() const
536 ENSURE_OR_THROW( m_pData
->m_pViewShell
, "not to be called without a view shell" );
537 SfxViewFrame
* pActFrame
= m_pData
->m_pViewShell
->GetFrame();
538 ENSURE_OR_THROW( pActFrame
, "a view shell without a view frame is pretty pathological" );
543 // SfxBaseController -> XController2 -> XController
546 void SAL_CALL
SfxBaseController::attachFrame( const Reference
< frame::XFrame
>& xFrame
) throw( RuntimeException
, std::exception
)
548 Reference
< frame::XFrame
> xTemp( getFrame() ) ;
550 SolarMutexGuard aGuard
;
553 xTemp
->removeFrameActionListener( m_pData
->m_xListener
) ;
554 Reference
< util::XCloseBroadcaster
> xCloseable( xTemp
, uno::UNO_QUERY
);
555 if ( xCloseable
.is() )
556 xCloseable
->removeCloseListener( m_pData
->m_xCloseListener
);
559 m_pData
->m_xFrame
= xFrame
;
563 xFrame
->addFrameActionListener( m_pData
->m_xListener
) ;
564 Reference
< util::XCloseBroadcaster
> xCloseable( xFrame
, uno::UNO_QUERY
);
565 if ( xCloseable
.is() )
566 xCloseable
->addCloseListener( m_pData
->m_xCloseListener
);
568 if ( m_pData
->m_pViewShell
)
570 ConnectSfxFrame_Impl( E_CONNECT
);
573 // attaching the frame to the controller is the last step in the creation of a new view, so notify this
574 SfxViewEventHint
aHint( SFX_EVENT_VIEWCREATED
, GlobalEventConfig::GetEventName( GlobalEventId::VIEWCREATED
), m_pData
->m_pViewShell
->GetObjectShell(), Reference
< frame::XController2
>( this ) );
575 SfxGetpApp()->NotifyEvent( aHint
);
581 // SfxBaseController -> XController
584 sal_Bool SAL_CALL
SfxBaseController::attachModel( const Reference
< frame::XModel
>& xModel
) throw( RuntimeException
, std::exception
)
586 if ( m_pData
->m_pViewShell
&& xModel
.is() && xModel
!= m_pData
->m_pViewShell
->GetObjectShell()->GetModel() )
588 // don't allow to reattach a model!
589 OSL_FAIL("Can't reattach model!");
593 Reference
< util::XCloseBroadcaster
> xCloseable( xModel
, uno::UNO_QUERY
);
594 if ( xCloseable
.is() )
595 xCloseable
->addCloseListener( m_pData
->m_xCloseListener
);
600 // SfxBaseController -> XController
603 sal_Bool SAL_CALL
SfxBaseController::suspend( sal_Bool bSuspend
) throw( RuntimeException
, std::exception
)
605 SolarMutexGuard aGuard
;
607 // ignore dublicate calls, which doesn't change anything real
608 if (bool(bSuspend
) == m_pData
->m_bSuspendState
)
611 if ( bSuspend
== sal_True
)
613 if ( !m_pData
->m_pViewShell
)
615 m_pData
->m_bSuspendState
= true;
619 if ( !m_pData
->m_pViewShell
->PrepareClose() )
622 if ( getFrame().is() )
623 getFrame()->removeFrameActionListener( m_pData
->m_xListener
) ;
624 SfxViewFrame
* pActFrame
= m_pData
->m_pViewShell
->GetFrame() ;
626 // More Views on the same document?
627 SfxObjectShell
* pDocShell
= m_pData
->m_pViewShell
->GetObjectShell() ;
628 bool bOther
= false ;
630 for ( const SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( pDocShell
); !bOther
&& pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, pDocShell
) )
631 bOther
= (pFrame
!= pActFrame
);
633 bool bRet
= bOther
|| pDocShell
->PrepareClose();
636 ConnectSfxFrame_Impl( E_DISCONNECT
);
637 m_pData
->m_bSuspendState
= true;
644 if ( getFrame().is() )
645 getFrame()->addFrameActionListener( m_pData
->m_xListener
) ;
647 if ( m_pData
->m_pViewShell
)
649 ConnectSfxFrame_Impl( E_RECONNECT
);
652 m_pData
->m_bSuspendState
= false;
658 // SfxBaseController -> XController
661 uno::Any
SfxBaseController::getViewData() throw( RuntimeException
, std::exception
)
665 SolarMutexGuard aGuard
;
666 if ( m_pData
->m_pViewShell
)
668 m_pData
->m_pViewShell
->WriteUserData( sData
) ;
676 // SfxBaseController -> XController
679 void SAL_CALL
SfxBaseController::restoreViewData( const uno::Any
& aValue
) throw( RuntimeException
, std::exception
)
681 SolarMutexGuard aGuard
;
682 if ( m_pData
->m_pViewShell
)
686 m_pData
->m_pViewShell
->ReadUserData( sData
) ;
691 // SfxBaseController -> XController
694 Reference
< frame::XFrame
> SAL_CALL
SfxBaseController::getFrame() throw( RuntimeException
, std::exception
)
696 SolarMutexGuard aGuard
;
697 return m_pData
->m_xFrame
;
701 // SfxBaseController -> XController
704 Reference
< frame::XModel
> SAL_CALL
SfxBaseController::getModel() throw( RuntimeException
, std::exception
)
706 SolarMutexGuard aGuard
;
707 return m_pData
->m_pViewShell
? m_pData
->m_pViewShell
->GetObjectShell()->GetModel() : Reference
< frame::XModel
> () ;
711 // SfxBaseController -> XDispatchProvider
714 Reference
< frame::XDispatch
> SAL_CALL
SfxBaseController::queryDispatch( const util::URL
& aURL
,
715 const OUString
& sTargetFrameName
,
716 sal_Int32 eSearchFlags
) throw( RuntimeException
, std::exception
)
718 SolarMutexGuard aGuard
;
719 Reference
< frame::XDispatch
> xDisp
;
720 if ( m_pData
->m_pViewShell
)
722 SfxViewFrame
* pAct
= m_pData
->m_pViewShell
->GetViewFrame() ;
723 if ( !m_pData
->m_bDisposing
)
725 if ( sTargetFrameName
== "_beamer" )
727 SfxViewFrame
*pFrame
= m_pData
->m_pViewShell
->GetViewFrame();
728 if ( eSearchFlags
& ( frame::FrameSearchFlag::CREATE
))
729 pFrame
->SetChildWindow( SID_BROWSER
, true );
730 SfxChildWindow
* pChildWin
= pFrame
->GetChildWindow( SID_BROWSER
);
731 Reference
< frame::XFrame
> xFrame
;
733 xFrame
= ( pChildWin
->GetFrame() );
735 xFrame
->setName( sTargetFrameName
);
737 Reference
< XDispatchProvider
> xProv( xFrame
, uno::UNO_QUERY
);
739 return xProv
->queryDispatch( aURL
, sTargetFrameName
, frame::FrameSearchFlag::SELF
);
742 if ( aURL
.Protocol
== ".uno:" )
744 OUString aMasterCommand
= SfxOfficeDispatch::GetMasterUnoCommand( aURL
);
745 bool bMasterCommand( !aMasterCommand
.isEmpty() );
747 pAct
= m_pData
->m_pViewShell
->GetViewFrame() ;
748 SfxSlotPool
& rSlotPool
= SfxSlotPool::GetSlotPool( pAct
);
750 const SfxSlot
* pSlot( 0 );
751 if ( bMasterCommand
)
752 pSlot
= rSlotPool
.GetUnoSlot( aMasterCommand
);
754 pSlot
= rSlotPool
.GetUnoSlot( aURL
.Path
);
755 if ( pSlot
&& ( !pAct
->GetFrame().IsInPlace() || !pSlot
->IsMode( SfxSlotMode::CONTAINER
) ) )
756 return pAct
->GetBindings().GetDispatch( pSlot
, aURL
, bMasterCommand
);
759 // try to find parent SfxViewFrame
760 Reference
< frame::XFrame
> xParentFrame
;
761 Reference
< frame::XFrame
> xOwnFrame
= pAct
->GetFrame().GetFrameInterface();
762 if ( xOwnFrame
.is() )
763 xParentFrame
= Reference
< frame::XFrame
>( xOwnFrame
->getCreator(), uno::UNO_QUERY
);
765 if ( xParentFrame
.is() )
767 // TODO/LATER: in future probably SfxViewFrame hirarchy should be the same as XFrame hirarchy
768 // SfxViewFrame* pParentFrame = pAct->GetParentViewFrame();
770 // search the related SfxViewFrame
771 SfxViewFrame
* pParentFrame
= NULL
;
772 for ( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst();
774 pFrame
= SfxViewFrame::GetNext( *pFrame
) )
776 if ( pFrame
->GetFrame().GetFrameInterface() == xParentFrame
)
778 pParentFrame
= pFrame
;
785 SfxSlotPool
& rFrameSlotPool
= SfxSlotPool::GetSlotPool( pParentFrame
);
786 const SfxSlot
* pSlot2( 0 );
787 if ( bMasterCommand
)
788 pSlot2
= rFrameSlotPool
.GetUnoSlot( aMasterCommand
);
790 pSlot2
= rFrameSlotPool
.GetUnoSlot( aURL
.Path
);
793 return pParentFrame
->GetBindings().GetDispatch( pSlot2
, aURL
, bMasterCommand
);
798 else if ( aURL
.Protocol
== "slot:" )
800 sal_uInt16 nId
= (sal_uInt16
) aURL
.Path
.toInt32();
802 pAct
= m_pData
->m_pViewShell
->GetViewFrame() ;
803 if (nId
>= SID_VERB_START
&& nId
<= SID_VERB_END
)
805 const SfxSlot
* pSlot
= m_pData
->m_pViewShell
->GetVerbSlot_Impl(nId
);
807 return pAct
->GetBindings().GetDispatch( pSlot
, aURL
, false );
810 SfxSlotPool
& rSlotPool
= SfxSlotPool::GetSlotPool( pAct
);
811 const SfxSlot
* pSlot
= rSlotPool
.GetSlot( nId
);
812 if ( pSlot
&& ( !pAct
->GetFrame().IsInPlace() || !pSlot
->IsMode( SfxSlotMode::CONTAINER
) ) )
813 return pAct
->GetBindings().GetDispatch( pSlot
, aURL
, false );
816 // try to find parent SfxViewFrame
817 Reference
< frame::XFrame
> xParentFrame
;
818 Reference
< frame::XFrame
> xOwnFrame
= pAct
->GetFrame().GetFrameInterface();
819 if ( xOwnFrame
.is() )
820 xParentFrame
= Reference
< frame::XFrame
>( xOwnFrame
->getCreator(), uno::UNO_QUERY
);
822 if ( xParentFrame
.is() )
824 // TODO/LATER: in future probably SfxViewFrame hirarchy should be the same as XFrame hirarchy
825 // SfxViewFrame* pParentFrame = pAct->GetParentViewFrame();
827 // search the related SfxViewFrame
828 SfxViewFrame
* pParentFrame
= NULL
;
829 for ( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst();
831 pFrame
= SfxViewFrame::GetNext( *pFrame
) )
833 if ( pFrame
->GetFrame().GetFrameInterface() == xParentFrame
)
835 pParentFrame
= pFrame
;
842 SfxSlotPool
& rSlotPool2
= SfxSlotPool::GetSlotPool( pParentFrame
);
843 const SfxSlot
* pSlot2
= rSlotPool2
.GetUnoSlot( aURL
.Path
);
845 return pParentFrame
->GetBindings().GetDispatch( pSlot2
, aURL
, false );
850 else if( sTargetFrameName
== "_self" || sTargetFrameName
.isEmpty() )
852 // check for already loaded URL ... but with additional jumpmark!
853 Reference
< frame::XModel
> xModel
= getModel();
854 if( xModel
.is() && !aURL
.Mark
.isEmpty() )
856 SfxSlotPool
& rSlotPool
= SfxSlotPool::GetSlotPool( pAct
);
857 const SfxSlot
* pSlot
= rSlotPool
.GetSlot( SID_JUMPTOMARK
);
858 if( !aURL
.Main
.isEmpty() && aURL
.Main
== xModel
->getURL() && pSlot
)
859 return Reference
< frame::XDispatch
>( new SfxOfficeDispatch( pAct
->GetBindings(), pAct
->GetDispatcher(), pSlot
, aURL
) );
869 // SfxBaseController -> XDispatchProvider
872 uno::Sequence
< Reference
< frame::XDispatch
> > SAL_CALL
SfxBaseController::queryDispatches( const uno::Sequence
< frame::DispatchDescriptor
>& seqDescripts
) throw( RuntimeException
, std::exception
)
874 // Create return list - which must have same size then the given descriptor
875 // It's not allowed to pack it!
876 sal_Int32 nCount
= seqDescripts
.getLength();
877 uno::Sequence
< Reference
< frame::XDispatch
> > lDispatcher( nCount
);
879 for( sal_Int32 i
=0; i
<nCount
; ++i
)
881 lDispatcher
[i
] = queryDispatch( seqDescripts
[i
].FeatureURL
,
882 seqDescripts
[i
].FrameName
,
883 seqDescripts
[i
].SearchFlags
);
890 // SfxBaseController -> XControllerBorder
893 frame::BorderWidths SAL_CALL
SfxBaseController::getBorder()
894 throw ( RuntimeException
, std::exception
)
896 frame::BorderWidths aResult
;
898 SolarMutexGuard aGuard
;
899 if ( m_pData
->m_pViewShell
)
901 SvBorder aBorder
= m_pData
->m_pViewShell
->GetBorderPixel();
902 aResult
.Left
= aBorder
.Left();
903 aResult
.Top
= aBorder
.Top();
904 aResult
.Right
= aBorder
.Right();
905 aResult
.Bottom
= aBorder
.Bottom();
911 void SAL_CALL
SfxBaseController::addBorderResizeListener( const Reference
< frame::XBorderResizeListener
>& xListener
)
912 throw ( RuntimeException
, std::exception
)
914 m_pData
->m_aListenerContainer
.addInterface( cppu::UnoType
<frame::XBorderResizeListener
>::get(),
918 void SAL_CALL
SfxBaseController::removeBorderResizeListener( const Reference
< frame::XBorderResizeListener
>& xListener
)
919 throw ( RuntimeException
, std::exception
)
921 m_pData
->m_aListenerContainer
.removeInterface( cppu::UnoType
<frame::XBorderResizeListener
>::get(),
925 awt::Rectangle SAL_CALL
SfxBaseController::queryBorderedArea( const awt::Rectangle
& aPreliminaryRectangle
)
926 throw ( RuntimeException
, std::exception
)
928 SolarMutexGuard aGuard
;
929 if ( m_pData
->m_pViewShell
)
931 Rectangle aTmpRect
= VCLRectangle( aPreliminaryRectangle
);
932 m_pData
->m_pViewShell
->QueryObjAreaPixel( aTmpRect
);
933 return AWTRectangle( aTmpRect
);
936 return aPreliminaryRectangle
;
939 void SfxBaseController::BorderWidthsChanged_Impl()
941 ::cppu::OInterfaceContainerHelper
* pContainer
= m_pData
->m_aListenerContainer
.getContainer(
942 cppu::UnoType
<frame::XBorderResizeListener
>::get());
945 frame::BorderWidths aBWidths
= getBorder();
946 Reference
< uno::XInterface
> xThis( static_cast< ::cppu::OWeakObject
* >(this), uno::UNO_QUERY
);
948 ::cppu::OInterfaceIteratorHelper
pIterator(*pContainer
);
949 while (pIterator
.hasMoreElements())
953 static_cast<frame::XBorderResizeListener
*>(pIterator
.next())->borderWidthsChanged( xThis
, aBWidths
);
955 catch (const RuntimeException
&)
964 // SfxBaseController -> XComponent
967 void SAL_CALL
SfxBaseController::dispose() throw( RuntimeException
, std::exception
)
969 SolarMutexGuard aGuard
;
970 Reference
< XController
> xTmp( this );
971 m_pData
->m_bDisposing
= true ;
973 lang::EventObject aEventObject
;
974 aEventObject
.Source
= *this ;
975 m_pData
->m_aListenerContainer
.disposeAndClear( aEventObject
) ;
977 if ( m_pData
->m_pController
&& m_pData
->m_pController
->getFrame().is() )
978 m_pData
->m_pController
->getFrame()->removeFrameActionListener( m_pData
->m_xListener
) ;
980 if ( m_pData
->m_pViewShell
)
982 SfxViewFrame
* pFrame
= m_pData
->m_pViewShell
->GetViewFrame() ;
983 if ( pFrame
&& pFrame
->GetViewShell() == m_pData
->m_pViewShell
)
984 pFrame
->GetFrame().SetIsClosing_Impl();
985 m_pData
->m_pViewShell
->DiscardClients_Impl();
986 m_pData
->m_pViewShell
->pImp
->m_bControllerSet
= false;
990 lang::EventObject aObject
;
991 aObject
.Source
= *this ;
993 SfxObjectShell
* pDoc
= pFrame
->GetObjectShell() ;
994 SfxViewFrame
*pView
= SfxViewFrame::GetFirst(pDoc
);
997 // if there is another ViewFrame or currently the ViewShell in my ViewFrame is switched (PagePreview)
998 if ( pView
!= pFrame
|| pView
->GetViewShell() != m_pData
->m_pViewShell
)
1000 pView
= SfxViewFrame::GetNext( *pView
, pDoc
);
1003 SfxGetpApp()->NotifyEvent( SfxViewEventHint(SFX_EVENT_CLOSEVIEW
, GlobalEventConfig::GetEventName( GlobalEventId::CLOSEVIEW
), pDoc
, Reference
< frame::XController2
>( this ) ) );
1005 SfxGetpApp()->NotifyEvent( SfxEventHint(SFX_EVENT_CLOSEDOC
, GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC
), pDoc
) );
1007 Reference
< frame::XModel
> xModel
= pDoc
->GetModel();
1008 Reference
< util::XCloseable
> xCloseable( xModel
, uno::UNO_QUERY
);
1011 xModel
->disconnectController( this );
1012 if ( xCloseable
.is() )
1013 xCloseable
->removeCloseListener( m_pData
->m_xCloseListener
);
1016 Reference
< frame::XFrame
> aXFrame
;
1017 attachFrame( aXFrame
);
1019 m_pData
->m_xListener
->disposing( aObject
);
1020 SfxViewShell
*pShell
= m_pData
->m_pViewShell
;
1021 m_pData
->m_pViewShell
= NULL
;
1022 if ( pFrame
->GetViewShell() == pShell
)
1024 // Enter registrations only allowed if we are the owner!
1025 if ( pFrame
->GetFrame().OwnsBindings_Impl() )
1026 pFrame
->GetBindings().ENTERREGISTRATIONS();
1027 pFrame
->GetFrame().SetFrameInterface_Impl( aXFrame
);
1028 pFrame
->GetFrame().DoClose_Impl();
1035 // SfxBaseController -> XComponent
1038 void SAL_CALL
SfxBaseController::addEventListener( const Reference
< lang::XEventListener
>& aListener
) throw( RuntimeException
, std::exception
)
1040 m_pData
->m_aListenerContainer
.addInterface( cppu::UnoType
<lang::XEventListener
>::get(), aListener
);
1044 // SfxBaseController -> XComponent
1047 void SAL_CALL
SfxBaseController::removeEventListener( const Reference
< lang::XEventListener
>& aListener
) throw( RuntimeException
, std::exception
)
1049 m_pData
->m_aListenerContainer
.removeInterface( cppu::UnoType
<lang::XEventListener
>::get(), aListener
);
1052 void SfxBaseController::ReleaseShell_Impl()
1054 SolarMutexGuard aGuard
;
1055 if ( m_pData
->m_pViewShell
)
1057 SfxObjectShell
* pDoc
= m_pData
->m_pViewShell
->GetObjectShell() ;
1058 Reference
< frame::XModel
> xModel
= pDoc
->GetModel();
1059 Reference
< util::XCloseable
> xCloseable( xModel
, uno::UNO_QUERY
);
1062 xModel
->disconnectController( this );
1063 if ( xCloseable
.is() )
1064 xCloseable
->removeCloseListener( m_pData
->m_xCloseListener
);
1066 m_pData
->m_pViewShell
= 0;
1068 Reference
< frame::XFrame
> aXFrame
;
1069 attachFrame( aXFrame
);
1073 SfxViewShell
* SfxBaseController::GetViewShell_Impl() const
1075 return m_pData
->m_pViewShell
;
1078 Reference
< task::XStatusIndicator
> SAL_CALL
SfxBaseController::getStatusIndicator( ) throw (RuntimeException
, std::exception
)
1080 SolarMutexGuard aGuard
;
1081 if ( m_pData
->m_pViewShell
&& !m_pData
->m_xIndicator
.is() )
1082 m_pData
->m_xIndicator
= new SfxStatusIndicator( this, m_pData
->m_pViewShell
->GetViewFrame()->GetFrame().GetWorkWindow_Impl() );
1083 return m_pData
->m_xIndicator
;
1086 void SAL_CALL
SfxBaseController::registerContextMenuInterceptor( const Reference
< ui::XContextMenuInterceptor
>& xInterceptor
) throw( RuntimeException
, std::exception
)
1089 m_pData
->m_aInterceptorContainer
.addInterface( xInterceptor
);
1091 SolarMutexGuard aGuard
;
1092 if ( m_pData
->m_pViewShell
)
1093 m_pData
->m_pViewShell
->AddContextMenuInterceptor_Impl( xInterceptor
);
1096 void SAL_CALL
SfxBaseController::releaseContextMenuInterceptor( const Reference
< ui::XContextMenuInterceptor
>& xInterceptor
) throw( RuntimeException
, std::exception
)
1099 m_pData
->m_aInterceptorContainer
.removeInterface( xInterceptor
);
1101 SolarMutexGuard aGuard
;
1102 if ( m_pData
->m_pViewShell
)
1103 m_pData
->m_pViewShell
->RemoveContextMenuInterceptor_Impl( xInterceptor
);
1106 void SAL_CALL
SfxBaseController::addKeyHandler( const Reference
< awt::XKeyHandler
>& xHandler
) throw (RuntimeException
, std::exception
)
1108 SolarMutexGuard aGuard
;
1109 m_pData
->m_aUserInputInterception
.addKeyHandler( xHandler
);
1112 void SAL_CALL
SfxBaseController::removeKeyHandler( const Reference
< awt::XKeyHandler
>& xHandler
) throw (RuntimeException
, std::exception
)
1114 SolarMutexGuard aGuard
;
1115 m_pData
->m_aUserInputInterception
.removeKeyHandler( xHandler
);
1118 void SAL_CALL
SfxBaseController::addMouseClickHandler( const Reference
< awt::XMouseClickHandler
>& xHandler
) throw (RuntimeException
, std::exception
)
1120 SolarMutexGuard aGuard
;
1121 m_pData
->m_aUserInputInterception
.addMouseClickHandler( xHandler
);
1124 void SAL_CALL
SfxBaseController::removeMouseClickHandler( const Reference
< awt::XMouseClickHandler
>& xHandler
) throw (RuntimeException
, std::exception
)
1126 SolarMutexGuard aGuard
;
1127 m_pData
->m_aUserInputInterception
.removeMouseClickHandler( xHandler
);
1130 uno::Sequence
< sal_Int16
> SAL_CALL
SfxBaseController::getSupportedCommandGroups()
1131 throw (RuntimeException
, std::exception
)
1133 SolarMutexGuard aGuard
;
1135 std::list
< sal_Int16
> aGroupList
;
1136 SfxViewFrame
* pViewFrame( m_pData
->m_pViewShell
->GetFrame() );
1137 SfxSlotPool
* pPool
= &SfxSlotPool::GetSlotPool( pViewFrame
);
1139 SfxSlotPool
* pSlotPool
= pPool
? pPool
: &SFX_SLOTPOOL();
1140 const SfxSlotMode
nMode( SfxSlotMode::TOOLBOXCONFIG
|SfxSlotMode::ACCELCONFIG
|SfxSlotMode::MENUCONFIG
);
1142 // Select Group ( Group 0 is internal )
1143 for ( sal_uInt16 i
=0; i
<pSlotPool
->GetGroupCount(); i
++ )
1145 pSlotPool
->SeekGroup( i
);
1146 const SfxSlot
* pSfxSlot
= pSlotPool
->FirstSlot();
1149 if ( pSfxSlot
->GetMode() & nMode
)
1151 sal_Int16 nCommandGroup
= MapGroupIDToCommandGroup( pSfxSlot
->GetGroupId() );
1152 aGroupList
.push_back( nCommandGroup
);
1155 pSfxSlot
= pSlotPool
->NextSlot();
1159 uno::Sequence
< sal_Int16
> aSeq
=
1160 comphelper::containerToSequence
< sal_Int16
>( aGroupList
);
1164 uno::Sequence
< frame::DispatchInformation
> SAL_CALL
SfxBaseController::getConfigurableDispatchInformation( sal_Int16 nCmdGroup
)
1165 throw (RuntimeException
, std::exception
)
1167 std::list
< frame::DispatchInformation
> aCmdList
;
1169 SolarMutexGuard aGuard
;
1170 if ( m_pData
->m_pViewShell
)
1172 const SfxSlotMode
nMode( SfxSlotMode::TOOLBOXCONFIG
|SfxSlotMode::ACCELCONFIG
|SfxSlotMode::MENUCONFIG
);
1174 SfxViewFrame
* pViewFrame( m_pData
->m_pViewShell
->GetFrame() );
1175 SfxSlotPool
* pPool( &SfxSlotPool::GetSlotPool( pViewFrame
));
1176 OUString
aCmdPrefix( ".uno:" );
1178 SfxSlotPool
* pSlotPool
= pPool
? pPool
: &SFX_SLOTPOOL();
1179 for ( sal_uInt16 i
=0; i
<pSlotPool
->GetGroupCount(); i
++ )
1181 pSlotPool
->SeekGroup( i
);
1182 const SfxSlot
* pSfxSlot
= pSlotPool
->FirstSlot();
1185 sal_Int16 nCommandGroup
= MapGroupIDToCommandGroup( pSfxSlot
->GetGroupId() );
1186 if ( nCommandGroup
== nCmdGroup
)
1190 if ( pSfxSlot
->GetMode() & nMode
)
1192 frame::DispatchInformation aCmdInfo
;
1193 OUStringBuffer
aBuf( aCmdPrefix
);
1194 aBuf
.appendAscii( pSfxSlot
->GetUnoName() );
1195 aCmdInfo
.Command
= aBuf
.makeStringAndClear();
1196 aCmdInfo
.GroupId
= nCommandGroup
;
1197 aCmdList
.push_back( aCmdInfo
);
1199 pSfxSlot
= pSlotPool
->NextSlot();
1206 uno::Sequence
< frame::DispatchInformation
> aSeq
=
1207 comphelper::containerToSequence
< frame::DispatchInformation
, std::list
< frame::DispatchInformation
> >( aCmdList
);
1212 bool SfxBaseController::HandleEvent_Impl( NotifyEvent
& rEvent
)
1214 return m_pData
->m_aUserInputInterception
.handleNotifyEvent( rEvent
);
1217 bool SfxBaseController::HasKeyListeners_Impl()
1219 return m_pData
->m_aUserInputInterception
.hasKeyHandlers();
1222 bool SfxBaseController::HasMouseClickListeners_Impl()
1224 return m_pData
->m_aUserInputInterception
.hasMouseClickListeners();
1227 void SfxBaseController::ConnectSfxFrame_Impl( const ConnectSfxFrame i_eConnect
)
1229 ENSURE_OR_THROW( m_pData
->m_pViewShell
, "not to be called without a view shell" );
1230 SfxViewFrame
* pViewFrame
= m_pData
->m_pViewShell
->GetFrame();
1231 ENSURE_OR_THROW( pViewFrame
, "a view shell without a view frame is pretty pathological" );
1233 const bool bConnect
= ( i_eConnect
!= E_DISCONNECT
);
1235 // disable window and dispatcher
1236 pViewFrame
->Enable( bConnect
);
1237 pViewFrame
->GetDispatcher()->Lock( !bConnect
);
1241 if ( i_eConnect
== E_CONNECT
)
1243 if ( ( m_pData
->m_pViewShell
->GetObjectShell() != NULL
)
1244 && ( m_pData
->m_pViewShell
->GetObjectShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1247 SfxViewFrame
* pViewFrm
= m_pData
->m_pViewShell
->GetViewFrame();
1248 if ( !pViewFrm
->GetFrame().IsInPlace() )
1250 // for outplace embedded objects, we want the layout manager to keep the content window
1251 // size constant, if possible
1254 Reference
< beans::XPropertySet
> xFrameProps( m_pData
->m_xFrame
, uno::UNO_QUERY_THROW
);
1255 Reference
< beans::XPropertySet
> xLayouterProps(
1256 xFrameProps
->getPropertyValue("LayoutManager"), uno::UNO_QUERY_THROW
);
1257 xLayouterProps
->setPropertyValue("PreserveContentSize", uno::makeAny( sal_True
) );
1259 catch (const uno::Exception
&)
1261 DBG_UNHANDLED_EXCEPTION();
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 if ( i_eConnect
!= E_RECONNECT
)
1271 pViewFrame
->GetDispatcher()->Push( *m_pData
->m_pViewShell
);
1272 if ( m_pData
->m_pViewShell
->GetSubShell() )
1273 pViewFrame
->GetDispatcher()->Push( *m_pData
->m_pViewShell
->GetSubShell() );
1274 m_pData
->m_pViewShell
->PushSubShells_Impl();
1275 pViewFrame
->GetDispatcher()->Flush();
1278 vcl::Window
* pEditWin
= m_pData
->m_pViewShell
->GetWindow();
1279 if ( pEditWin
&& m_pData
->m_pViewShell
->IsShowView_Impl() )
1282 if ( SfxViewFrame::Current() == pViewFrame
)
1283 pViewFrame
->GetDispatcher()->Update_Impl( true );
1285 vcl::Window
* pFrameWin
= &pViewFrame
->GetWindow();
1286 if ( pFrameWin
!= &pViewFrame
->GetFrame().GetWindow() )
1289 if ( i_eConnect
== E_CONNECT
)
1291 ::comphelper::NamedValueCollection
aDocumentArgs( getModel()->getArgs() );
1293 const sal_Int16 nPluginMode
= aDocumentArgs
.getOrDefault( "PluginMode", sal_Int16( 0 ) );
1294 const bool bHasPluginMode
= ( nPluginMode
!= 0 );
1296 SfxFrame
& rFrame
= pViewFrame
->GetFrame();
1297 SfxObjectShell
& rDoc
= *m_pData
->m_pViewShell
->GetObjectShell();
1298 if ( !rFrame
.IsMarkedHidden_Impl() )
1300 if ( rDoc
.IsHelpDocument() || ( nPluginMode
== 2 ) )
1301 pViewFrame
->GetDispatcher()->HideUI( true );
1303 pViewFrame
->GetDispatcher()->HideUI( false );
1305 if ( rFrame
.IsInPlace() )
1306 pViewFrame
->LockAdjustPosSizePixel();
1308 if ( nPluginMode
== 3 )
1309 rFrame
.GetWorkWindow_Impl()->SetInternalDockingAllowed( false );
1311 if ( !rFrame
.IsInPlace() )
1312 pViewFrame
->GetDispatcher()->Update_Impl();
1314 rFrame
.GetWindow().Show();
1315 if ( !rFrame
.IsInPlace() || ( nPluginMode
== 3 ) )
1316 pViewFrame
->MakeActive_Impl( rFrame
.GetFrameInterface()->isActive() );
1318 if ( rFrame
.IsInPlace() )
1320 pViewFrame
->UnlockAdjustPosSizePixel();
1321 // force resize for OLE server to fix layout problems of writer and math
1323 if ( nPluginMode
== 3 )
1324 pViewFrame
->Resize( true );
1329 DBG_ASSERT( !rFrame
.IsInPlace() && !bHasPluginMode
, "Special modes not compatible with hidden mode!" );
1330 rFrame
.GetWindow().Show();
1333 // UpdateTitle now, hidden TopFrames have otherwise no Name!
1334 pViewFrame
->UpdateTitle();
1336 if ( !rFrame
.IsInPlace() )
1337 pViewFrame
->Resize( true );
1339 // if there's a JumpMark given, then, well, jump to it
1340 ::comphelper::NamedValueCollection
aViewArgs( getCreationArguments() );
1341 const OUString sJumpMark
= aViewArgs
.getOrDefault( "JumpMark", OUString() );
1342 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 if ( !sJumpMark
.isEmpty() )
1350 m_pData
->m_pViewShell
->JumpToMark( sJumpMark
);
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 if ( !bHasPluginMode
&& !bHasJumpMark
)
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 buried here deep within the controller's
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
1371 Reference
< XViewDataSupplier
> xViewDataSupplier( getModel(), UNO_QUERY_THROW
);
1372 Reference
< XIndexAccess
> xViewData( xViewDataSupplier
->getViewData() );
1374 // find the view data item whose ViewId matches the ID of the view we're just connecting to
1375 const SfxObjectFactory
& rDocFactory( rDoc
.GetFactory() );
1376 const sal_Int32 nCount
= xViewData
.is() ? xViewData
->getCount() : 0;
1377 sal_Int32 nViewDataIndex
= 0;
1378 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
1380 const ::comphelper::NamedValueCollection
aViewData( xViewData
->getByIndex(i
) );
1381 OUString
sViewId( aViewData
.getOrDefault( "ViewId", OUString() ) );
1382 if ( sViewId
.isEmpty() )
1385 const SfxViewFactory
* pViewFactory
= rDocFactory
.GetViewFactoryByViewName( sViewId
);
1386 if ( pViewFactory
== NULL
)
1389 if ( pViewFactory
->GetOrdinal() == pViewFrame
->GetCurViewId() )
1395 if ( nViewDataIndex
< nCount
)
1397 Sequence
< PropertyValue
> aViewData
;
1398 OSL_VERIFY( xViewData
->getByIndex( nViewDataIndex
) >>= aViewData
);
1399 if ( aViewData
.getLength() > 0 )
1400 m_pData
->m_pViewShell
->ReadUserDataSequence( aViewData
, true );
1403 catch (const Exception
&)
1405 DBG_UNHANDLED_EXCEPTION();
1411 // invalidate slot corresponding to the view shell
1412 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 if ( nViewNo
!= USHRT_MAX
)
1415 pViewFrame
->GetBindings().Invalidate( nViewNo
+ SID_VIEWSHELL0
);
1418 void SfxBaseController::ShowInfoBars( )
1420 if ( m_pData
->m_pViewShell
)
1422 // CMIS verifications
1423 Reference
< document::XCmisDocument
> xCmisDoc( m_pData
->m_pViewShell
->GetObjectShell()->GetModel(), uno::UNO_QUERY
);
1424 if ( xCmisDoc
.is( ) && xCmisDoc
->canCheckOut( ) )
1426 uno::Sequence
< document::CmisProperty
> aCmisProperties
= xCmisDoc
->getCmisProperties( );
1428 if ( xCmisDoc
->isVersionable( ) && aCmisProperties
.hasElements( ) )
1430 // Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
1431 // and find if it is a Google Drive file.
1432 bool bIsGoogleFile
= false;
1433 bool bCheckedOut
= false;
1434 for ( sal_Int32 i
= 0; i
< aCmisProperties
.getLength(); ++i
)
1436 if ( aCmisProperties
[i
].Id
== "cmis:isVersionSeriesCheckedOut" ) {
1437 uno::Sequence
< sal_Bool
> bTmp
;
1438 aCmisProperties
[i
].Value
>>= bTmp
;
1439 bCheckedOut
= bTmp
[0];
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 if ( aCmisProperties
[i
].Name
== "title" )
1444 bIsGoogleFile
= true;
1447 if ( !bCheckedOut
&& !bIsGoogleFile
)
1449 // Get the Frame and show the InfoBar if not checked out
1450 SfxViewFrame
* pViewFrame
= m_pData
->m_pViewShell
->GetFrame();
1451 SfxInfoBarWindow
* pInfoBar
= pViewFrame
->AppendInfoBar( "checkout", SfxResId( STR_NONCHECKEDOUT_DOCUMENT
) );
1454 VclPtrInstance
<PushButton
> pBtn( &pViewFrame
->GetWindow(), SfxResId( BT_CHECKOUT
) );
1455 pBtn
->SetClickHdl( LINK( this, SfxBaseController
, CheckOutHandler
) );
1456 pInfoBar
->addButton(pBtn
);
1464 IMPL_LINK_NOARG ( SfxBaseController
, CheckOutHandler
)
1466 if ( m_pData
->m_pViewShell
)
1467 m_pData
->m_pViewShell
->GetObjectShell()->CheckOut( );
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
;
1495 OUString SAL_CALL
SfxBaseController::getTitle()
1496 throw (RuntimeException
, std::exception
)
1498 return impl_getTitleHelper()->getTitle ();
1503 void SAL_CALL
SfxBaseController::setTitle(const OUString
& sTitle
)
1504 throw (RuntimeException
, std::exception
)
1506 impl_getTitleHelper()->setTitle (sTitle
);
1510 // frame::XTitleChangeBroadcaster
1511 void SAL_CALL
SfxBaseController::addTitleChangeListener(const Reference
< frame::XTitleChangeListener
>& xListener
)
1512 throw (RuntimeException
, std::exception
)
1514 Reference
< frame::XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper(), uno::UNO_QUERY
);
1515 if (xBroadcaster
.is ())
1516 xBroadcaster
->addTitleChangeListener (xListener
);
1520 // frame::XTitleChangeBroadcaster
1521 void SAL_CALL
SfxBaseController::removeTitleChangeListener(const Reference
< frame::XTitleChangeListener
>& xListener
)
1522 throw (RuntimeException
, std::exception
)
1524 Reference
< frame::XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper(), uno::UNO_QUERY
);
1525 if (xBroadcaster
.is ())
1526 xBroadcaster
->removeTitleChangeListener (xListener
);
1529 void SfxBaseController::initialize( const css::uno::Sequence
< css::uno::Any
>& /*aArguments*/ ) throw (css::uno::RuntimeException
, std::exception
)
1533 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */