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 
46 using namespace com::sun::star;
47 
48 static 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 
68  if( m_pContentNode->IsNoTextNode() &&
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 
101  if (m_pContentNode->IsGrfNode())
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 
146 static 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  const SwPosition* pAPos = pFormat->GetAnchor().GetContentAnchor();
196  SwTableNode *pTableNd;
197  if (pAPos && nullptr != (pTableNd = pAPos->nNode.GetNode().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 
225 bool SwBaseLink::SwapIn( bool bWaitForData, bool bNativFormat )
226 {
227  if( !GetObj() && ( bNativFormat || ( !IsSynchron() && bWaitForData ) ))
228  {
229  AddNextRef();
230  GetRealObject_();
231  ReleaseRef();
232  }
233 
234  bool bRes = false;
235 
236  if( GetObj() )
237  {
238  OUString aMimeType( SotExchange::GetFormatMimeType( GetContentType() ));
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 {
269  if( m_pContentNode && !m_pContentNode->GetDoc().IsInDtor() )
270  {
271  // Delete the connection
272  if( m_pContentNode->IsGrfNode() )
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  SwPosition const*const pAPos = rAnchor.GetContentAnchor();
287  if (pAPos &&
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 &pAPos->nNode.GetNode();
294  }
295  return nullptr;
296  }
297  }
298 
299  OSL_ENSURE( false, "GetAnchor is not shadowed" );
300  return nullptr;
301 }
302 
303 bool 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: */
bool is() const
bool hasValue()
Marks a position in the document model.
Definition: pam.hxx:35
bool IsLinkInServer(const SwBaseLink *) const
Definition: swserv.cxx:181
void setWidth(tools::Long nWidth)
SwNodeIndex nNode
Definition: pam.hxx:37
sal_uIntPtr sal_uLong
bool IsFrameInPaint() const
Definition: ndgrf.hxx:103
Definition: doc.hxx:186
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:260
SvMacroItemId
SwNode & GetNode() const
Definition: ndindex.hxx:119
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:84
sal_uInt16 CallEvent(SvMacroItemId nEvent, const SwCallMouseEvent &rCallEvent, bool bChkPtr=false)
Definition: docbasic.cxx:130
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
const SwTable & GetTable() const
Definition: node.hxx:500
SotClipboardFormatId
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
Definition: dialoghelp.cxx:19
static bool SetGrfFlySize(const Size &rGrfSz, SwGrfNode *pGrfNd, const Size &rOrigGrfSize)
Definition: swbaslnk.cxx:146
sal_uInt16 GetBrowseWidthByTable(const SwDoc &rDoc) const
Calculates available width by the table-frame or static GetBrowseWidth if no layout exists...
Definition: htmltbl.cxx:373
Style of a layout element.
Definition: frmfmt.hxx:58
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
SwDoc & GetDoc()
Definition: node.hxx:211
void SetGraphic(const Graphic &rGraphic)
isolated only way to set GraphicObject to allow more actions when doing so
Definition: ndgrf.cxx:361
GraphicType GetType() const
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:328
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
FlyAnchors.
Definition: fmtanchr.hxx:34
bool IsChgTwipSize() const
Definition: ndgrf.hxx:97
tools::Long Width() const
const char *const aMimeType[]
void TriggerGraphicArrived()
Definition: ndgrf.cxx:367
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:1694
static OUString GetFormatMimeType(SotClipboardFormatId nFormat)
void SetTwipSize(const Size &rSz)
Definition: ndgrf.cxx:632
bool GetGraphicFromAny(const OUString &rMimeType, const css::uno::Any &rValue, Graphic &rGrf, weld::Window *pParentWin)
const GraphicObject & GetGrfObj(bool bWait=false) const
Definition: ndgrf.cxx:379
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
GraphicType GetType() const
virtual Size GetTwipSize() const override
Definition: ndgrf.cxx:432
void Set(SwCallEventObjectType eTyp, const SwFrameFormat *pFormat)
Definition: swevent.hxx:87
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:463
sal_uInt16 DecGrfsThatResize()
Definition: swtable.hxx:181
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
static SotClipboardFormatId GetFormatIdFromMimeType(const OUString &rMimeType)
SwHTMLTableLayout * GetHTMLTableLayout()
Definition: swtable.hxx:176
tools::Long AdjustWidth(tools::Long n)
tools::Long Height() const
void SetSize(const Size &rSize)
tools::Long AdjustHeight(tools::Long n)
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:355
sal_uInt16 CalcLineSpace(SvxBoxItemLine nLine, bool bEvenIfNoLine=false) const
virtual sfx2::LinkManager & GetLinkManager()=0
void setHeight(tools::Long nHeight)
bool IsInDtor() const
Definition: doc.hxx:402
SwGrfNode * GetGrfNode()
Definition: ndgrf.hxx:154
static SotClipboardFormatId RegisterStatusInfoId()
SwFrameFormat * GetFlyFormat() const
If node is in a fly return the respective format.
Definition: node.cxx:717
#define HTMLTABLE_RESIZE_NOW
Definition: htmltbl.hxx:36
const Size & GetSize() const
Size GetGraphicSizeTwip(const Graphic &rGraphic, vcl::RenderContext *pOutDev)
Definition: swtypes.cxx:28
Base class of the Writer document model elements.
Definition: node.hxx:79
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo