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/lang/XUnoTunnel.hpp>
27 #include <com/sun/star/container/XChild.hpp>
28 #include <com/sun/star/embed/XEmbeddedObject.hpp>
30 #include <vcl/menu.hxx>
31 #include <svl/intitem.hxx>
32 #include <svl/stritem.hxx>
33 #include <tools/svborder.hxx>
34 #include <osl/diagnose.h>
36 #include <appdata.hxx>
37 #include <sfx2/app.hxx>
38 #include <sfx2/event.hxx>
39 #include <sfx2/frame.hxx>
40 #include <sfx2/objsh.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/docfile.hxx>
43 #include <sfx2/docfilt.hxx>
44 #include <sfx2/frmdescr.hxx>
45 #include <sfx2/sfxsids.hrc>
46 #include <sfx2/viewsh.hxx>
47 #include <sfx2/viewfrm.hxx>
48 #include "impframe.hxx"
49 #include <workwin.hxx>
50 #include <sfx2/ipclient.hxx>
53 using namespace com::sun::star
;
55 static std::vector
<SfxFrame
*>* pFramesArr_Impl
=nullptr;
57 using namespace ::com::sun::star::uno
;
58 using namespace ::com::sun::star::util
;
59 using namespace ::com::sun::star::frame
;
60 using namespace ::com::sun::star::container
;
62 SfxPoolItem
* SfxUnoAnyItem::CreateDefault()
64 return new SfxUnoAnyItem();
67 SfxPoolItem
* SfxUnoFrameItem::CreateDefault()
69 return new SfxUnoFrameItem();
72 void SfxFrame::Construct_Impl()
74 pImpl
.reset(new SfxFrame_Impl
);
75 if ( !pFramesArr_Impl
)
76 pFramesArr_Impl
= new std::vector
<SfxFrame
*>;
77 pFramesArr_Impl
->push_back( this );
83 RemoveTopFrame_Impl( this );
84 pWindow
.disposeAndClear();
86 auto it
= std::find( pFramesArr_Impl
->begin(), pFramesArr_Impl
->end(), this );
87 if ( it
!= pFramesArr_Impl
->end() )
88 pFramesArr_Impl
->erase( it
);
93 bool SfxFrame::DoClose()
95 // Actually, one more PrepareClose is still needed!
97 if ( !pImpl
->bClosing
)
99 pImpl
->bClosing
= true;
102 // now close frame; it will be deleted if this call is successful, so don't use any members after that!
106 Reference
< XCloseable
> xCloseable ( pImpl
->xFrame
, UNO_QUERY
);
108 xCloseable
->close(true);
109 else if ( pImpl
->xFrame
.is() )
111 Reference
< XFrame
> xFrame
= pImpl
->xFrame
;
112 xFrame
->setComponent( Reference
< css::awt::XWindow
>(), Reference
< XController
>() );
118 catch( css::util::CloseVetoException
& )
120 pImpl
->bClosing
= false;
123 catch( css::lang::DisposedException
& )
131 void SfxFrame::DoClose_Impl()
133 SfxBindings
* pBindings
= nullptr;
134 if ( pImpl
->pCurrentViewFrame
)
135 pBindings
= &pImpl
->pCurrentViewFrame
->GetBindings();
137 // For internal tasks Controllers and Tools must be cleared
138 if ( pImpl
->pWorkWin
)
139 pImpl
->pWorkWin
->DeleteControllers_Impl();
141 if ( pImpl
->pCurrentViewFrame
)
142 pImpl
->pCurrentViewFrame
->Close();
144 if ( pImpl
->bOwnsBindings
)
153 bool SfxFrame::DocIsModified_Impl()
155 return pImpl
->pCurrentViewFrame
&& pImpl
->pCurrentViewFrame
->GetObjectShell() &&
156 pImpl
->pCurrentViewFrame
->GetObjectShell()->IsModified();
159 bool SfxFrame::PrepareClose_Impl( bool bUI
)
163 // prevent recursive calls
164 if( !pImpl
->bPrepClosing
)
166 pImpl
->bPrepClosing
= true;
168 SfxObjectShell
* pCur
= GetCurrentDocument() ;
171 // SFX components have a known behaviour
172 // First check if this frame is the only view to its current document
174 for ( const SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pCur
);
175 !bOther
&& pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, pCur
) )
177 bOther
= ( &pFrame
->GetFrame() != this );
180 SfxGetpApp()->NotifyEvent( SfxViewEventHint(SfxEventHintId::PrepareCloseView
, GlobalEventConfig::GetEventName( GlobalEventId::PREPARECLOSEVIEW
), pCur
, GetController() ) );
183 // if there are other views only the current view of this frame must be asked
184 bRet
= GetCurrentViewFrame()->GetViewShell()->PrepareClose( bUI
);
186 // otherwise ask the document
187 bRet
= pCur
->PrepareClose( bUI
);
190 pImpl
->bPrepClosing
= false;
193 if ( bRet
&& pImpl
->pWorkWin
)
194 // if closing was accepted by the component the UI subframes must be asked also
195 bRet
= pImpl
->pWorkWin
->PrepareClose_Impl();
201 bool SfxFrame::IsClosing_Impl() const
203 return pImpl
->bClosing
;
206 void SfxFrame::SetIsClosing_Impl()
208 pImpl
->bClosing
= true;
211 void SfxFrame::CancelTransfers()
213 if( pImpl
->bInCancelTransfers
)
216 pImpl
->bInCancelTransfers
= true;
217 SfxObjectShell
* pObj
= GetCurrentDocument();
218 if( pObj
) //&& !( pObj->Get_Impl()->nLoadedFlags & SfxLoadedFlags::ALL ))
221 for( pFrm
= SfxViewFrame::GetFirst( pObj
);
222 pFrm
&& &pFrm
->GetFrame() == this;
223 pFrm
= SfxViewFrame::GetNext( *pFrm
, pObj
) ) ;
224 // No more Frame in Document -> Cancel
227 pObj
->CancelTransfers();
228 GetCurrentDocument()->Broadcast( SfxHint(SfxHintId::TitleChanged
) );
232 // Check if StarOne-Loader should be canceled
233 SfxFrameWeakRef
wFrame( this );
235 pImpl
->bInCancelTransfers
= false;
238 SfxViewFrame
* SfxFrame::GetCurrentViewFrame() const
240 return pImpl
->pCurrentViewFrame
;
243 bool SfxFrame::IsAutoLoadLocked_Impl() const
245 // Its own Document is locked?
246 const SfxObjectShell
* pObjSh
= GetCurrentDocument();
247 if ( !pObjSh
|| !pObjSh
->IsAutoLoadLocked() )
250 // otherwise allow AutoLoad
254 SfxObjectShell
* SfxFrame::GetCurrentDocument() const
256 return pImpl
->pCurrentViewFrame
?
257 pImpl
->pCurrentViewFrame
->GetObjectShell() :
261 void SfxFrame::SetCurrentViewFrame_Impl( SfxViewFrame
*pFrame
)
263 pImpl
->pCurrentViewFrame
= pFrame
;
266 bool SfxFrame::GetHasTitle() const
268 return pImpl
->mbHasTitle
;
271 void SfxFrame::SetHasTitle( bool n
)
273 pImpl
->mbHasTitle
= n
;
276 void SfxFrame::GetViewData_Impl()
278 // Update all modifiable data between load and unload, the
279 // fixed data is only processed once (after PrepareForDoc_Impl in
280 // updateDescriptor) to save time.
282 SfxViewFrame
* pViewFrame
= GetCurrentViewFrame();
283 if( pViewFrame
&& pViewFrame
->GetViewShell() )
285 SfxItemSet
*pSet
= GetDescriptor()->GetArgs();
286 if ( GetController().is() && pSet
->GetItemState( SID_VIEW_DATA
) != SfxItemState::SET
)
288 css::uno::Any aData
= GetController()->getViewData();
289 pSet
->Put( SfxUnoAnyItem( SID_VIEW_DATA
, aData
) );
292 if ( pViewFrame
->GetCurViewId() )
293 pSet
->Put( SfxUInt16Item( SID_VIEW_ID
, static_cast<sal_uInt16
>(pViewFrame
->GetCurViewId()) ) );
297 void SfxFrame::UpdateDescriptor( SfxObjectShell
const *pDoc
)
299 // For PrepareForDoc_Impl frames, the descriptor of the updated
300 // and new itemset to be initialized. All data fir restoring the view
301 // are thus saved. If the document be replaced, GetViewData_Impl (so)
302 // the latest information hinzugef by "added. All together then the
303 // browser-history saved in. When you activate such frame pick entry
304 // is complete itemsets and the descriptor in the OpenDoc sent;.
305 // Here only the fixed properties identified "other adjustable, the
306 // retrieved by GetViewData (saves time).
308 assert(pDoc
&& "NULL-Document inserted ?!");
310 const SfxMedium
*pMed
= pDoc
->GetMedium();
311 GetDescriptor()->SetActualURL();
313 // Mark FileOpen parameter
314 SfxItemSet
* pItemSet
= pMed
->GetItemSet();
316 const std::shared_ptr
<const SfxFilter
>& pFilter
= pMed
->GetFilter();
319 aFilter
= pFilter
->GetFilterName();
321 const SfxStringItem
* pRefererItem
= SfxItemSet::GetItem
<SfxStringItem
>(pItemSet
, SID_REFERER
, false);
322 const SfxStringItem
* pOptionsItem
= SfxItemSet::GetItem
<SfxStringItem
>(pItemSet
, SID_FILE_FILTEROPTIONS
, false);
323 const SfxStringItem
* pTitle1Item
= SfxItemSet::GetItem
<SfxStringItem
>(pItemSet
, SID_DOCINFO_TITLE
, false);
325 SfxItemSet
*pSet
= GetDescriptor()->GetArgs();
327 // Delete all old Items
331 pSet
->Put( *pRefererItem
);
333 pSet
->Put( SfxStringItem( SID_REFERER
, OUString() ) );
336 pSet
->Put( *pOptionsItem
);
339 pSet
->Put( *pTitle1Item
);
341 pSet
->Put( SfxStringItem( SID_FILTER_NAME
, aFilter
));
345 SfxFrameDescriptor
* SfxFrame::GetDescriptor() const
347 // Create a FrameDescriptor On Demand; if there is no TopLevel-Frame
348 // will result in an error, as no valid link is created.
350 if ( !pImpl
->pDescr
)
352 DBG_ASSERT( true, "No TopLevel-Frame, but no Descriptor!" );
353 pImpl
->pDescr
= new SfxFrameDescriptor
;
354 if ( GetCurrentDocument() )
355 pImpl
->pDescr
->SetURL( GetCurrentDocument()->GetMedium()->GetOrigURL() );
357 return pImpl
->pDescr
;
360 void SfxFrame::GetDefaultTargetList(TargetList
& rList
)
362 // An empty string for 'No Target'
363 rList
.emplace_back( );
364 rList
.emplace_back( "_top" );
365 rList
.emplace_back( "_parent" );
366 rList
.emplace_back( "_blank" );
367 rList
.emplace_back( "_self" );
370 void SfxFrame::InsertTopFrame_Impl( SfxFrame
* pFrame
)
372 auto& rArr
= SfxGetpApp()->Get_Impl()->vTopFrames
;
373 rArr
.push_back( pFrame
);
376 void SfxFrame::RemoveTopFrame_Impl( SfxFrame
* pFrame
)
378 auto& rArr
= SfxGetpApp()->Get_Impl()->vTopFrames
;
379 auto it
= std::find( rArr
.begin(), rArr
.end(), pFrame
);
380 if ( it
!= rArr
.end() )
384 SfxFrameItem::SfxFrameItem( sal_uInt16 nWhichId
, SfxViewFrame
const *p
)
385 : SfxPoolItem( nWhichId
), pFrame( p
? &p
->GetFrame() : nullptr )
390 SfxFrameItem::SfxFrameItem( sal_uInt16 nWhichId
, SfxFrame
*p
):
391 SfxPoolItem( nWhichId
),
392 pFrame( p
), wFrame( p
)
396 SfxFrameItem::SfxFrameItem( SfxFrame
*p
):
398 pFrame( p
), wFrame( p
)
402 bool SfxFrameItem::operator==( const SfxPoolItem
&rItem
) const
404 return SfxPoolItem::operator==(rItem
) &&
405 static_cast<const SfxFrameItem
&>(rItem
).pFrame
== pFrame
&&
406 static_cast<const SfxFrameItem
&>(rItem
).wFrame
== wFrame
;
409 SfxFrameItem
* SfxFrameItem::Clone( SfxItemPool
*) const
411 SfxFrameItem
* pNew
= new SfxFrameItem( wFrame
);
412 pNew
->pFrame
= pFrame
;
416 bool SfxFrameItem::QueryValue( css::uno::Any
& rVal
, sal_uInt8
) const
420 rVal
<<= wFrame
->GetFrameInterface();
427 bool SfxFrameItem::PutValue( const css::uno::Any
& rVal
, sal_uInt8
)
429 Reference
< XFrame
> xFrame
;
430 if ( (rVal
>>= xFrame
) && xFrame
.is() )
432 SfxFrame
* pFr
= SfxFrame::GetFirst();
435 if ( pFr
->GetFrameInterface() == xFrame
)
437 wFrame
= pFrame
= pFr
;
441 pFr
= SfxFrame::GetNext( *pFr
);
449 SfxUnoAnyItem::SfxUnoAnyItem()
454 SfxUnoAnyItem::SfxUnoAnyItem( sal_uInt16 nWhichId
, const css::uno::Any
& rAny
)
455 : SfxPoolItem( nWhichId
)
460 bool SfxUnoAnyItem::operator==( const SfxPoolItem
& rItem
) const
462 assert(SfxPoolItem::operator==(rItem
)); (void)rItem
;
466 SfxUnoAnyItem
* SfxUnoAnyItem::Clone( SfxItemPool
*) const
468 return new SfxUnoAnyItem( *this );
471 bool SfxUnoAnyItem::QueryValue( css::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ ) const
477 bool SfxUnoAnyItem::PutValue( const css::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ )
483 SfxUnoFrameItem::SfxUnoFrameItem()
489 SfxUnoFrameItem::SfxUnoFrameItem( sal_uInt16 nWhichId
, const css::uno::Reference
< css::frame::XFrame
>& i_rFrame
)
490 : SfxPoolItem( nWhichId
)
491 , m_xFrame( i_rFrame
)
495 bool SfxUnoFrameItem::operator==( const SfxPoolItem
& i_rItem
) const
497 return SfxPoolItem::operator==(i_rItem
) &&
498 static_cast< const SfxUnoFrameItem
& >( i_rItem
).m_xFrame
== m_xFrame
;
501 SfxUnoFrameItem
* SfxUnoFrameItem::Clone( SfxItemPool
* ) const
503 return new SfxUnoFrameItem( *this );
506 bool SfxUnoFrameItem::QueryValue( css::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ ) const
512 bool SfxUnoFrameItem::PutValue( const css::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ )
514 return ( rVal
>>= m_xFrame
);
517 css::uno::Reference
< css::frame::XController
> SfxFrame::GetController() const
519 if ( pImpl
->pCurrentViewFrame
&& pImpl
->pCurrentViewFrame
->GetViewShell() )
520 return pImpl
->pCurrentViewFrame
->GetViewShell()->GetController();
522 return css::uno::Reference
< css::frame::XController
> ();
525 const css::uno::Reference
< css::frame::XFrame
>& SfxFrame::GetFrameInterface() const
527 return pImpl
->xFrame
;
530 void SfxFrame::SetFrameInterface_Impl( const css::uno::Reference
< css::frame::XFrame
>& rFrame
)
532 pImpl
->xFrame
= rFrame
;
533 css::uno::Reference
< css::frame::XDispatchRecorder
> xRecorder
;
534 if ( !rFrame
.is() && GetCurrentViewFrame() )
535 GetCurrentViewFrame()->GetBindings().SetRecorder_Impl( xRecorder
);
538 void SfxFrame::Appear()
540 if ( GetCurrentViewFrame() )
542 GetCurrentViewFrame()->Show();
544 pImpl
->xFrame
->getContainerWindow()->setVisible( true );
545 Reference
< css::awt::XTopWindow
> xTopWindow( pImpl
->xFrame
->getContainerWindow(), UNO_QUERY
);
546 if ( xTopWindow
.is() )
547 xTopWindow
->toFront();
551 void SfxFrame::AppearWithUpdate()
554 if ( GetCurrentViewFrame() )
555 GetCurrentViewFrame()->GetDispatcher()->Update_Impl( true );
558 void SfxFrame::SetOwnsBindings_Impl( bool bSet
)
560 pImpl
->bOwnsBindings
= bSet
;
563 bool SfxFrame::OwnsBindings_Impl() const
565 return pImpl
->bOwnsBindings
;
568 void SfxFrame::SetToolSpaceBorderPixel_Impl( const SvBorder
& rBorder
)
570 pImpl
->aBorder
= rBorder
;
571 SfxViewFrame
*pF
= GetCurrentViewFrame();
575 Point
aPos ( rBorder
.Left(), rBorder
.Top() );
576 Size
aSize( GetWindow().GetOutputSizePixel() );
577 tools::Long nDeltaX
= rBorder
.Left() + rBorder
.Right();
578 if ( aSize
.Width() > nDeltaX
)
579 aSize
.AdjustWidth( -nDeltaX
);
583 tools::Long nDeltaY
= rBorder
.Top() + rBorder
.Bottom();
584 if ( aSize
.Height() > nDeltaY
)
585 aSize
.AdjustHeight( -nDeltaY
);
587 aSize
.setHeight( 0 );
589 pF
->GetWindow().SetPosSizePixel( aPos
, aSize
);
592 tools::Rectangle
SfxFrame::GetTopOuterRectPixel_Impl() const
594 Size
aSize( GetWindow().GetOutputSizePixel() );
595 return tools::Rectangle( Point(), aSize
);
598 SfxWorkWindow
* SfxFrame::GetWorkWindow_Impl() const
600 if ( pImpl
->pWorkWin
)
601 return pImpl
->pWorkWin
;
606 void SfxFrame::CreateWorkWindow_Impl()
608 SfxFrame
* pFrame
= this;
612 // this makes sense only for inplace activated objects
615 Reference
< XChild
> xChild( GetCurrentDocument()->GetModel(), UNO_QUERY
);
618 Reference
< XModel
> xParent( xChild
->getParent(), UNO_QUERY
);
621 Reference
< XController
> xParentCtrler
= xParent
->getCurrentController();
622 if ( xParentCtrler
.is() )
624 Reference
< XFrame
> xFrame( xParentCtrler
->getFrame() );
625 SfxFrame
* pFr
= SfxFrame::GetFirst();
628 if ( pFr
->GetFrameInterface() == xFrame
)
634 pFr
= SfxFrame::GetNext( *pFr
);
642 OSL_FAIL("SfxFrame::CreateWorkWindow_Impl: Exception caught. Please try to submit a reproducible bug!");
646 pImpl
->pWorkWin
= new SfxWorkWindow( &pFrame
->GetWindow(), this, pFrame
);
649 void SfxFrame::GrabFocusOnComponent_Impl()
651 if ( pImpl
->bReleasingComponent
)
653 GetWindow().GrabFocus();
657 vcl::Window
* pFocusWindow
= &GetWindow();
658 if ( GetCurrentViewFrame() && GetCurrentViewFrame()->GetViewShell() && GetCurrentViewFrame()->GetViewShell()->GetWindow() )
659 pFocusWindow
= GetCurrentViewFrame()->GetViewShell()->GetWindow();
661 if( !pFocusWindow
->HasChildPathFocus() )
662 pFocusWindow
->GrabFocus();
665 void SfxFrame::ReleasingComponent_Impl()
667 pImpl
->bReleasingComponent
= true;
670 bool SfxFrame::IsInPlace() const
672 return pImpl
->bInPlace
;
675 void SfxFrame::Resize()
677 if ( IsClosing_Impl() )
680 if ( OwnsBindings_Impl() )
684 SetToolSpaceBorderPixel_Impl( SvBorder() );
688 // check for IPClient that contains UIactive object or object that is currently UI activating
689 SfxWorkWindow
*pWork
= GetWorkWindow_Impl();
690 SfxInPlaceClient
* pClient
= GetCurrentViewFrame()->GetViewShell() ? GetCurrentViewFrame()->GetViewShell()->GetUIActiveIPClient_Impl() : nullptr;
694 = SfxObjectShell::GetShellFromComponent(pClient
->GetObject()->getComponent());
695 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst(pDoc
);
696 pWork
= pFrame
? pFrame
->GetFrame().GetWorkWindow_Impl() : nullptr;
701 pWork
->ArrangeChildren_Impl();
702 pWork
->ShowChildren_Impl();
705 // problem in presence of UIActive object: when the window is resized, but the toolspace border
706 // remains the same, setting the toolspace border at the ContainerEnvironment doesn't force a
707 // resize on the IPEnvironment; without that no resize is called for the SfxViewFrame. So always
708 // set the window size of the SfxViewFrame explicit.
709 SetToolSpaceBorderPixel_Impl( pImpl
->aBorder
);
712 else if ( pImpl
->pCurrentViewFrame
)
714 pImpl
->pCurrentViewFrame
->GetWindow().SetSizePixel( GetWindow().GetOutputSizePixel() );
719 SfxFrame
* SfxFrame::GetFirst()
721 if ( !pFramesArr_Impl
)
723 return pFramesArr_Impl
->empty() ? nullptr : pFramesArr_Impl
->front();
726 SfxFrame
* SfxFrame::GetNext( SfxFrame
& rFrame
)
728 auto it
= std::find( pFramesArr_Impl
->begin(), pFramesArr_Impl
->end(), &rFrame
);
729 if ( it
!= pFramesArr_Impl
->end() && (++it
) != pFramesArr_Impl
->end() )
735 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */