LibreOffice Module sw (master)  1
ddefld.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 <sal/config.h>
21 
22 #include <o3tl/any.hxx>
23 #include <osl/diagnose.h>
24 #include <osl/thread.h>
25 #include <sfx2/linkmgr.hxx>
26 #include <sot/exchange.hxx>
27 #include <doc.hxx>
29 #include <IDocumentState.hxx>
31 #include <editsh.hxx>
32 #include <ndtxt.hxx>
33 #include <fmtfld.hxx>
34 #include <txtfld.hxx>
35 #include <ddefld.hxx>
36 #include <swtable.hxx>
37 #include <swbaslnk.hxx>
38 #include <swddetbl.hxx>
39 #include <unofldmid.h>
40 #include <hints.hxx>
41 #include <calbck.hxx>
42 
43 using namespace ::com::sun::star;
44 
45 #define DDE_TXT_ENCODING osl_getThreadTextEncoding()
46 
48 {
50 public:
52  : SwBaseLink( nUpdateType, SotClipboardFormatId::STRING ),
53  rFieldType( rType )
54  {}
55 
56  virtual void Closed() override;
57  virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
58  const OUString& rMimeType, const css::uno::Any & rValue ) override;
59 
60  virtual const SwNode* GetAnchor() const override;
61  virtual bool IsInRange( sal_uLong nSttNd, sal_uLong nEndNd ) const override;
62 };
63 
65  const uno::Any & rValue )
66 {
67  switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
68  {
69  case SotClipboardFormatId::STRING:
70  if( !IsNoDataFlag() )
71  {
72  uno::Sequence< sal_Int8 > aSeq;
73  rValue >>= aSeq;
74  OUString sStr( reinterpret_cast<char const *>(aSeq.getConstArray()), aSeq.getLength(), DDE_TXT_ENCODING );
75 
76  // remove not needed CR-LF at the end
77  sal_Int32 n = sStr.getLength();
78  while( n && 0 == sStr[ n-1 ] )
79  --n;
80  if( n && 0x0a == sStr[ n-1 ] )
81  --n;
82  if( n && 0x0d == sStr[ n-1 ] )
83  --n;
84 
85  bool bDel = n != sStr.getLength();
86  if( bDel )
87  sStr = sStr.copy( 0, n );
88 
89  rFieldType.SetExpansion( sStr );
90  // set Expansion first! (otherwise this flag will be deleted)
91  rFieldType.SetCRLFDelFlag( bDel );
92  }
93  break;
94 
95  // other formats
96  default:
97  return SUCCESS;
98  }
99 
100  OSL_ENSURE( rFieldType.GetDoc(), "no pDoc" );
101 
102  // no dependencies left?
104  {
107 
108  // Search for fields. If no valid found, disconnect.
109  SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
110  bool bCallModify = false;
112 
114  for(SwClient* pLast = aIter.First(); pLast; pLast = aIter.Next())
115  {
116  // a DDE table or a DDE field attribute in the text
117  if( dynamic_cast<const SwFormatField *>(pLast) == nullptr ||
118  static_cast<SwFormatField*>(pLast)->GetTextField() )
119  {
120  if( !bCallModify )
121  {
122  if( pESh )
123  pESh->StartAllAction();
124  else if( pSh )
125  pSh->StartAction();
126  }
127  pLast->ModifyNotification( nullptr, &aUpdateDDE );
128  bCallModify = true;
129  }
130  }
131 
133 
134  if( bCallModify )
135  {
136  if( pESh )
137  pESh->EndAllAction();
138  else if( pSh )
139  pSh->EndAction();
140 
141  if( pSh )
143  }
144  }
145 
146  return SUCCESS;
147 }
148 
150 {
151  if( rFieldType.GetDoc() && !rFieldType.GetDoc()->IsInDtor() )
152  {
153  // advise goes, convert all fields into text?
156  if( pESh )
157  {
158  pESh->StartAllAction();
159  pESh->FieldToText( &rFieldType );
160  pESh->EndAllAction();
161  }
162  else
163  {
164  pSh->StartAction();
165  // to call at the doc ??
166  pSh->EndAction();
167  }
168  }
169  SvBaseLink::Closed();
170 }
171 
173 
175 {
176  // here, any anchor of the normal NodesArray should be sufficient
177  const SwNode* pNd = nullptr;
178  rFieldType.CallSwClientNotify(sw::LinkAnchorSearchHint(rFieldType.GetDoc()->GetNodes(), pNd));
179  return pNd;
180 }
181 
182 bool SwIntrnlRefLink::IsInRange( sal_uLong nSttNd, sal_uLong nEndNd ) const
183 {
184  bool bInRange = false;
185  rFieldType.CallSwClientNotify(sw::InRangeSearchHint(
186  nSttNd, nEndNd, bInRange));
187  return bInRange;
188 }
189 
190 SwDDEFieldType::SwDDEFieldType(const OUString& rName,
191  const OUString& rCmd, SfxLinkUpdateMode nUpdateType )
192  : SwFieldType( SwFieldIds::Dde ),
193  aName( rName ), pDoc( nullptr ), nRefCnt( 0 )
194 {
195  bCRLFFlag = bDeleted = false;
196  refLink = new SwIntrnlRefLink( *this, nUpdateType );
197  SetCmd( rCmd );
198 }
199 
201 {
202  if( pDoc && !pDoc->IsInDtor() )
204  refLink->Disconnect();
205 }
206 
207 std::unique_ptr<SwFieldType> SwDDEFieldType::Copy() const
208 {
209  std::unique_ptr<SwDDEFieldType> pType(new SwDDEFieldType( aName, GetCmd(), GetType() ));
210  pType->aExpansion = aExpansion;
211  pType->bCRLFFlag = bCRLFFlag;
212  pType->bDeleted = bDeleted;
213  pType->SetDoc( pDoc );
214  return pType;
215 }
216 
217 OUString SwDDEFieldType::GetName() const
218 {
219  return aName;
220 }
221 
222 void SwDDEFieldType::SetCmd( const OUString& _aStr )
223 {
224  OUString aStr = _aStr;
225  sal_Int32 nIndex = 0;
226  do
227  {
228  aStr = aStr.replaceFirst(" ", " ", &nIndex);
229  } while (nIndex>=0);
230  refLink->SetLinkSourceName( aStr );
231 }
232 
233 OUString const & SwDDEFieldType::GetCmd() const
234 {
235  return refLink->GetLinkSourceName();
236 }
237 
239 {
240  if( pNewDoc == pDoc )
241  return;
242 
243  if( pDoc && refLink.is() )
244  {
245  OSL_ENSURE( !nRefCnt, "How do we get the references?" );
247  }
248 
249  pDoc = pNewDoc;
250  if( pDoc && nRefCnt )
251  {
254  }
255 }
256 
258 {
259  if( nRefCnt )
260  {
264  refLink->Update();
265  }
266  else
267  {
268  Disconnect();
270  }
271 }
272 
273 void SwDDEFieldType::QueryValue( uno::Any& rVal, sal_uInt16 nWhichId ) const
274 {
275  sal_Int32 nPart = -1;
276  switch( nWhichId )
277  {
278  case FIELD_PROP_PAR2: nPart = 2; break;
279  case FIELD_PROP_PAR4: nPart = 1; break;
280  case FIELD_PROP_SUBTYPE: nPart = 0; break;
281  case FIELD_PROP_BOOL1:
282  rVal <<= GetType() == SfxLinkUpdateMode::ALWAYS;
283  break;
284  case FIELD_PROP_PAR5:
285  rVal <<= aExpansion;
286  break;
287  default:
288  assert(false);
289  }
290  if ( nPart>=0 )
291  rVal <<= GetCmd().getToken(nPart, sfx2::cTokenSeparator);
292 }
293 
294 void SwDDEFieldType::PutValue( const uno::Any& rVal, sal_uInt16 nWhichId )
295 {
296  sal_Int32 nPart = -1;
297  switch( nWhichId )
298  {
299  case FIELD_PROP_PAR2: nPart = 2; break;
300  case FIELD_PROP_PAR4: nPart = 1; break;
301  case FIELD_PROP_SUBTYPE: nPart = 0; break;
302  case FIELD_PROP_BOOL1:
303  SetType( *o3tl::doAccess<bool>(rVal) ?
304  SfxLinkUpdateMode::ALWAYS :
305  SfxLinkUpdateMode::ONCALL );
306  break;
307  case FIELD_PROP_PAR5:
308  rVal >>= aExpansion;
309  break;
310  default:
311  assert(false);
312  }
313  if( nPart>=0 )
314  {
315  const OUString sOldCmd( GetCmd() );
316  OUStringBuffer sNewCmd;
317  sal_Int32 nIndex = 0;
318  for (sal_Int32 i=0; i<3; ++i)
319  {
320  OUString sToken = sOldCmd.getToken(0, sfx2::cTokenSeparator, nIndex);
321  if (i==nPart)
322  {
323  rVal >>= sToken;
324  }
325  sNewCmd.append((i < 2)
326  ? sToken + OUStringLiteral1(sfx2::cTokenSeparator) : sToken);
327  }
328  SetCmd( sNewCmd.makeStringAndClear() );
329  }
330 }
331 
333  : SwField(pInitType)
334 {
335 }
336 
338 {
339  if( GetTyp()->HasOnlyOneListener() )
340  static_cast<SwDDEFieldType*>(GetTyp())->Disconnect();
341 }
342 
343 OUString SwDDEField::ExpandImpl(SwRootFrame const*const) const
344 {
345  OUString aStr = static_cast<SwDDEFieldType*>(GetTyp())->GetExpansion();
346  aStr = aStr.replaceAll("\r", "");
347  aStr = aStr.replaceAll("\t", " ");
348  aStr = aStr.replaceAll("\n", "|");
349  if (aStr.endsWith("|"))
350  {
351  return aStr.copy(0, aStr.getLength()-1);
352  }
353  return aStr;
354 }
355 
356 std::unique_ptr<SwField> SwDDEField::Copy() const
357 {
358  return std::make_unique<SwDDEField>(static_cast<SwDDEFieldType*>(GetTyp()));
359 }
360 
362 OUString SwDDEField::GetPar1() const
363 {
364  return static_cast<const SwDDEFieldType*>(GetTyp())->GetName();
365 }
366 
368 OUString SwDDEField::GetPar2() const
369 {
370  return static_cast<const SwDDEFieldType*>(GetTyp())->GetCmd();
371 }
372 
374 void SwDDEField::SetPar2(const OUString& rStr)
375 {
376  static_cast<SwDDEFieldType*>(GetTyp())->SetCmd(rStr);
377 }
378 
379 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:233
bool is() const
sal_uInt16 nRefCnt
Definition: ddefld.hxx:59
virtual void SetPar2(const OUString &rStr) override
set field type command
Definition: ddefld.cxx:374
STRING
void SetCmd(const OUString &aStr)
Definition: ddefld.cxx:222
SwDDEFieldType(const OUString &rName, const OUString &rCmd, SfxLinkUpdateMode)
Definition: ddefld.cxx:190
#define FIELD_PROP_PAR5
Definition: unofldmid.h:43
virtual ~SwDDEField() override
Definition: ddefld.cxx:337
virtual void SetModified()=0
Must be called manually at changes of format.
sal_uIntPtr sal_uLong
const sal_Unicode cTokenSeparator
void SetType(SfxLinkUpdateMode nType)
Definition: ddefld.hxx:84
Base class of all fields.
Definition: fldbas.hxx:279
SfxLinkUpdateMode GetType() const
Definition: ddefld.hxx:83
Definition: doc.hxx:185
void Disconnect()
Definition: ddefld.hxx:89
TElementType * Next()
Definition: calbck.hxx:376
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:292
OUString const aName
Definition: ddefld.hxx:53
virtual ~LinkAnchorSearchHint() override
Definition: ddefld.cxx:172
bool HasWriterListeners() const
Definition: calbck.hxx:211
void EndAllAction()
Definition: edws.cxx:96
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
#define FIELD_PROP_SUBTYPE
Definition: unofldmid.h:27
#define RES_UPDATEDDETBL
Definition: hintids.hxx:293
OUString const & GetCmd() const
Definition: ddefld.cxx:233
const SwDoc * GetDoc() const
Definition: ddefld.hxx:94
virtual OUString ExpandImpl(SwRootFrame const *pLayout) const override
Definition: ddefld.cxx:343
SAL_DLLPRIVATE void RefCntChgd()
Definition: ddefld.cxx:257
bool bCRLFFlag
Definition: ddefld.hxx:60
void SetDoc(SwDoc *pDoc)
Definition: ddefld.cxx:238
virtual void PutValue(const css::uno::Any &rVal, sal_uInt16 nWhich) override
Definition: ddefld.cxx:294
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
SotClipboardFormatId
virtual std::unique_ptr< SwFieldType > Copy() const override
Definition: ddefld.cxx:207
void SetCRLFDelFlag(bool bFlag)
Definition: ddefld.hxx:101
T * get() const
#define DDE_TXT_ENCODING
Definition: ddefld.cxx:45
SwDoc * pDoc
Definition: ddefld.hxx:57
void Remove(SvBaseLink const *pLink)
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:323
virtual OUString GetPar1() const override
Get parameter via types.
Definition: ddefld.cxx:362
TElementType * First()
Definition: calbck.hxx:345
int i
SwFieldIds
Definition: fldbas.hxx:38
virtual OUString GetPar2() const override
get field type command
Definition: ddefld.cxx:368
void StartAction()
Definition: viewsh.hxx:592
void UnlockModify()
Definition: calbck.hxx:217
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:426
void LockModify()
Definition: calbck.hxx:216
SwDDEField(SwDDEFieldType *)
Definition: ddefld.cxx:332
bool bDeleted
Definition: ddefld.hxx:61
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:437
void InsertDDELink(SvBaseLink *, const OUString &rServer, const OUString &rTopic, const OUString &rItem)
SwFieldType * GetTyp() const
Definition: fldbas.hxx:382
void EndAction(const bool bIdleEnd=false)
Definition: viewsh.hxx:597
#define FIELD_PROP_BOOL1
Definition: unofldmid.h:28
bool IsModifyLocked() const
Definition: calbck.hxx:221
void SetExpansion(const OUString &rStr)
Definition: ddefld.hxx:71
void FieldToText(SwFieldType const *pType)
Definition: edfld.cxx:127
OUString aExpansion
Definition: ddefld.hxx:54
#define FIELD_PROP_PAR2
Definition: unofldmid.h:24
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
static SotClipboardFormatId GetFormatIdFromMimeType(const OUString &rMimeType)
tools::SvRef< sfx2::SvBaseLink > refLink
Definition: ddefld.hxx:56
virtual sfx2::LinkManager & GetLinkManager()=0
OString const aName
bool IsInDtor() const
Definition: doc.hxx:398
#define FIELD_PROP_PAR4
Definition: unofldmid.h:36
virtual std::unique_ptr< SwField > Copy() const override
Definition: ddefld.cxx:356
virtual ~SwDDEFieldType() override
Definition: ddefld.cxx:200
void StartAllAction()
For all views of this document.
Definition: edws.cxx:85
virtual OUString GetName() const override
Only in derived classes.
Definition: ddefld.cxx:217
aStr
virtual void QueryValue(css::uno::Any &rVal, sal_uInt16 nWhich) const override
Definition: ddefld.cxx:273
SfxLinkUpdateMode
virtual bool IsVisibleLinks() const =0
Insert links in-/visibly into LinkManager (linked ranges).
Base class of the Writer document model elements.
Definition: node.hxx:79