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 .
20 #include <com/sun/star/uno/Reference.h>
21 #include <com/sun/star/awt/XTopWindow.hpp>
22 #include <com/sun/star/awt/XWindow.hpp>
23 #include <com/sun/star/util/XCloseable.hpp>
24 #include <com/sun/star/util/CloseVetoException.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <com/sun/star/container/XChild.hpp>
27 #include <com/sun/star/embed/XEmbeddedObject.hpp>
29 #include <svl/intitem.hxx>
30 #include <svl/stritem.hxx>
31 #include <tools/svborder.hxx>
32 #include <comphelper/diagnose_ex.hxx>
34 #include <appdata.hxx>
35 #include <sfx2/app.hxx>
36 #include <sfx2/event.hxx>
37 #include <sfx2/frame.hxx>
38 #include <sfx2/objsh.hxx>
39 #include <sfx2/dispatch.hxx>
40 #include <sfx2/docfile.hxx>
41 #include <sfx2/docfilt.hxx>
42 #include <sfx2/frmdescr.hxx>
43 #include <sfx2/sfxsids.hrc>
44 #include <sfx2/viewsh.hxx>
45 #include <sfx2/viewfrm.hxx>
46 #include "impframe.hxx"
48 #include <workwin.hxx>
49 #include <sfx2/ipclient.hxx>
52 using namespace com::sun::star
;
54 static std::vector
<SfxFrame
*> gaFramesArr_Impl
;
56 using namespace ::com::sun::star::uno
;
57 using namespace ::com::sun::star::util
;
58 using namespace ::com::sun::star::frame
;
59 using namespace ::com::sun::star::container
;
61 SfxPoolItem
* SfxUnoAnyItem::CreateDefault()
63 return new SfxUnoAnyItem(0, uno::Any());
66 SfxPoolItem
* SfxUnoFrameItem::CreateDefault()
68 return new SfxUnoFrameItem();
70 void SfxFrame::Construct_Impl()
72 m_pImpl
.reset(new SfxFrame_Impl
);
73 gaFramesArr_Impl
.push_back( this );
79 RemoveTopFrame_Impl( this );
80 m_pWindow
.disposeAndClear();
82 auto it
= std::find( gaFramesArr_Impl
.begin(), gaFramesArr_Impl
.end(), this );
83 if ( it
!= gaFramesArr_Impl
.end() )
84 gaFramesArr_Impl
.erase( it
);
86 delete m_pImpl
->pDescr
;
89 bool SfxFrame::DoClose()
91 // Actually, one more PrepareClose is still needed!
93 if ( !m_pImpl
->bClosing
)
95 m_pImpl
->bClosing
= true;
98 // now close frame; it will be deleted if this call is successful, so don't use any members after that!
102 Reference
< XCloseable
> xCloseable ( m_pImpl
->xFrame
, UNO_QUERY
);
104 xCloseable
->close(true);
105 else if ( m_pImpl
->xFrame
.is() )
107 Reference
< XFrame
> xFrame
= m_pImpl
->xFrame
;
108 xFrame
->setComponent( Reference
< css::awt::XWindow
>(), Reference
< XController
>() );
114 catch( css::util::CloseVetoException
& )
116 m_pImpl
->bClosing
= false;
119 catch( css::lang::DisposedException
& )
127 void SfxFrame::DoClose_Impl()
129 SfxBindings
* pBindings
= nullptr;
130 if ( m_pImpl
->pCurrentViewFrame
)
131 pBindings
= &m_pImpl
->pCurrentViewFrame
->GetBindings();
133 // For internal tasks Controllers and Tools must be cleared
134 if ( m_pImpl
->pWorkWin
)
135 m_pImpl
->pWorkWin
->DeleteControllers_Impl();
137 if ( m_pImpl
->pCurrentViewFrame
)
138 m_pImpl
->pCurrentViewFrame
->Close();
140 if ( m_pImpl
->bOwnsBindings
)
149 bool SfxFrame::DocIsModified_Impl()
151 return m_pImpl
->pCurrentViewFrame
&& m_pImpl
->pCurrentViewFrame
->GetObjectShell() &&
152 m_pImpl
->pCurrentViewFrame
->GetObjectShell()->IsModified();
155 bool SfxFrame::PrepareClose_Impl( bool bUI
)
159 // prevent recursive calls
160 if( !m_pImpl
->bPrepClosing
)
162 m_pImpl
->bPrepClosing
= true;
164 SfxObjectShell
* pCur
= GetCurrentDocument() ;
167 // SFX components have a known behaviour
168 // First check if this frame is the only view to its current document
170 for ( const SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pCur
);
171 !bOther
&& pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, pCur
) )
173 bOther
= ( &pFrame
->GetFrame() != this );
176 SfxGetpApp()->NotifyEvent( SfxViewEventHint(SfxEventHintId::PrepareCloseView
, GlobalEventConfig::GetEventName( GlobalEventId::PREPARECLOSEVIEW
), pCur
, GetController() ) );
179 // if there are other views only the current view of this frame must be asked
180 bRet
= GetCurrentViewFrame()->GetViewShell()->PrepareClose( bUI
);
182 // otherwise ask the document
183 bRet
= pCur
->PrepareClose( bUI
);
186 m_pImpl
->bPrepClosing
= false;
189 if ( bRet
&& m_pImpl
->pWorkWin
)
190 // if closing was accepted by the component the UI subframes must be asked also
191 bRet
= m_pImpl
->pWorkWin
->PrepareClose_Impl();
197 bool SfxFrame::IsClosing_Impl() const
199 return m_pImpl
->bClosing
;
202 void SfxFrame::SetIsClosing_Impl()
204 m_pImpl
->bClosing
= true;
207 void SfxFrame::CancelTransfers()
209 if( m_pImpl
->bInCancelTransfers
)
212 m_pImpl
->bInCancelTransfers
= true;
213 SfxObjectShell
* pObj
= GetCurrentDocument();
214 if( pObj
) //&& !( pObj->Get_Impl()->nLoadedFlags & SfxLoadedFlags::ALL ))
217 for( pFrm
= SfxViewFrame::GetFirst( pObj
);
218 pFrm
&& &pFrm
->GetFrame() == this;
219 pFrm
= SfxViewFrame::GetNext( *pFrm
, pObj
) ) ;
220 // No more Frame in Document -> Cancel
223 pObj
->CancelTransfers();
224 GetCurrentDocument()->Broadcast( SfxHint(SfxHintId::TitleChanged
) );
228 // Check if StarOne-Loader should be canceled
229 SfxFrameWeakRef
wFrame( this );
231 m_pImpl
->bInCancelTransfers
= false;
234 SfxViewFrame
* SfxFrame::GetCurrentViewFrame() const
236 return m_pImpl
->pCurrentViewFrame
;
239 bool SfxFrame::IsAutoLoadLocked_Impl() const
241 // Its own Document is locked?
242 const SfxObjectShell
* pObjSh
= GetCurrentDocument();
243 if ( !pObjSh
|| !pObjSh
->IsAutoLoadLocked() )
246 // otherwise allow AutoLoad
250 SfxObjectShell
* SfxFrame::GetCurrentDocument() const
252 return m_pImpl
->pCurrentViewFrame
?
253 m_pImpl
->pCurrentViewFrame
->GetObjectShell() :
257 void SfxFrame::SetCurrentViewFrame_Impl( SfxViewFrame
*pFrame
)
259 m_pImpl
->pCurrentViewFrame
= pFrame
;
262 bool SfxFrame::GetHasTitle() const
264 return m_pImpl
->mbHasTitle
;
267 void SfxFrame::SetHasTitle( bool n
)
269 m_pImpl
->mbHasTitle
= n
;
272 void SfxFrame::GetViewData_Impl()
274 // Update all modifiable data between load and unload, the
275 // fixed data is only processed once (after PrepareForDoc_Impl in
276 // updateDescriptor) to save time.
278 SfxViewFrame
* pViewFrame
= GetCurrentViewFrame();
279 if( pViewFrame
&& pViewFrame
->GetViewShell() )
281 SfxItemSet
*pSet
= GetDescriptor()->GetArgs();
282 if ( GetController().is() && pSet
->GetItemState( SID_VIEW_DATA
) != SfxItemState::SET
)
284 css::uno::Any aData
= GetController()->getViewData();
285 pSet
->Put( SfxUnoAnyItem( SID_VIEW_DATA
, aData
) );
288 if ( pViewFrame
->GetCurViewId() )
289 pSet
->Put( SfxUInt16Item( SID_VIEW_ID
, static_cast<sal_uInt16
>(pViewFrame
->GetCurViewId()) ) );
293 void SfxFrame::UpdateDescriptor( SfxObjectShell
const *pDoc
)
295 // For PrepareForDoc_Impl frames, the descriptor of the updated
296 // and new itemset to be initialized. All data fir restoring the view
297 // are thus saved. If the document be replaced, GetViewData_Impl (so)
298 // the latest information hinzugef by "added. All together then the
299 // browser-history saved in. When you activate such frame pick entry
300 // is complete itemsets and the descriptor in the OpenDoc sent;.
301 // Here only the fixed properties identified "other adjustable, the
302 // retrieved by GetViewData (saves time).
304 assert(pDoc
&& "NULL-Document inserted ?!");
306 const SfxMedium
*pMed
= pDoc
->GetMedium();
307 GetDescriptor()->SetActualURL();
309 // Mark FileOpen parameter
310 SfxItemSet
* pItemSet
= pMed
->GetItemSet();
312 const std::shared_ptr
<const SfxFilter
>& pFilter
= pMed
->GetFilter();
315 aFilter
= pFilter
->GetFilterName();
317 const SfxStringItem
* pRefererItem
= SfxItemSet::GetItem
<SfxStringItem
>(pItemSet
, SID_REFERER
, false);
318 const SfxStringItem
* pOptionsItem
= SfxItemSet::GetItem
<SfxStringItem
>(pItemSet
, SID_FILE_FILTEROPTIONS
, false);
319 const SfxStringItem
* pTitle1Item
= SfxItemSet::GetItem
<SfxStringItem
>(pItemSet
, SID_DOCINFO_TITLE
, false);
321 SfxItemSet
*pSet
= GetDescriptor()->GetArgs();
323 // Delete all old Items
327 pSet
->Put( *pRefererItem
);
329 pSet
->Put( SfxStringItem( SID_REFERER
, OUString() ) );
332 pSet
->Put( *pOptionsItem
);
335 pSet
->Put( *pTitle1Item
);
337 pSet
->Put( SfxStringItem( SID_FILTER_NAME
, aFilter
));
341 SfxFrameDescriptor
* SfxFrame::GetDescriptor() const
343 // Create a FrameDescriptor On Demand; if there is no TopLevel-Frame
344 // will result in an error, as no valid link is created.
346 if ( !m_pImpl
->pDescr
)
348 DBG_ASSERT( true, "No TopLevel-Frame, but no Descriptor!" );
349 m_pImpl
->pDescr
= new SfxFrameDescriptor
;
350 if ( GetCurrentDocument() )
351 m_pImpl
->pDescr
->SetURL( GetCurrentDocument()->GetMedium()->GetOrigURL() );
353 return m_pImpl
->pDescr
;
356 void SfxFrame::GetDefaultTargetList(TargetList
& rList
)
358 // An empty string for 'No Target'
359 rList
.emplace_back( );
360 rList
.emplace_back( "_top" );
361 rList
.emplace_back( "_parent" );
362 rList
.emplace_back( "_blank" );
363 rList
.emplace_back( "_self" );
366 void SfxFrame::InsertTopFrame_Impl( SfxFrame
* pFrame
)
368 auto& rArr
= SfxGetpApp()->Get_Impl()->vTopFrames
;
369 rArr
.push_back( pFrame
);
372 void SfxFrame::RemoveTopFrame_Impl( SfxFrame
* pFrame
)
374 auto& rArr
= SfxGetpApp()->Get_Impl()->vTopFrames
;
375 auto it
= std::find( rArr
.begin(), rArr
.end(), pFrame
);
376 if ( it
!= rArr
.end() )
380 SfxFrameItem::SfxFrameItem( sal_uInt16 nWhichId
, SfxViewFrame
const *p
)
381 : SfxPoolItem( nWhichId
), pFrame( p
? &p
->GetFrame() : nullptr )
386 SfxFrameItem::SfxFrameItem( sal_uInt16 nWhichId
, SfxFrame
*p
):
387 SfxPoolItem( nWhichId
),
388 pFrame( p
), wFrame( p
)
392 SfxFrameItem::SfxFrameItem( SfxFrame
*p
):
394 pFrame( p
), wFrame( p
)
398 bool SfxFrameItem::operator==( const SfxPoolItem
&rItem
) const
400 return SfxPoolItem::operator==(rItem
) &&
401 static_cast<const SfxFrameItem
&>(rItem
).pFrame
== pFrame
&&
402 static_cast<const SfxFrameItem
&>(rItem
).wFrame
== wFrame
;
405 SfxFrameItem
* SfxFrameItem::Clone( SfxItemPool
*) const
407 SfxFrameItem
* pNew
= new SfxFrameItem( wFrame
);
408 pNew
->pFrame
= pFrame
;
412 bool SfxFrameItem::QueryValue( css::uno::Any
& rVal
, sal_uInt8
) const
416 rVal
<<= wFrame
->GetFrameInterface();
423 bool SfxFrameItem::PutValue( const css::uno::Any
& rVal
, sal_uInt8
)
425 Reference
< XFrame
> xFrame
;
426 if ( (rVal
>>= xFrame
) && xFrame
.is() )
428 SfxFrame
* pFr
= SfxFrame::GetFirst();
431 if ( pFr
->GetFrameInterface() == xFrame
)
433 wFrame
= pFrame
= pFr
;
437 pFr
= SfxFrame::GetNext( *pFr
);
446 SfxUnoAnyItem::SfxUnoAnyItem( sal_uInt16 nWhichId
, const css::uno::Any
& rAny
)
447 : SfxPoolItem( nWhichId
)
452 bool SfxUnoAnyItem::operator==( const SfxPoolItem
& rItem
) const
454 assert(SfxPoolItem::operator==(rItem
)); (void)rItem
;
458 SfxUnoAnyItem
* SfxUnoAnyItem::Clone( SfxItemPool
*) const
460 return new SfxUnoAnyItem( *this );
463 bool SfxUnoAnyItem::QueryValue( css::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ ) const
469 bool SfxUnoAnyItem::PutValue( const css::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ )
475 SfxUnoFrameItem::SfxUnoFrameItem()
479 SfxUnoFrameItem::SfxUnoFrameItem( sal_uInt16 nWhichId
, css::uno::Reference
< css::frame::XFrame
> i_xFrame
)
480 : SfxPoolItem( nWhichId
)
481 , m_xFrame(std::move( i_xFrame
))
485 bool SfxUnoFrameItem::operator==( const SfxPoolItem
& i_rItem
) const
487 return SfxPoolItem::operator==(i_rItem
) &&
488 static_cast< const SfxUnoFrameItem
& >( i_rItem
).m_xFrame
== m_xFrame
;
491 SfxUnoFrameItem
* SfxUnoFrameItem::Clone( SfxItemPool
* ) const
493 return new SfxUnoFrameItem( *this );
496 bool SfxUnoFrameItem::QueryValue( css::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ ) const
502 bool SfxUnoFrameItem::PutValue( const css::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ )
504 return ( rVal
>>= m_xFrame
);
507 css::uno::Reference
< css::frame::XController
> SfxFrame::GetController() const
509 if ( m_pImpl
->pCurrentViewFrame
&& m_pImpl
->pCurrentViewFrame
->GetViewShell() )
510 return m_pImpl
->pCurrentViewFrame
->GetViewShell()->GetController();
512 return css::uno::Reference
< css::frame::XController
> ();
515 const css::uno::Reference
< css::frame::XFrame
>& SfxFrame::GetFrameInterface() const
517 return m_pImpl
->xFrame
;
520 void SfxFrame::SetFrameInterface_Impl( const css::uno::Reference
< css::frame::XFrame
>& rFrame
)
522 m_pImpl
->xFrame
= rFrame
;
523 css::uno::Reference
< css::frame::XDispatchRecorder
> xRecorder
;
524 if ( !rFrame
.is() && GetCurrentViewFrame() )
525 GetCurrentViewFrame()->GetBindings().SetRecorder_Impl( xRecorder
);
528 void SfxFrame::Appear()
530 if ( GetCurrentViewFrame() )
532 GetCurrentViewFrame()->Show();
534 m_pImpl
->xFrame
->getContainerWindow()->setVisible( true );
535 Reference
< css::awt::XTopWindow
> xTopWindow( m_pImpl
->xFrame
->getContainerWindow(), UNO_QUERY
);
536 if ( xTopWindow
.is() )
537 xTopWindow
->toFront();
541 void SfxFrame::AppearWithUpdate()
544 if ( GetCurrentViewFrame() )
545 GetCurrentViewFrame()->GetDispatcher()->Update_Impl( true );
548 void SfxFrame::SetOwnsBindings_Impl( bool bSet
)
550 m_pImpl
->bOwnsBindings
= bSet
;
553 bool SfxFrame::OwnsBindings_Impl() const
555 return m_pImpl
->bOwnsBindings
;
558 void SfxFrame::SetToolSpaceBorderPixel_Impl( const SvBorder
& rBorder
)
560 m_pImpl
->aBorder
= rBorder
;
561 SfxViewFrame
*pF
= GetCurrentViewFrame();
565 Point
aPos ( rBorder
.Left(), rBorder
.Top() );
566 Size
aSize( GetWindow().GetOutputSizePixel() );
567 tools::Long nDeltaX
= rBorder
.Left() + rBorder
.Right();
568 if ( aSize
.Width() > nDeltaX
)
569 aSize
.AdjustWidth( -nDeltaX
);
573 tools::Long nDeltaY
= rBorder
.Top() + rBorder
.Bottom();
574 if ( aSize
.Height() > nDeltaY
)
575 aSize
.AdjustHeight( -nDeltaY
);
577 aSize
.setHeight( 0 );
579 pF
->GetWindow().SetPosSizePixel( aPos
, aSize
);
582 tools::Rectangle
SfxFrame::GetTopOuterRectPixel_Impl() const
584 Size
aSize( GetWindow().GetOutputSizePixel() );
585 return tools::Rectangle( Point(), aSize
);
588 SfxWorkWindow
* SfxFrame::GetWorkWindow_Impl() const
590 return m_pImpl
->pWorkWin
;
593 void SfxFrame::CreateWorkWindow_Impl()
595 SfxFrame
* pFrame
= this;
599 // this makes sense only for inplace activated objects
602 Reference
< XChild
> xChild( GetCurrentDocument()->GetModel(), UNO_QUERY
);
605 Reference
< XModel
> xParent( xChild
->getParent(), UNO_QUERY
);
608 Reference
< XController
> xParentCtrler
= xParent
->getCurrentController();
609 if ( xParentCtrler
.is() )
611 Reference
< XFrame
> xFrame( xParentCtrler
->getFrame() );
612 SfxFrame
* pFr
= SfxFrame::GetFirst();
615 if ( pFr
->GetFrameInterface() == xFrame
)
621 pFr
= SfxFrame::GetNext( *pFr
);
629 TOOLS_WARN_EXCEPTION( "sfx.view", "SfxFrame::CreateWorkWindow_Impl: Exception caught. Please try to submit a reproducible bug!");
633 m_pImpl
->pWorkWin
= new SfxWorkWindow( &pFrame
->GetWindow(), this, pFrame
);
636 void SfxFrame::GrabFocusOnComponent_Impl()
638 if ( m_pImpl
->bReleasingComponent
)
640 GetWindow().GrabFocus();
644 vcl::Window
* pFocusWindow
= &GetWindow();
645 if ( GetCurrentViewFrame() && GetCurrentViewFrame()->GetViewShell() && GetCurrentViewFrame()->GetViewShell()->GetWindow() )
646 pFocusWindow
= GetCurrentViewFrame()->GetViewShell()->GetWindow();
648 if( !pFocusWindow
->HasChildPathFocus() )
649 pFocusWindow
->GrabFocus();
652 void SfxFrame::ReleasingComponent_Impl()
654 m_pImpl
->bReleasingComponent
= true;
657 bool SfxFrame::IsInPlace() const
659 return m_pImpl
->bInPlace
;
662 void SfxFrame::Resize()
664 if ( IsClosing_Impl() )
667 if ( OwnsBindings_Impl() )
671 SetToolSpaceBorderPixel_Impl( SvBorder() );
675 // check for IPClient that contains UIactive object or object that is currently UI activating
676 SfxWorkWindow
*pWork
= GetWorkWindow_Impl();
677 SfxInPlaceClient
* pClient
= GetCurrentViewFrame()->GetViewShell() ? GetCurrentViewFrame()->GetViewShell()->GetUIActiveIPClient_Impl() : nullptr;
681 = SfxObjectShell::GetShellFromComponent(pClient
->GetObject()->getComponent());
682 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst(pDoc
);
683 pWork
= pFrame
? pFrame
->GetFrame().GetWorkWindow_Impl() : nullptr;
688 pWork
->ArrangeChildren_Impl();
689 pWork
->ShowChildren_Impl();
692 // problem in presence of UIActive object: when the window is resized, but the toolspace border
693 // remains the same, setting the toolspace border at the ContainerEnvironment doesn't force a
694 // resize on the IPEnvironment; without that no resize is called for the SfxViewFrame. So always
695 // set the window size of the SfxViewFrame explicit.
696 SetToolSpaceBorderPixel_Impl( m_pImpl
->aBorder
);
699 else if ( m_pImpl
->pCurrentViewFrame
)
701 m_pImpl
->pCurrentViewFrame
->GetWindow().SetSizePixel( GetWindow().GetOutputSizePixel() );
706 SfxFrame
* SfxFrame::GetFirst()
708 return gaFramesArr_Impl
.empty() ? nullptr : gaFramesArr_Impl
.front();
711 SfxFrame
* SfxFrame::GetNext( SfxFrame
& rFrame
)
713 auto it
= std::find( gaFramesArr_Impl
.begin(), gaFramesArr_Impl
.end(), &rFrame
);
714 if ( it
!= gaFramesArr_Impl
.end() && (++it
) != gaFramesArr_Impl
.end() )
720 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */