Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / docnode / swbaslnk.cxx
blob287bc8079586293afd07d1d85538620378384b6d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
30 #include <frmatr.hxx>
31 #include <frmfmt.hxx>
32 #include <doc.hxx>
33 #include <IDocumentLayoutAccess.hxx>
34 #include <IDocumentLinksAdministration.hxx>
35 #include <pam.hxx>
36 #include <swtable.hxx>
37 #include <swevent.hxx>
38 #include <swbaslnk.hxx>
39 #include <swserv.hxx>
40 #include <viewsh.hxx>
41 #include <ndgrf.hxx>
42 #include <htmltbl.hxx>
43 #include <dialoghelp.hxx>
44 #include <memory>
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 )
54 if( !m_pContentNode )
56 OSL_ENSURE(false, "DataChanged without ContentNode" );
57 return ERROR_GENERAL;
60 SwDoc& rDoc = m_pContentNode->GetDoc();
61 if( rDoc.IsInDtor() || ChkNoDataFlag() )
63 return SUCCESS;
66 SotClipboardFormatId nFormat = SotExchange::GetFormatIdFromMimeType( rMimeType );
68 if( m_pContentNode->IsNoTextNode() &&
69 nFormat == sfx2::LinkManager::RegisterStatusInfoId() )
71 // Only a status change - serve Events?
72 OUString sState;
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!
95 bool bUpdate = false;
96 bool bFrameInPaint = false;
97 Size aGrfSz, aOldSz;
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();
110 Graphic aGrf;
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);
122 bUpdate = true;
124 // Always use the correct graphic size
125 if( aGrfSz.Height() && aGrfSz.Width() &&
126 aOldSz.Height() && aOldSz.Width() &&
127 aGrfSz != aOldSz )
129 pSwGrfNode->SetTwipSize(aGrfSz);
130 aOldSz = aGrfSz;
134 else if( m_pContentNode->IsOLENode() )
135 bUpdate = true;
137 if ( !bUpdate || bFrameInPaint )
138 return SUCCESS;
140 if(pSwGrfNode && !SetGrfFlySize(aGrfSz, pSwGrfNode, aOldSz))
141 pSwGrfNode->TriggerGraphicArrived();
143 return SUCCESS;
146 static bool SetGrfFlySize( const Size& rGrfSz, SwGrfNode* pGrfNd, const Size& rOrigGrfSize )
148 bool bRet = false;
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)
163 Size aCalcSz( aSz );
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() );
172 else
173 // Take over height and width
174 aCalcSz = rGrfSz;
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 );
187 bRet = true;
190 if( !aSz.Width() )
192 // If the graphic is anchored in a table, we need to recalculate
193 // the table rows
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();
202 if( pLayout )
204 const sal_uInt16 nBrowseWidth =
205 pLayout->GetBrowseWidthByTable( rDoc );
206 if ( nBrowseWidth )
208 pLayout->Resize( nBrowseWidth, true, true,
209 bLastGrf ? HTMLTABLE_RESIZE_NOW
210 : 500 );
217 // SetTwipSize rescales an ImageMap if needed for which
218 // it requires the Frame Format
219 pGrfNd->SetTwipSize( rGrfSz );
222 return bRet;
225 bool SwBaseLink::SwapIn( bool bWaitForData, bool bNativFormat )
227 if( !GetObj() && ( bNativFormat || ( !IsSynchron() && bWaitForData ) ))
229 AddNextRef();
230 GetRealObject_();
231 ReleaseRef();
234 bool bRes = false;
236 if( GetObj() )
238 OUString aMimeType( SotExchange::GetFormatMimeType( GetContentType() ));
239 uno::Any aValue;
240 (void)GetObj()->GetData( aValue, aMimeType, !IsSynchron() && bWaitForData );
242 if( bWaitForData && !GetObj() )
244 OSL_ENSURE( false, "The SvxFileObject was deleted in a GetData!" );
246 else
248 bRes = aValue.hasValue();
249 if ( bRes )
251 DataChanged( aMimeType, aValue );
255 else if( !IsSynchron() && bWaitForData )
257 SetSynchron( true );
258 bRes = Update();
259 SetSynchron( false );
261 else
262 bRes = Update();
264 return bRes;
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
280 if (m_pContentNode)
282 SwFrameFormat *const pFormat = m_pContentNode->GetFlyFormat();
283 if (pFormat)
285 const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
286 SwNode const*const pAnchorNode = rAnchor.GetAnchorNode();
287 if (pAnchorNode &&
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())))
293 return pAnchorNode;
295 return nullptr;
299 OSL_ENSURE( false, "GetAnchor is not shadowed" );
300 return nullptr;
303 bool SwBaseLink::IsRecursion( const SwBaseLink* pChkLnk ) const
305 tools::SvRef<SwServerObject> aRef( static_cast<SwServerObject*>(GetObj()) );
306 if( aRef.is() )
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 );
312 return false;
315 bool SwBaseLink::IsInRange( SwNodeOffset, SwNodeOffset ) const
317 // Not Graphic or OLE Links
318 // Fields or Sections have their own derivation!
319 return false;
322 SwBaseLink::~SwBaseLink()
326 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */