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 <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
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
},
146 typedef boost::unordered_map
< sal_Int16
, sal_Int16
> GroupHashMap
;
149 sal_Int16
MapGroupIDToCommandGroup( sal_Int16 nGroupID
)
151 static GroupHashMap mHashMap
;
153 if ( !bGroupIDMapInitialized
)
156 while ( GroupIDCommandGroupMap
[i
].nGroupID
!= 0 )
158 mHashMap
.insert( GroupHashMap::value_type(
159 GroupIDCommandGroupMap
[i
].nGroupID
,
160 GroupIDCommandGroupMap
[i
].nCommandGroup
));
163 bGroupIDMapInitialized
= sal_True
;
166 GroupHashMap::const_iterator pIter
= mHashMap
.find( nGroupID
);
167 if ( pIter
!= mHashMap
.end() )
168 return pIter
->second
;
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
183 if ( m_nInReschedule
== 0 )
186 Application::Reschedule();
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
;
201 SfxStatusIndicator(SfxBaseController
* pController
, SfxWorkWindow
* pWork
)
202 : xOwner( pController
)
203 , 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
);
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
;
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(void) throw(RuntimeException
)
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
)
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
)
273 SolarMutexGuard aGuard
;
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
);
290 void SAL_CALL
SfxStatusIndicator::reset() throw(RuntimeException
)
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
)
307 SolarMutexGuard aGuard
;
312 //________________________________________________________________________________________________________
313 // declaration IMPL_SfxBaseController_ListenerHelper
314 //________________________________________________________________________________________________________
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
) ;
322 virtual void SAL_CALL
disposing( const lang::EventObject
& aEvent
) throw (RuntimeException
) ;
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
) ;
337 virtual void SAL_CALL
notifyClosing( const lang::EventObject
& aEvent
) throw (RuntimeException
) ;
338 virtual void SAL_CALL
disposing( const lang::EventObject
& aEvent
) throw (RuntimeException
) ;
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
);
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(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
;
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
);
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!" );
519 if ( nViewNo
< rDocFac
.GetViewFactoryCount() )
520 sViewName
= rDocFac
.GetViewFactory( nViewNo
).GetAPIViewName();
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" );
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
;
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
;
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
);
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!");
599 Reference
< util::XCloseBroadcaster
> xCloseable( xModel
, uno::UNO_QUERY
);
600 if ( xCloseable
.is() )
601 xCloseable
->addCloseListener( m_pData
->m_xCloseListener
);
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
)
617 if ( bSuspend
== sal_True
)
619 if ( !m_pData
->m_pViewShell
)
621 m_pData
->m_bSuspendState
= sal_True
;
625 if ( !m_pData
->m_pViewShell
->PrepareClose() )
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();
642 ConnectSfxFrame_Impl( E_DISCONNECT
);
643 m_pData
->m_bSuspendState
= sal_True
;
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
;
663 //________________________________________________________________________________________________________
664 // SfxBaseController -> XController
665 //________________________________________________________________________________________________________
667 uno::Any
SfxBaseController::getViewData() throw( RuntimeException
)
671 SolarMutexGuard aGuard
;
672 if ( m_pData
->m_pViewShell
)
674 m_pData
->m_pViewShell
->WriteUserData( sData1
) ;
675 OUString
sData( sData1
);
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
)
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
;
740 xFrame
= ( pChildWin
->GetFrame() );
742 xFrame
->setName( sTargetFrameName
);
744 Reference
< XDispatchProvider
> xProv( xFrame
, uno::UNO_QUERY
);
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
);
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
);
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();
781 pFrame
= SfxViewFrame::GetNext( *pFrame
) )
783 if ( pFrame
->GetFrame().GetFrameInterface() == xParentFrame
)
785 pParentFrame
= pFrame
;
792 SfxSlotPool
& rFrameSlotPool
= SfxSlotPool::GetSlotPool( pParentFrame
);
793 const SfxSlot
* pSlot2( 0 );
794 if ( bMasterCommand
)
795 pSlot2
= rFrameSlotPool
.GetUnoSlot( aMasterCommand
);
797 pSlot2
= rFrameSlotPool
.GetUnoSlot( aURL
.Path
);
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
);
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
);
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();
838 pFrame
= SfxViewFrame::GetNext( *pFrame
) )
840 if ( pFrame
->GetFrame().GetFrameInterface() == xParentFrame
)
842 pParentFrame
= pFrame
;
849 SfxSlotPool
& rSlotPool2
= SfxSlotPool::GetSlotPool( pParentFrame
);
850 const SfxSlot
* pSlot2
= rSlotPool2
.GetUnoSlot( aURL
.Path
);
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
) );
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
);
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();
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),
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),
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
) );
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
&)
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;
997 lang::EventObject aObject
;
998 aObject
.Source
= *this ;
1000 SfxObjectShell
* pDoc
= pFrame
->GetObjectShell() ;
1001 SfxViewFrame
*pView
= SfxViewFrame::GetFirst(pDoc
);
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
)
1007 pView
= SfxViewFrame::GetNext( *pView
, pDoc
);
1010 SFX_APP()->NotifyEvent( SfxViewEventHint(SFX_EVENT_CLOSEVIEW
, GlobalEventConfig::GetEventName( STR_EVENT_CLOSEVIEW
), pDoc
, Reference
< frame::XController2
>( this ) ) );
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
);
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
);
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();
1156 if ( pSfxSlot
->GetMode() & nMode
)
1158 sal_Int16 nCommandGroup
= MapGroupIDToCommandGroup( pSfxSlot
->GetGroupId() );
1159 aGroupList
.push_back( nCommandGroup
);
1162 pSfxSlot
= pSlotPool
->NextSlot();
1166 uno::Sequence
< sal_Int16
> aSeq
=
1167 comphelper::containerToSequence
< sal_Int16
>( aGroupList
);
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();
1192 sal_Int16 nCommandGroup
= MapGroupIDToCommandGroup( pSfxSlot
->GetGroupId() );
1193 if ( nCommandGroup
== nCmdGroup
)
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
);
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
);
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() )
1289 if ( SfxViewFrame::Current() == pViewFrame
)
1290 pViewFrame
->GetDispatcher()->Update_Impl( sal_True
);
1292 Window
* pFrameWin
= &pViewFrame
->GetWindow();
1293 if ( pFrameWin
!= &pViewFrame
->GetFrame().GetWindow() )
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
);
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();
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
1330 if ( nPluginMode
== 3 )
1331 pViewFrame
->Resize( sal_True
);
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
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() )
1392 const SfxViewFactory
* pViewFactory
= rDocFactory
.GetViewFactoryByViewName( sViewId
);
1393 if ( pViewFactory
== NULL
)
1396 if ( pViewFactory
->GetOrdinal() == pViewFrame
->GetCurViewId() )
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
;
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( );
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 //=============================================================================
1495 OUString SAL_CALL
SfxBaseController::getTitle()
1496 throw (RuntimeException
)
1498 return impl_getTitleHelper()->getTitle ();
1501 //=============================================================================
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: */