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 <vcl/svapp.hxx>
22 #include <osl/diagnose.h>
23 #include <sfx2/lnkbase.hxx>
24 #include <editeng/boxitem.hxx>
25 #include <sfx2/linkmgr.hxx>
26 #include <sfx2/event.hxx>
27 #include <sot/exchange.hxx>
28 #include <fmtfsize.hxx>
29 #include <fmtanchr.hxx>
33 #include <IDocumentLayoutAccess.hxx>
34 #include <IDocumentLinksAdministration.hxx>
36 #include <swtable.hxx>
37 #include <swevent.hxx>
38 #include <swbaslnk.hxx>
42 #include <htmltbl.hxx>
43 #include <dialoghelp.hxx>
46 using namespace com::sun::star
;
48 static bool SetGrfFlySize( const Size
& rGrfSz
, SwGrfNode
* pGrfNd
, const Size
&rOrigGrfSize
);
51 ::sfx2::SvBaseLink::UpdateResult
SwBaseLink::DataChanged(
52 const OUString
& rMimeType
, const uno::Any
& rValue
)
56 OSL_ENSURE(false, "DataChanged without ContentNode" );
60 SwDoc
& rDoc
= m_pContentNode
->GetDoc();
61 if( rDoc
.IsInDtor() || ChkNoDataFlag() )
66 SotClipboardFormatId nFormat
= SotExchange::GetFormatIdFromMimeType( rMimeType
);
68 if( m_pContentNode
->IsNoTextNode() &&
69 nFormat
== sfx2::LinkManager::RegisterStatusInfoId() )
71 // Only a status change - serve Events?
74 if( rValue
.hasValue() && ( rValue
>>= sState
))
76 SvMacroItemId nEvent
= SvMacroItemId::NONE
;
77 switch( sState
.toInt32() )
79 case sfx2::LinkManager::STATE_LOAD_OK
: nEvent
= SvMacroItemId::OnImageLoadDone
; break;
80 case sfx2::LinkManager::STATE_LOAD_ERROR
: nEvent
= SvMacroItemId::OnImageLoadError
; break;
81 case sfx2::LinkManager::STATE_LOAD_ABORT
: nEvent
= SvMacroItemId::OnImageLoadCancel
; break;
84 SwFrameFormat
* pFormat
;
85 if( nEvent
!= SvMacroItemId::NONE
&& nullptr != ( pFormat
= m_pContentNode
->GetFlyFormat() ))
87 SwCallMouseEvent aCallEvent
;
88 aCallEvent
.Set( EVENT_OBJECT_IMAGE
, pFormat
);
89 rDoc
.CallEvent( nEvent
, aCallEvent
);
92 return SUCCESS
; // That's it!
96 bool bFrameInPaint
= false;
99 SwGrfNode
* pSwGrfNode
= nullptr;
101 if (m_pContentNode
->IsGrfNode())
103 pSwGrfNode
= m_pContentNode
->GetGrfNode();
104 assert(pSwGrfNode
&& "Error, pSwGrfNode expected when node answers IsGrfNode() with true (!)");
105 aOldSz
= pSwGrfNode
->GetTwipSize();
106 const GraphicObject
& rGrfObj
= pSwGrfNode
->GetGrfObj();
108 bFrameInPaint
= pSwGrfNode
->IsFrameInPaint();
112 // tdf#124698 if any auth dialog is needed, find what the parent window should be
113 weld::Window
* pDlgParent
= GetFrameWeld(&rDoc
);
115 if (rDoc
.getIDocumentLinksAdministration().GetLinkManager().GetGraphicFromAny(rMimeType
, rValue
, aGrf
, pDlgParent
) &&
116 ( GraphicType::Default
!= aGrf
.GetType() ||
117 GraphicType::Default
!= rGrfObj
.GetType() ) )
119 aGrfSz
= ::GetGraphicSizeTwip( aGrf
, nullptr );
121 pSwGrfNode
->SetGraphic(aGrf
);
124 // Always use the correct graphic size
125 if( aGrfSz
.Height() && aGrfSz
.Width() &&
126 aOldSz
.Height() && aOldSz
.Width() &&
129 pSwGrfNode
->SetTwipSize(aGrfSz
);
134 else if( m_pContentNode
->IsOLENode() )
137 if ( !bUpdate
|| bFrameInPaint
)
140 if(pSwGrfNode
&& !SetGrfFlySize(aGrfSz
, pSwGrfNode
, aOldSz
))
141 pSwGrfNode
->TriggerGraphicArrived();
146 static bool SetGrfFlySize( const Size
& rGrfSz
, SwGrfNode
* pGrfNd
, const Size
& rOrigGrfSize
)
149 SwViewShell
*pSh
= pGrfNd
->GetDoc().getIDocumentLayoutAccess().GetCurrentViewShell();
150 std::unique_ptr
<CurrShell
> pCurr
;
151 if ( pGrfNd
->GetDoc().GetEditShell() )
152 pCurr
.reset(new CurrShell( pSh
));
154 Size aSz
= rOrigGrfSize
;
155 if ( !(aSz
.Width() && aSz
.Height()) &&
156 rGrfSz
.Width() && rGrfSz
.Height() )
158 SwFrameFormat
* pFormat
= nullptr;
159 if (pGrfNd
->IsChgTwipSize())
160 pFormat
= pGrfNd
->GetFlyFormat();
161 if (nullptr != pFormat
)
164 if ( !aSz
.Height() && aSz
.Width() )
165 // Calculate the right height
166 aCalcSz
.setHeight( rGrfSz
.Height() *
167 aSz
.Width() / rGrfSz
.Width() );
168 else if ( !aSz
.Width() && aSz
.Height() )
169 // Calculate the right width
170 aCalcSz
.setWidth( rGrfSz
.Width() *
171 aSz
.Height() / rGrfSz
.Height() );
173 // Take over height and width
176 const SvxBoxItem
&rBox
= pFormat
->GetBox();
177 aCalcSz
.AdjustWidth(rBox
.CalcLineSpace(SvxBoxItemLine::LEFT
) +
178 rBox
.CalcLineSpace(SvxBoxItemLine::RIGHT
) );
179 aCalcSz
.AdjustHeight(rBox
.CalcLineSpace(SvxBoxItemLine::TOP
) +
180 rBox
.CalcLineSpace(SvxBoxItemLine::BOTTOM
) );
181 const SwFormatFrameSize
& rOldAttr
= pFormat
->GetFrameSize();
182 if( rOldAttr
.GetSize() != aCalcSz
)
184 SwFormatFrameSize
aAttr( rOldAttr
);
185 aAttr
.SetSize( aCalcSz
);
186 pFormat
->SetFormatAttr( aAttr
);
192 // If the graphic is anchored in a table, we need to recalculate
194 const SwDoc
& rDoc
= pGrfNd
->GetDoc();
195 SwNode
* pAnchorNode
= pFormat
->GetAnchor().GetAnchorNode();
196 SwTableNode
*pTableNd
;
197 if (pAnchorNode
&& nullptr != (pTableNd
= pAnchorNode
->FindTableNode()))
199 const bool bLastGrf
= !pTableNd
->GetTable().DecGrfsThatResize();
200 SwHTMLTableLayout
*pLayout
=
201 pTableNd
->GetTable().GetHTMLTableLayout();
204 const sal_uInt16 nBrowseWidth
=
205 pLayout
->GetBrowseWidthByTable( rDoc
);
208 pLayout
->Resize( nBrowseWidth
, true, true,
209 bLastGrf
? HTMLTABLE_RESIZE_NOW
217 // SetTwipSize rescales an ImageMap if needed for which
218 // it requires the Frame Format
219 pGrfNd
->SetTwipSize( rGrfSz
);
225 bool SwBaseLink::SwapIn( bool bWaitForData
, bool bNativFormat
)
227 if( !GetObj() && ( bNativFormat
|| ( !IsSynchron() && bWaitForData
) ))
238 OUString
aMimeType( SotExchange::GetFormatMimeType( GetContentType() ));
240 (void)GetObj()->GetData( aValue
, aMimeType
, !IsSynchron() && bWaitForData
);
242 if( bWaitForData
&& !GetObj() )
244 OSL_ENSURE( false, "The SvxFileObject was deleted in a GetData!" );
248 bRes
= aValue
.hasValue();
251 DataChanged( aMimeType
, aValue
);
255 else if( !IsSynchron() && bWaitForData
)
259 SetSynchron( false );
267 void SwBaseLink::Closed()
269 if( m_pContentNode
&& !m_pContentNode
->GetDoc().IsInDtor() )
271 // Delete the connection
272 if( m_pContentNode
->IsGrfNode() )
273 static_cast<SwGrfNode
*>(m_pContentNode
)->ReleaseLink();
275 SvBaseLink::Closed();
278 const SwNode
* SwBaseLink::GetAnchor() const
282 SwFrameFormat
*const pFormat
= m_pContentNode
->GetFlyFormat();
285 const SwFormatAnchor
& rAnchor
= pFormat
->GetAnchor();
286 SwNode
const*const pAnchorNode
= rAnchor
.GetAnchorNode();
288 ((RndStdIds::FLY_AS_CHAR
== rAnchor
.GetAnchorId()) ||
289 (RndStdIds::FLY_AT_CHAR
== rAnchor
.GetAnchorId()) ||
290 (RndStdIds::FLY_AT_FLY
== rAnchor
.GetAnchorId()) ||
291 (RndStdIds::FLY_AT_PARA
== rAnchor
.GetAnchorId())))
299 OSL_ENSURE( false, "GetAnchor is not shadowed" );
303 bool SwBaseLink::IsRecursion( const SwBaseLink
* pChkLnk
) const
305 tools::SvRef
<SwServerObject
> aRef( static_cast<SwServerObject
*>(GetObj()) );
308 // As it's a ServerObject, we query all contained Links
309 // if we are contained in them. Else we have a recursion.
310 return aRef
->IsLinkInServer( pChkLnk
);
315 bool SwBaseLink::IsInRange( SwNodeOffset
, SwNodeOffset
) const
317 // Not Graphic or OLE Links
318 // Fields or Sections have their own derivation!
322 SwBaseLink::~SwBaseLink()
326 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */