LibreOffice Module sw (master) 1
swbaslnk.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <vcl/svapp.hxx>
21
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>
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>
45
46using namespace com::sun::star;
47
48static bool SetGrfFlySize( const Size& rGrfSz, SwGrfNode* pGrfNd, const Size &rOrigGrfSize );
49
50
52 const OUString& rMimeType, const uno::Any & rValue )
53{
54 if( !m_pContentNode )
55 {
56 OSL_ENSURE(false, "DataChanged without ContentNode" );
57 return ERROR_GENERAL;
58 }
59
60 SwDoc& rDoc = m_pContentNode->GetDoc();
61 if( rDoc.IsInDtor() || ChkNoDataFlag() )
62 {
63 return SUCCESS;
64 }
65
67
70 {
71 // Only a status change - serve Events?
72 OUString sState;
73
74 if( rValue.hasValue() && ( rValue >>= sState ))
75 {
76 SvMacroItemId nEvent = SvMacroItemId::NONE;
77 switch( sState.toInt32() )
78 {
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;
82 }
83
84 SwFrameFormat* pFormat;
85 if( nEvent != SvMacroItemId::NONE && nullptr != ( pFormat = m_pContentNode->GetFlyFormat() ))
86 {
87 SwCallMouseEvent aCallEvent;
88 aCallEvent.Set( EVENT_OBJECT_IMAGE, pFormat );
89 rDoc.CallEvent( nEvent, aCallEvent );
90 }
91 }
92 return SUCCESS; // That's it!
93 }
94
95 bool bUpdate = false;
96 bool bFrameInPaint = false;
97 Size aGrfSz, aOldSz;
98
99 SwGrfNode* pSwGrfNode = nullptr;
100
102 {
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();
107
108 bFrameInPaint = pSwGrfNode->IsFrameInPaint();
109
110 Graphic aGrf;
111
112 // tdf#124698 if any auth dialog is needed, find what the parent window should be
113 weld::Window* pDlgParent = GetFrameWeld(&rDoc);
114
115 if (rDoc.getIDocumentLinksAdministration().GetLinkManager().GetGraphicFromAny(rMimeType, rValue, aGrf, pDlgParent) &&
116 ( GraphicType::Default != aGrf.GetType() ||
117 GraphicType::Default != rGrfObj.GetType() ) )
118 {
119 aGrfSz = ::GetGraphicSizeTwip( aGrf, nullptr );
120
121 pSwGrfNode->SetGraphic(aGrf);
122 bUpdate = true;
123
124 // Always use the correct graphic size
125 if( aGrfSz.Height() && aGrfSz.Width() &&
126 aOldSz.Height() && aOldSz.Width() &&
127 aGrfSz != aOldSz )
128 {
129 pSwGrfNode->SetTwipSize(aGrfSz);
130 aOldSz = aGrfSz;
131 }
132 }
133 }
134 else if( m_pContentNode->IsOLENode() )
135 bUpdate = true;
136
137 if ( !bUpdate || bFrameInPaint )
138 return SUCCESS;
139
140 if(pSwGrfNode && !SetGrfFlySize(aGrfSz, pSwGrfNode, aOldSz))
141 pSwGrfNode->TriggerGraphicArrived();
142
143 return SUCCESS;
144}
145
146static bool SetGrfFlySize( const Size& rGrfSz, SwGrfNode* pGrfNd, const Size& rOrigGrfSize )
147{
148 bool bRet = false;
150 std::unique_ptr<CurrShell> pCurr;
151 if ( pGrfNd->GetDoc().GetEditShell() )
152 pCurr.reset(new CurrShell( pSh ));
153
154 Size aSz = rOrigGrfSize;
155 if ( !(aSz.Width() && aSz.Height()) &&
156 rGrfSz.Width() && rGrfSz.Height() )
157 {
158 SwFrameFormat* pFormat = nullptr;
159 if (pGrfNd->IsChgTwipSize())
160 pFormat = pGrfNd->GetFlyFormat();
161 if (nullptr != pFormat)
162 {
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;
175
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 )
183 {
184 SwFormatFrameSize aAttr( rOldAttr );
185 aAttr.SetSize( aCalcSz );
186 pFormat->SetFormatAttr( aAttr );
187 bRet = true;
188 }
189
190 if( !aSz.Width() )
191 {
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()))
198 {
199 const bool bLastGrf = !pTableNd->GetTable().DecGrfsThatResize();
200 SwHTMLTableLayout *pLayout =
201 pTableNd->GetTable().GetHTMLTableLayout();
202 if( pLayout )
203 {
204 const sal_uInt16 nBrowseWidth =
205 pLayout->GetBrowseWidthByTable( rDoc );
206 if ( nBrowseWidth )
207 {
208 pLayout->Resize( nBrowseWidth, true, true,
209 bLastGrf ? HTMLTABLE_RESIZE_NOW
210 : 500 );
211 }
212 }
213 }
214 }
215 }
216
217 // SetTwipSize rescales an ImageMap if needed for which
218 // it requires the Frame Format
219 pGrfNd->SetTwipSize( rGrfSz );
220 }
221
222 return bRet;
223}
224
225bool SwBaseLink::SwapIn( bool bWaitForData, bool bNativFormat )
226{
227 if( !GetObj() && ( bNativFormat || ( !IsSynchron() && bWaitForData ) ))
228 {
229 AddNextRef();
231 ReleaseRef();
232 }
233
234 bool bRes = false;
235
236 if( GetObj() )
237 {
239 uno::Any aValue;
240 (void)GetObj()->GetData( aValue, aMimeType, !IsSynchron() && bWaitForData );
241
242 if( bWaitForData && !GetObj() )
243 {
244 OSL_ENSURE( false, "The SvxFileObject was deleted in a GetData!" );
245 }
246 else
247 {
248 bRes = aValue.hasValue();
249 if ( bRes )
250 {
251 DataChanged( aMimeType, aValue );
252 }
253 }
254 }
255 else if( !IsSynchron() && bWaitForData )
256 {
257 SetSynchron( true );
258 bRes = Update();
259 SetSynchron( false );
260 }
261 else
262 bRes = Update();
263
264 return bRes;
265}
266
268{
270 {
271 // Delete the connection
273 static_cast<SwGrfNode*>(m_pContentNode)->ReleaseLink();
274 }
275 SvBaseLink::Closed();
276}
277
279{
280 if (m_pContentNode)
281 {
282 SwFrameFormat *const pFormat = m_pContentNode->GetFlyFormat();
283 if (pFormat)
284 {
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())))
292 {
293 return pAnchorNode;
294 }
295 return nullptr;
296 }
297 }
298
299 OSL_ENSURE( false, "GetAnchor is not shadowed" );
300 return nullptr;
301}
302
303bool SwBaseLink::IsRecursion( const SwBaseLink* pChkLnk ) const
304{
305 tools::SvRef<SwServerObject> aRef( static_cast<SwServerObject*>(GetObj()) );
306 if( aRef.is() )
307 {
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 );
311 }
312 return false;
313}
314
316{
317 // Not Graphic or OLE Links
318 // Fields or Sections have their own derivation!
319 return false;
320}
321
323{
324}
325
326/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
GraphicType GetType() const
GraphicType GetType() const
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
virtual sfx2::LinkManager & GetLinkManager()=0
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
void setWidth(tools::Long nWidth)
tools::Long AdjustWidth(tools::Long n)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
static OUString GetFormatMimeType(SotClipboardFormatId nFormat)
static SotClipboardFormatId GetFormatIdFromMimeType(std::u16string_view rMimeType)
sal_Int16 CalcLineSpace(SvxBoxItemLine nLine, bool bEvenIfNoLine=false, bool bAllowNegative=false) const
const Size & GetSize() const
void SetSize(const Size &rSize)
Definition: doc.hxx:197
sal_uInt16 CallEvent(SvMacroItemId nEvent, const SwCallMouseEvent &rCallEvent, bool bChkPtr=false)
Definition: docbasic.cxx:130
bool IsInDtor() const
Definition: doc.hxx:417
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:274
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:330
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:419
FlyAnchors.
Definition: fmtanchr.hxx:37
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1614
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:108
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:88
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:447
Style of a layout element.
Definition: frmfmt.hxx:72
virtual Size GetTwipSize() const override
Definition: ndgrf.cxx:409
void SetGraphic(const Graphic &rGraphic)
isolated only way to set GraphicObject to allow more actions when doing so
Definition: ndgrf.cxx:346
void SetTwipSize(const Size &rSz)
Definition: ndgrf.cxx:608
const GraphicObject & GetGrfObj(bool bWait=false) const
Definition: ndgrf.cxx:364
bool IsChgTwipSize() const
Definition: ndgrf.hxx:93
bool IsFrameInPaint() const
Definition: ndgrf.hxx:99
void TriggerGraphicArrived()
Definition: ndgrf.cxx:352
bool Resize(sal_uInt16 nAbsAvail, bool bRecalc=false, bool bForce=false, sal_uLong nDelay=0)
Recalculation of table widths for available width that has been passed.
Definition: htmltbl.cxx:1697
sal_uInt16 GetBrowseWidthByTable(const SwDoc &rDoc) const
Calculates available width by the table-frame or static GetBrowseWidth if no layout exists.
Definition: htmltbl.cxx:375
Base class of the Writer document model elements.
Definition: node.hxx:98
bool IsGrfNode() const
Definition: node.hxx:195
SwFrameFormat * GetFlyFormat() const
If node is in a fly return the respective format.
Definition: node.cxx:738
SwGrfNode * GetGrfNode()
Definition: ndgrf.hxx:150
bool IsNoTextNode() const
Definition: node.hxx:194
SwDoc & GetDoc()
Definition: node.hxx:233
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:380
bool IsOLENode() const
Definition: node.hxx:193
const SwTable & GetTable() const
Definition: node.hxx:542
sal_uInt16 DecGrfsThatResize()
Definition: swtable.hxx:187
SwHTMLTableLayout * GetHTMLTableLayout()
Definition: swtable.hxx:182
static SotClipboardFormatId RegisterStatusInfoId()
bool GetGraphicFromAny(std::u16string_view rMimeType, const css::uno::Any &rValue, Graphic &rGrf, weld::Window *pParentWin)
virtual bool GetData(css::uno::Any &rData, const OUString &rMimeType, bool bSynchron=false)
bool is() const
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
Definition: dialoghelp.cxx:19
SvMacroItemId
SotClipboardFormatId
#define HTMLTABLE_RESIZE_NOW
Definition: htmltbl.hxx:36
const sal_Unicode *const aMimeType[]
void Set(SwCallEventObjectType eTyp, const SwFrameFormat *pFormat)
Definition: swevent.hxx:87
bool hasValue()
static bool SetGrfFlySize(const Size &rGrfSz, SwGrfNode *pGrfNd, const Size &rOrigGrfSize)
Definition: swbaslnk.cxx:146
@ EVENT_OBJECT_IMAGE
Definition: swevent.hxx:48
Size GetGraphicSizeTwip(const Graphic &rGraphic, vcl::RenderContext *pOutDev)
Definition: swtypes.cxx:28