LibreOffice Module sw (master)  1
bookmrk.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 <memory>
21 #include <bookmrk.hxx>
22 #include <IDocumentUndoRedo.hxx>
24 #include <IDocumentState.hxx>
25 #include <doc.hxx>
26 #include <ndtxt.hxx>
27 #include <pam.hxx>
28 #include <swserv.hxx>
29 #include <sfx2/linkmgr.hxx>
30 #include <UndoBookmark.hxx>
31 #include <unobookmark.hxx>
32 #include <xmloff/odffields.hxx>
33 #include <libxml/xmlwriter.h>
34 #include <comphelper/random.hxx>
36 #include <sal/log.hxx>
37 #include <svl/zforlist.hxx>
38 #include <edtwin.hxx>
39 #include <DateFormFieldButton.hxx>
42 
43 using namespace ::sw::mark;
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 
47 namespace sw::mark
48 {
49 
51  {
52  SwPosition const& rStartPos(rMark.GetMarkStart());
53  SwPosition const& rEndPos(rMark.GetMarkEnd());
54  SwNodes const& rNodes(rStartPos.nNode.GetNodes());
55  sal_uLong const nStartNode(rStartPos.nNode.GetIndex());
56  sal_uLong const nEndNode(rEndPos.nNode.GetIndex());
57  int nFields(0);
58  std::optional<SwPosition> ret;
59  for (sal_uLong n = nEndNode; nStartNode <= n; --n)
60  {
61  SwNode *const pNode(rNodes[n]);
62  if (pNode->IsTextNode())
63  {
64  SwTextNode & rTextNode(*pNode->GetTextNode());
65  sal_Int32 const nStart(n == nStartNode
66  ? rStartPos.nContent.GetIndex() + 1
67  : 0);
68  sal_Int32 const nEnd(n == nEndNode
69  // subtract 1 to ignore the end char
70  ? rEndPos.nContent.GetIndex() - 1
71  : rTextNode.Len());
72  for (sal_Int32 i = nEnd; nStart < i; --i)
73  {
74  const sal_Unicode c(rTextNode.GetText()[i - 1]);
75  switch (c)
76  {
78  --nFields;
79  assert(0 <= nFields);
80  break;
82  ++nFields;
83  // fields in field result could happen by manual
84  // editing, although the field update deletes them
85  break;
87  if (nFields == 0)
88  {
89  assert(!ret); // one per field
90  ret = SwPosition(rTextNode, i - 1);
91 #ifndef DBG_UTIL
92  return *ret;
93 #endif
94  }
95  break;
96  }
97  }
98  }
99  else if (pNode->IsEndNode())
100  {
101  assert(nStartNode <= pNode->StartOfSectionIndex());
102  // fieldmark cannot overlap node section
103  n = pNode->StartOfSectionIndex();
104  }
105  else
106  {
107  assert(pNode->IsNoTextNode());
108  }
109  }
110  assert(ret); // must have found it
111  return *ret;
112  }
113 } // namespace sw::mark
114 
115 namespace
116 {
117  void lcl_FixPosition(SwPosition& rPos)
118  {
119  // make sure the position has 1) the proper node, and 2) a proper index
120  SwTextNode* pTextNode = rPos.nNode.GetNode().GetTextNode();
121  if(pTextNode == nullptr && rPos.nContent.GetIndex() > 0)
122  {
123  SAL_INFO(
124  "sw.core",
125  "illegal position: " << rPos.nContent.GetIndex()
126  << " without proper TextNode");
127  rPos.nContent.Assign(nullptr, 0);
128  }
129  else if(pTextNode != nullptr && rPos.nContent.GetIndex() > pTextNode->Len())
130  {
131  SAL_INFO(
132  "sw.core",
133  "illegal position: " << rPos.nContent.GetIndex()
134  << " is beyond " << pTextNode->Len());
135  rPos.nContent.Assign(pTextNode, pTextNode->Len());
136  }
137  }
138 
139  void lcl_AssertFieldMarksSet(Fieldmark const * const pField,
140  const sal_Unicode aStartMark,
141  const sal_Unicode aEndMark)
142  {
143  if (aEndMark != CH_TXT_ATR_FORMELEMENT)
144  {
145  SwPosition const& rStart(pField->GetMarkStart());
146  assert(rStart.nNode.GetNode().GetTextNode()->GetText()[rStart.nContent.GetIndex()] == aStartMark); (void) rStart; (void) aStartMark;
147  SwPosition const sepPos(sw::mark::FindFieldSep(*pField));
148  assert(sepPos.nNode.GetNode().GetTextNode()->GetText()[sepPos.nContent.GetIndex()] == CH_TXT_ATR_FIELDSEP); (void) sepPos;
149  }
150  SwPosition const& rEnd(pField->GetMarkEnd());
151  assert(rEnd.nNode.GetNode().GetTextNode()->GetText()[rEnd.nContent.GetIndex() - 1] == aEndMark); (void) rEnd;
152  }
153 
154  void lcl_SetFieldMarks(Fieldmark* const pField,
155  SwDoc* const io_pDoc,
156  const sal_Unicode aStartMark,
157  const sal_Unicode aEndMark,
158  SwPosition const*const pSepPos)
159  {
161  OUString startChar(aStartMark);
162  if (aEndMark != CH_TXT_ATR_FORMELEMENT
163  && pField->GetMarkStart() == pField->GetMarkEnd())
164  {
165  // do only 1 InsertString call - to expand existing bookmarks at the
166  // position over the whole field instead of just aStartMark
167  startChar += OUStringChar(CH_TXT_ATR_FIELDSEP) + OUStringChar(aEndMark);
168  }
169 
170  SwPosition start = pField->GetMarkStart();
171  if (aEndMark != CH_TXT_ATR_FORMELEMENT)
172  {
173  SwPaM aStartPaM(start);
174  io_pDoc->getIDocumentContentOperations().InsertString(aStartPaM, startChar);
175  start.nContent -= startChar.getLength(); // restore, it was moved by InsertString
176  // do not manipulate via reference directly but call SetMarkStartPos
177  // which works even if start and end pos were the same
178  pField->SetMarkStartPos( start );
179  SwPosition& rEnd = pField->GetMarkEnd(); // note: retrieve after
180  // setting start, because if start==end it can go stale, see SetMarkPos()
181  assert(pSepPos == nullptr || (start < *pSepPos && *pSepPos <= rEnd));
182  if (startChar.getLength() == 1)
183  {
184  *aStartPaM.GetPoint() = pSepPos ? *pSepPos : rEnd;
185  io_pDoc->getIDocumentContentOperations().InsertString(aStartPaM, OUString(CH_TXT_ATR_FIELDSEP));
186  if (!pSepPos || rEnd < *pSepPos)
187  { // rEnd is not moved automatically if it's same as insert pos
188  ++rEnd.nContent;
189  }
190  }
191  assert(pSepPos == nullptr || (start < *pSepPos && *pSepPos <= rEnd));
192  }
193  else
194  {
195  assert(pSepPos == nullptr);
196  }
197 
198  SwPosition& rEnd = pField->GetMarkEnd();
199  if (aEndMark && startChar.getLength() == 1)
200  {
201  SwPaM aEndPaM(rEnd);
202  io_pDoc->getIDocumentContentOperations().InsertString(aEndPaM, OUString(aEndMark));
203  ++rEnd.nContent;
204  }
205  lcl_AssertFieldMarksSet(pField, aStartMark, aEndMark);
206 
208  };
209 
210  void lcl_RemoveFieldMarks(Fieldmark const * const pField,
211  SwDoc* const io_pDoc,
212  const sal_Unicode aStartMark,
213  const sal_Unicode aEndMark)
214  {
216 
217  const SwPosition& rStart = pField->GetMarkStart();
218  SwTextNode const*const pStartTextNode = rStart.nNode.GetNode().GetTextNode();
219  assert(pStartTextNode);
220  if (aEndMark != CH_TXT_ATR_FORMELEMENT)
221  {
222  (void) pStartTextNode;
223  // check this before start / end because of the +1 / -1 ...
224  SwPosition const sepPos(sw::mark::FindFieldSep(*pField));
225  io_pDoc->GetDocumentContentOperationsManager().DeleteDummyChar(rStart, aStartMark);
227  }
228 
229  const SwPosition& rEnd = pField->GetMarkEnd();
230  SwTextNode *const pEndTextNode = rEnd.nNode.GetNode().GetTextNode();
231  assert(pEndTextNode);
232  const sal_Int32 nEndPos = (rEnd == rStart)
233  ? rEnd.nContent.GetIndex()
234  : rEnd.nContent.GetIndex() - 1;
235  assert(pEndTextNode->GetText()[nEndPos] == aEndMark);
236  SwPosition const aEnd(*pEndTextNode, nEndPos);
237  io_pDoc->GetDocumentContentOperationsManager().DeleteDummyChar(aEnd, aEndMark);
238 
240  };
241 
242  auto InvalidatePosition(SwPosition const& rPos) -> void
243  {
244  SwUpdateAttr const hint(rPos.nContent.GetIndex(), rPos.nContent.GetIndex(), 0);
245  rPos.nNode.GetNode().GetTextNode()->NotifyClients(nullptr, &hint);
246  }
247 }
248 
249 namespace sw::mark
250 {
252  const OUString& rName)
253  : m_pPos1(new SwPosition(*(aPaM.GetPoint())))
254  , m_aName(rName)
255  {
256  m_pPos1->nContent.SetMark(this);
257  lcl_FixPosition(*m_pPos1);
258  if (aPaM.HasMark() && (*aPaM.GetMark() != *aPaM.GetPoint()))
259  {
261  lcl_FixPosition(*m_pPos2);
262  }
263  }
264 
265  // For fieldmarks, the CH_TXT_ATR_FIELDSTART and CH_TXT_ATR_FIELDEND
266  // themselves are part of the covered range. This is guaranteed by
267  // TextFieldmark::InitDoc/lcl_AssureFieldMarksSet.
268  bool MarkBase::IsCoveringPosition(const SwPosition& rPos) const
269  {
270  return GetMarkStart() <= rPos && rPos < GetMarkEnd();
271  }
272 
273  void MarkBase::SetMarkPos(const SwPosition& rNewPos)
274  {
275  std::make_unique<SwPosition>(rNewPos).swap(m_pPos1);
276  m_pPos1->nContent.SetMark(this);
277  }
278 
280  {
281  std::make_unique<SwPosition>(rNewPos).swap(m_pPos2);
282  m_pPos2->nContent.SetMark(this);
283  }
284 
285  OUString MarkBase::ToString( ) const
286  {
287  return "Mark: ( Name, [ Node1, Index1 ] ): ( " + m_aName + ", [ "
288  + OUString::number( GetMarkPos().nNode.GetIndex( ) ) + ", "
289  + OUString::number( GetMarkPos().nContent.GetIndex( ) ) + " ] )";
290  }
291 
293  {
294  xmlTextWriterStartElement(pWriter, BAD_CAST("MarkBase"));
295  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(m_aName.toUtf8().getStr()));
296  xmlTextWriterStartElement(pWriter, BAD_CAST("markPos"));
297  GetMarkPos().dumpAsXml(pWriter);
298  xmlTextWriterEndElement(pWriter);
299  if (IsExpanded())
300  {
301  xmlTextWriterStartElement(pWriter, BAD_CAST("otherMarkPos"));
302  GetOtherMarkPos().dumpAsXml(pWriter);
303  xmlTextWriterEndElement(pWriter);
304  }
305  xmlTextWriterEndElement(pWriter);
306  }
307 
309  { }
310 
311  OUString MarkBase::GenerateNewName(const OUString& rPrefix)
312  {
313  static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != nullptr);
314 
315  if (bHack)
316  {
317  static sal_Int64 nIdCounter = SAL_CONST_INT64(6000000000);
318  return rPrefix + OUString::number(nIdCounter++);
319  }
320  else
321  {
322  static OUString sUniquePostfix;
323  static sal_Int32 nCount = SAL_MAX_INT32;
324  if(nCount == SAL_MAX_INT32)
325  {
326  unsigned int const n(comphelper::rng::uniform_uint_distribution(0,
327  std::numeric_limits<unsigned int>::max()));
328  sUniquePostfix = "_" + OUString::number(n);
329  nCount = 0;
330  }
331  // putting the counter in front of the random parts will speed up string comparisons
332  return rPrefix + OUString::number(nCount++) + sUniquePostfix;
333  }
334  }
335 
336  void MarkBase::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew )
337  {
338  NotifyClients(pOld, pNew);
339  if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
340  { // invalidate cached uno object
341  SetXBookmark(uno::Reference<text::XTextContent>(nullptr));
342  }
343  }
344 
346  {
347  }
348 
350  : MarkBase(rPaM, MarkBase::GenerateNewName("__NavigatorReminder__"))
351  { }
352 
353  UnoMark::UnoMark(const SwPaM& aPaM)
354  : MarkBase(aPaM, MarkBase::GenerateNewName("__UnoMark__"))
355  { }
356 
358  : MarkBase(aPaM, MarkBase::GenerateNewName("__DdeLink__"))
359  { }
360 
362  {
363  m_aRefObj = pObj;
364  }
365 
367  {
368  if(m_aRefObj.is())
370  }
371 
373  {
374  if( m_aRefObj.is() )
375  {
376  if(m_aRefObj->HasDataLinks())
377  {
379  p->SendDataChanged();
380  }
382  }
383  }
384 
386  const vcl::KeyCode& rCode,
387  const OUString& rName)
388  : DdeBookmark(aPaM)
389  , ::sfx2::Metadatable()
390  , m_aCode(rCode)
391  , m_bHidden(false)
392  {
393  m_aName = rName;
394  }
395 
396  void Bookmark::InitDoc(SwDoc* const io_pDoc,
397  sw::mark::InsertMode const, SwPosition const*const)
398  {
399  if (io_pDoc->GetIDocumentUndoRedo().DoesUndo())
400  {
401  io_pDoc->GetIDocumentUndoRedo().AppendUndo(
402  std::make_unique<SwUndoInsBookmark>(*this));
403  }
404  io_pDoc->getIDocumentState().SetModified();
406  }
407 
408  void Bookmark::DeregisterFromDoc(SwDoc* const io_pDoc)
409  {
411 
412  if (io_pDoc->GetIDocumentUndoRedo().DoesUndo())
413  {
414  io_pDoc->GetIDocumentUndoRedo().AppendUndo(
415  std::make_unique<SwUndoDeleteBookmark>(*this));
416  }
417  io_pDoc->getIDocumentState().SetModified();
419  }
420 
421  // invalidate text frames in case it's hidden or Formatting Marks enabled
423  {
424  InvalidatePosition(GetMarkPos());
425  if (IsExpanded())
426  {
427  InvalidatePosition(GetOtherMarkPos());
428  }
429  }
430 
431  void Bookmark::Hide(bool const isHide)
432  {
433  if (isHide != m_bHidden)
434  {
435  m_bHidden = isHide;
437  }
438  }
439 
440  void Bookmark::SetHideCondition(OUString const& rHideCondition)
441  {
442  if (m_sHideCondition != rHideCondition)
443  {
444  m_sHideCondition = rHideCondition;
446  }
447  }
448 
450  {
451  SwDoc *const pDoc( GetMarkPos().GetDoc() );
452  assert(pDoc);
453  return pDoc->GetXmlIdRegistry();
454  }
455 
457  {
458  SwDoc *const pDoc( GetMarkPos().GetDoc() );
459  assert(pDoc);
460  return pDoc->IsClipBoard();
461  }
462 
463  bool Bookmark::IsInUndo() const
464  {
465  return false;
466  }
467 
469  {
470  SwDoc *const pDoc( GetMarkPos().GetDoc() );
471  assert(pDoc);
472  return !pDoc->IsInHeaderFooter( GetMarkPos().nNode );
473  }
474 
475  uno::Reference< rdf::XMetadatable > Bookmark::MakeUnoObject()
476  {
477  SwDoc *const pDoc( GetMarkPos().GetDoc() );
478  assert(pDoc);
479  const uno::Reference< rdf::XMetadatable> xMeta(
480  SwXBookmark::CreateXBookmark(*pDoc, this), uno::UNO_QUERY);
481  return xMeta;
482  }
483 
485  : MarkBase(rPaM, MarkBase::GenerateNewName("__Fieldmark__"))
486  {
487  if(!IsExpanded())
489  }
490 
491  void Fieldmark::SetMarkStartPos( const SwPosition& rNewStartPos )
492  {
493  if ( GetMarkPos( ) <= GetOtherMarkPos( ) )
494  return SetMarkPos( rNewStartPos );
495  else
496  return SetOtherMarkPos( rNewStartPos );
497  }
498 
499  void Fieldmark::SetMarkEndPos( const SwPosition& rNewEndPos )
500  {
501  if ( GetMarkPos( ) <= GetOtherMarkPos( ) )
502  return SetOtherMarkPos( rNewEndPos );
503  else
504  return SetMarkPos( rNewEndPos );
505  }
506 
507  OUString Fieldmark::ToString( ) const
508  {
509  return "Fieldmark: ( Name, Type, [ Nd1, Id1 ], [ Nd2, Id2 ] ): ( " + m_aName + ", "
510  + m_aFieldname + ", [ " + OUString::number( GetMarkPos().nNode.GetIndex( ) )
511  + ", " + OUString::number( GetMarkPos( ).nContent.GetIndex( ) ) + " ], ["
512  + OUString::number( GetOtherMarkPos().nNode.GetIndex( ) ) + ", "
513  + OUString::number( GetOtherMarkPos( ).nContent.GetIndex( ) ) + " ] ) ";
514  }
515 
517  {
518  // TODO: Does exist a better solution to trigger a format of the
519  // fieldmark portion? If yes, please use it.
520  SwPaM aPaM( GetMarkPos(), GetOtherMarkPos() );
521  aPaM.InvalidatePaM();
522  }
523 
525  {
526  xmlTextWriterStartElement(pWriter, BAD_CAST("Fieldmark"));
527  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("fieldname"), BAD_CAST(m_aFieldname.toUtf8().getStr()));
528  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("fieldHelptext"), BAD_CAST(m_aFieldHelptext.toUtf8().getStr()));
529  MarkBase::dumpAsXml(pWriter);
530  xmlTextWriterStartElement(pWriter, BAD_CAST("parameters"));
531  for (auto& rParam : m_vParams)
532  {
533  xmlTextWriterStartElement(pWriter, BAD_CAST("parameter"));
534  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(rParam.first.toUtf8().getStr()));
535  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(comphelper::anyToString(rParam.second).toUtf8().getStr()));
536  xmlTextWriterEndElement(pWriter);
537  }
538  xmlTextWriterEndElement(pWriter);
539  xmlTextWriterEndElement(pWriter);
540  }
541 
542  TextFieldmark::TextFieldmark(const SwPaM& rPaM, const OUString& rName)
543  : Fieldmark(rPaM)
544  {
545  if ( !rName.isEmpty() )
546  m_aName = rName;
547  }
548 
549  void TextFieldmark::InitDoc(SwDoc* const io_pDoc,
550  sw::mark::InsertMode const eMode, SwPosition const*const pSepPos)
551  {
552  if (eMode == sw::mark::InsertMode::New)
553  {
554  lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND, pSepPos);
555  // no need to invalidate text frames here, the insertion of the
556  // CH_TXT_ATR already invalidates
557  }
558  else
559  {
560  lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
561  }
562  }
563 
565  {
566  IDocumentUndoRedo & rIDUR(pDoc->GetIDocumentUndoRedo());
567  if (rIDUR.DoesUndo())
568  {
569  rIDUR.AppendUndo(std::make_unique<SwUndoDelTextFieldmark>(*this));
570  }
571  ::sw::UndoGuard const ug(rIDUR); // prevent SwUndoDeletes
572  lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
573  }
574 
576  : Fieldmark(rPaM)
577  { }
578 
579  void NonTextFieldmark::InitDoc(SwDoc* const io_pDoc,
580  sw::mark::InsertMode const eMode, SwPosition const*const pSepPos)
581  {
582  assert(pSepPos == nullptr);
583  if (eMode == sw::mark::InsertMode::New)
584  {
585  lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT, pSepPos);
586 
587  // For some reason the end mark is moved from 1 by the Insert:
588  // we don't want this for checkboxes
589  SwPosition aNewEndPos = GetMarkEnd();
590  aNewEndPos.nContent--;
591  SetMarkEndPos( aNewEndPos );
592  }
593  else
594  {
595  lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
596  }
597  }
598 
600  {
601  IDocumentUndoRedo & rIDUR(pDoc->GetIDocumentUndoRedo());
602  if (rIDUR.DoesUndo())
603  {
604  rIDUR.AppendUndo(std::make_unique<SwUndoDelNoTextFieldmark>(*this));
605  }
606  ::sw::UndoGuard const ug(rIDUR); // prevent SwUndoDeletes
607  lcl_RemoveFieldMarks(this, pDoc,
609  }
610 
611 
613  : NonTextFieldmark(rPaM)
614  { }
615 
616  void CheckboxFieldmark::SetChecked(bool checked)
617  {
618  if ( IsChecked() != checked )
619  {
620  (*GetParameters())[OUString(ODF_FORMCHECKBOX_RESULT)] <<= checked;
621  // mark document as modified
622  SwDoc *const pDoc( GetMarkPos().GetDoc() );
623  if ( pDoc )
624  pDoc->getIDocumentState().SetModified();
625  }
626  }
627 
629  {
630  bool bResult = false;
631  parameter_map_t::const_iterator pResult = GetParameters()->find(OUString(ODF_FORMCHECKBOX_RESULT));
632  if(pResult != GetParameters()->end())
633  pResult->second >>= bResult;
634  return bResult;
635  }
636 
638  : NonTextFieldmark(rPaM)
639  , m_pButton(nullptr)
640  {
641  }
642 
644  {
646  }
647 
649  {
650  if(m_pButton)
651  m_pButton->Show(false);
652  }
653 
655  {
656  if(m_pButton)
658  }
659 
662  {
663  }
664 
666  {
667  }
668 
670  {
671  if(pEditWin)
672  {
673  if(!m_pButton)
676  m_pButton->Show();
677  }
678  }
679 
680  void DropDownFieldmark::SetPortionPaintArea(const SwRect& rPortionPaintArea)
681  {
682  if(m_aPortionPaintArea == rPortionPaintArea &&
684  return;
685 
686  m_aPortionPaintArea = rPortionPaintArea;
687  if(m_pButton)
688  {
689  m_pButton->Show();
692  }
693  }
694 
697  , m_pNumberFormatter(nullptr)
698  , m_pDocumentContentOperationsManager(nullptr)
699  {
700  }
701 
703  {
704  }
705 
706  void DateFieldmark::InitDoc(SwDoc* const io_pDoc,
707  sw::mark::InsertMode eMode, SwPosition const*const pSepPos)
708  {
711  if (eMode == sw::mark::InsertMode::New)
712  {
713  lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND, pSepPos);
714  }
715  else
716  {
717  lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
718  }
719  }
720 
722  {
723  IDocumentUndoRedo & rIDUR(pDoc->GetIDocumentUndoRedo());
724  if (rIDUR.DoesUndo())
725  {
726  // TODO does this need a 3rd Undo class?
727  rIDUR.AppendUndo(std::make_unique<SwUndoDelTextFieldmark>(*this));
728  }
729  ::sw::UndoGuard const ug(rIDUR); // prevent SwUndoDeletes
730  lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
731  }
732 
734  {
735  if(pEditWin)
736  {
737  if(!m_pButton)
740  m_pButton->CalcPosAndSize(aPaintArea);
741  m_pButton->Show();
742  }
743  }
744 
745  void DateFieldmark::SetPortionPaintAreaStart(const SwRect& rPortionPaintArea)
746  {
747  if (rPortionPaintArea.IsEmpty())
748  return;
749 
750  m_aPaintAreaStart = rPortionPaintArea;
752  }
753 
754  void DateFieldmark::SetPortionPaintAreaEnd(const SwRect& rPortionPaintArea)
755  {
756  if (rPortionPaintArea.IsEmpty())
757  return;
758 
759  if(m_aPaintAreaEnd == rPortionPaintArea &&
761  return;
762 
763  m_aPaintAreaEnd = rPortionPaintArea;
764  if(m_pButton)
765  {
766  m_pButton->Show();
768  m_pButton->CalcPosAndSize(aPaintArea);
770  }
772  }
773 
774  OUString DateFieldmark::GetContent() const
775  {
776  const SwTextNode* const pTextNode = GetMarkEnd().nNode.GetNode().GetTextNode();
777  SwPosition const sepPos(sw::mark::FindFieldSep(*this));
778  const sal_Int32 nStart(sepPos.nContent.GetIndex());
779  const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex());
780 
781  OUString sContent;
782  if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength() &&
783  nEnd > nStart + 2)
784  sContent = pTextNode->GetText().copy(nStart + 1, nEnd - nStart - 2);
785  return sContent;
786  }
787 
788  void DateFieldmark::ReplaceContent(const OUString& sNewContent)
789  {
791  return;
792 
793  const SwTextNode* const pTextNode = GetMarkEnd().nNode.GetNode().GetTextNode();
794  SwPosition const sepPos(sw::mark::FindFieldSep(*this));
795  const sal_Int32 nStart(sepPos.nContent.GetIndex());
796  const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex());
797 
798  if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength() &&
799  nEnd > nStart + 2)
800  {
801  SwPaM aFieldPam(GetMarkStart().nNode, nStart + 1,
802  GetMarkStart().nNode, nEnd - 1);
803  m_pDocumentContentOperationsManager->ReplaceRange(aFieldPam, sNewContent, false);
804  }
805  else
806  {
807  SwPaM aFieldStartPam(GetMarkStart().nNode, nStart + 1);
808  m_pDocumentContentOperationsManager->InsertString(aFieldStartPam, sNewContent);
809  }
810 
811  }
812 
813  std::pair<bool, double> DateFieldmark::GetCurrentDate() const
814  {
815  // Check current date param first
816  std::pair<bool, double> aResult = ParseCurrentDateParam();
817  if(aResult.first)
818  return aResult;
819 
821  bool bFoundValidDate = false;
822  double dCurrentDate = 0;
823  OUString sDateFormat;
824  auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
825  if (pResult != pParameters->end())
826  {
827  pResult->second >>= sDateFormat;
828  }
829 
830  OUString sLang;
831  pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
832  if (pResult != pParameters->end())
833  {
834  pResult->second >>= sLang;
835  }
836 
837  // Get current content of the field
838  OUString sContent = GetContent();
839 
840  sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
841  if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
842  {
843  sal_Int32 nCheckPos = 0;
845  m_pNumberFormatter->PutEntry(sDateFormat,
846  nCheckPos,
847  nType,
848  nFormat,
849  LanguageTag(sLang).getLanguageType());
850  }
851 
852  if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
853  {
854  bFoundValidDate = m_pNumberFormatter->IsNumberFormat(sContent, nFormat, dCurrentDate);
855  }
856  return std::pair<bool, double>(bFoundValidDate, dCurrentDate);
857  }
858 
859  void DateFieldmark::SetCurrentDate(double fDate)
860  {
861  // Replace current content with the selected date
863 
864  // Also save the current date in a standard format
866  (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= GetDateInStandardDateFormat(fDate);
867  }
868 
869  OUString DateFieldmark::GetDateInStandardDateFormat(double fDate) const
870  {
871  OUString sCurrentDate;
873  if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
874  {
875  sal_Int32 nCheckPos = 0;
877  OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
878  m_pNumberFormatter->PutEntry(sFormat,
879  nCheckPos,
880  nType,
881  nFormat,
883  }
884 
885  if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
886  {
887  Color* pCol = nullptr;
888  m_pNumberFormatter->GetOutputString(fDate, nFormat, sCurrentDate, &pCol, false);
889  }
890  return sCurrentDate;
891  }
892 
893  std::pair<bool, double> DateFieldmark::ParseCurrentDateParam() const
894  {
895  bool bFoundValidDate = false;
896  double dCurrentDate = 0;
897 
899  auto pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
900  OUString sCurrentDate;
901  if (pResult != pParameters->end())
902  {
903  pResult->second >>= sCurrentDate;
904  }
905  if(!sCurrentDate.isEmpty())
906  {
908  if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
909  {
910  sal_Int32 nCheckPos = 0;
912  OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
913  m_pNumberFormatter->PutEntry(sFormat,
914  nCheckPos,
915  nType,
916  nFormat,
918  }
919 
920  if(nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
921  {
922  bFoundValidDate = m_pNumberFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate);
923  }
924  }
925  return std::pair<bool, double>(bFoundValidDate, dCurrentDate);
926  }
927 
928 
929  OUString DateFieldmark::GetDateInCurrentDateFormat(double fDate) const
930  {
931  // Get current date format and language
932  OUString sDateFormat;
934  auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
935  if (pResult != pParameters->end())
936  {
937  pResult->second >>= sDateFormat;
938  }
939 
940  OUString sLang;
941  pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
942  if (pResult != pParameters->end())
943  {
944  pResult->second >>= sLang;
945  }
946 
947  // Fill the content with the specified format
948  OUString sCurrentContent;
949  sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
950  if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
951  {
952  sal_Int32 nCheckPos = 0;
954  OUString sFormat = sDateFormat;
955  m_pNumberFormatter->PutEntry(sFormat,
956  nCheckPos,
957  nType,
958  nFormat,
959  LanguageTag(sLang).getLanguageType());
960  }
961 
962  if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
963  {
964  Color* pCol = nullptr;
965  m_pNumberFormatter->GetOutputString(fDate, nFormat, sCurrentContent, &pCol, false);
966  }
967  return sCurrentContent;
968  }
969 
971  {
972  std::pair<bool, double> aResult = ParseCurrentDateParam();
973  if(!aResult.first)
974  return;
975 
976  // Current date became invalid
977  if(GetDateInCurrentDateFormat(aResult.second) != GetContent())
978  {
980  (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= OUString();
981  }
982  }
983 }
984 
985 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetMarkStartPos(const SwPosition &rNewStartPos)
Definition: bookmrk.cxx:491
OUString m_aName
Definition: bookmrk.hxx:122
static OUString GenerateNewName(const OUString &rPrefix)
Definition: bookmrk.cxx:311
virtual void Hide(bool rHide) override
Definition: bookmrk.cxx:431
virtual std::pair< bool, double > GetCurrentDate() const override
Definition: bookmrk.cxx:813
bool is() const
DateFieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:695
virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) override
Definition: bookmrk.cxx:336
std::map< OUString, css::uno::Any > parameter_map_t
Definition: IMark.hxx:94
Marks a position in the document model.
Definition: pam.hxx:35
OUString m_aFieldHelptext
Definition: bookmrk.hxx:240
bool IsChecked() const override
Definition: bookmrk.cxx:628
sal_uLong StartOfSectionIndex() const
Definition: node.hxx:673
virtual void ShowButton(SwEditWin *pEditWin) override
Definition: bookmrk.cxx:669
const OUString & GetText() const
Definition: ndtxt.hxx:211
virtual bool IsInUndo() const override
Definition: bookmrk.cxx:463
virtual void ReplaceContent(const OUString &sNewContent) override
Definition: bookmrk.cxx:788
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1409
SwNodeIndex nNode
Definition: pam.hxx:37
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, Color **ppColor, bool bUseStarFormat=false)
virtual void ReleaseDoc(SwDoc *const pDoc) override
Definition: bookmrk.cxx:599
OUString m_sHideCondition
Definition: bookmrk.hxx:203
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:274
virtual void SetModified()=0
Must be called manually at changes of format.
sal_uIntPtr sal_uLong
void disposeAndClear()
const SwPosition * GetMark() const
Definition: pam.hxx:209
sal_Int64 n
#define ODF_FORMDATE_CURRENTDATE
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: bookmrk.cxx:524
Definition: doc.hxx:186
#define ODF_FORMDATE_DATEFORMAT_LANGUAGE
virtual SwPosition & GetMarkStart() const override
Definition: bookmrk.hxx:65
virtual void InitDoc(SwDoc *const io_pDoc, sw::mark::InsertMode eMode, SwPosition const *pSepPos) override
Definition: bookmrk.cxx:706
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:259
sw::DocumentContentOperationsManager * m_pDocumentContentOperationsManager
Definition: bookmrk.hxx:337
virtual auto InvalidateFrames() -> void override
Definition: bookmrk.cxx:422
OUString m_aFieldname
Definition: bookmrk.hxx:239
SwPosition FindFieldSep(IFieldmark const &rMark)
return position of the CH_TXT_ATR_FIELDSEP for rMark
Definition: bookmrk.cxx:50
void SetChecked(bool checked) override
Definition: bookmrk.cxx:616
virtual OUString ToString() const override
Definition: bookmrk.cxx:285
SwNode & GetNode() const
Definition: ndindex.hxx:119
virtual void ReleaseDoc(SwDoc *const pDoc) override
Definition: bookmrk.cxx:564
UnoMark(const SwPaM &rPaM)
Definition: bookmrk.cxx:353
virtual ::sfx2::IXmlIdRegistry & GetRegistry() override
Definition: bookmrk.cxx:449
virtual void ReleaseDoc(SwDoc *const pDoc) override
Definition: bookmrk.cxx:721
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
#define RES_REMOVE_UNO_OBJECT
Definition: hintids.hxx:398
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:314
void SetPortionPaintAreaEnd(const SwRect &rPortionPaintArea)
Definition: bookmrk.cxx:754
virtual bool IsCoveringPosition(const SwPosition &rPos) const override
Definition: bookmrk.cxx:268
#define CH_TXT_ATR_FORMELEMENT
Definition: hintids.hxx:143
virtual ~DdeBookmark() override
Definition: bookmrk.cxx:372
bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND) override
Insert string into existing text node at position rRg.Point().
TextFieldmark(const SwPaM &rPaM, const OUString &rName)
Definition: bookmrk.cxx:542
#define ODF_FORMCHECKBOX_RESULT
bool IsInHeaderFooter(const SwNodeIndex &rIdx) const
Definition: doclay.cxx:1548
Fieldmark with a drop down button (e.g. this button opens the date picker for a date field) ...
Definition: bookmrk.hxx:275
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
void InvalidatePaM()
Definition: pam.cxx:1115
std::unique_ptr< SwPosition > m_pPos1
Definition: bookmrk.hxx:120
virtual bool IsExpanded() const override
Definition: bookmrk.hxx:83
Point TopLeft() const
Definition: swrect.cxx:176
#define ODF_FORMDATE_CURRENTDATE_LANGUAGE
virtual SwPosition & GetMarkEnd() const override
Definition: bookmrk.hxx:73
sal_uInt16 sal_Unicode
SwIndex nContent
Definition: pam.hxx:38
std::unique_ptr< SwPosition > m_pPos2
Definition: bookmrk.hxx:121
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
virtual ~DropDownFieldmark() override
Definition: bookmrk.cxx:665
int nCount
void RemoveServer(SvLinkSource *rObj)
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
std::pair< bool, double > ParseCurrentDateParam() const
Definition: bookmrk.cxx:893
::sfx2::IXmlIdRegistry & GetXmlIdRegistry()
Definition: docnew.cxx:787
OUString GetDateInCurrentDateFormat(double fDate) const
Definition: bookmrk.cxx:929
void InvalidateCurrentDateParam()
Definition: bookmrk.cxx:970
virtual parameter_map_t * GetParameters()=0
#define ODF_FORMDATE_CURRENTDATE_FORMAT
void DeleteDummyChar(SwPosition const &rPos, sal_Unicode cDummy)
bool IsEmpty() const
Definition: swrect.hxx:295
virtual bool DoesUndo() const =0
Is Undo enabled?
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW)
Bookmark(const SwPaM &rPaM, const vcl::KeyCode &rCode, const OUString &rName)
Definition: bookmrk.cxx:385
virtual void ShowButton(SwEditWin *pEditWin) override
Definition: bookmrk.cxx:733
void SetRefObject(SwServerObject *pObj)
Definition: bookmrk.cxx:361
Point BottomRight() const
Definition: swrect.cxx:179
OUString m_aName
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
struct _xmlTextWriter * xmlTextWriterPtr
static css::uno::Reference< css::text::XTextContent > CreateXBookmark(SwDoc &rDoc,::sw::mark::IMark *pBookmark)
Definition: unobkm.cxx:155
T * get() const
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
virtual void AppendUndo(std::unique_ptr< SwUndo > pUndo)=0
Add new Undo action.
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
#define SAL_MAX_INT32
int i
const SwPosition * GetPoint() const
Definition: pam.hxx:207
void SetMarkEndPos(const SwPosition &rNewEndPos)
Definition: bookmrk.cxx:499
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:58
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: bookmrk.cxx:292
::sw::DocumentContentOperationsManager const & GetDocumentContentOperationsManager() const
Definition: doc.cxx:324
void CalcPosAndSize(const SwRect &rPortionPaintArea)
virtual void InitDoc(SwDoc *const io_Doc, sw::mark::InsertMode eMode, SwPosition const *pSepPos) override
Definition: bookmrk.cxx:396
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
void SetNoServer()
Definition: swserv.cxx:249
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
virtual auto InvalidateFrames() -> void
Definition: bookmrk.cxx:345
virtual ~MarkBase() override
Definition: bookmrk.cxx:308
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:145
SvNumberFormatter * m_pNumberFormatter
Definition: bookmrk.hxx:336
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:393
DdeBookmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:357
virtual css::uno::Reference< css::rdf::XMetadatable > MakeUnoObject() override
Definition: bookmrk.cxx:475
bool IsNoTextNode() const
Definition: node.hxx:648
SvNumFormatType
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber)
bool IsEndNode() const
Definition: node.hxx:632
void SetPortionPaintAreaStart(const SwRect &rPortionPaintArea)
Definition: bookmrk.cxx:745
#define ODF_FORMDATE_DATEFORMAT
DropDownFieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:660
CheckboxFieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:612
enumrange< T >::Iterator end(enumrange< T >)
virtual OUString ToString() const override
Definition: bookmrk.cxx:507
virtual void DeregisterFromDoc(SwDoc *const io_pDoc) override
Definition: bookmrk.cxx:408
void NotifyClients(const SfxPoolItem *pOldValue, const SfxPoolItem *pNewValue)
Definition: calbck.cxx:167
bool HasDataLinks() const
NavigatorReminder(const SwPaM &rPaM)
Definition: bookmrk.cxx:349
NonTextFieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:575
virtual void InitDoc(SwDoc *const io_pDoc, sw::mark::InsertMode eMode, SwPosition const *pSepPos) override
Definition: bookmrk.cxx:549
virtual SwPosition & GetOtherMarkPos() const override
Definition: bookmrk.hxx:60
FieldmarkWithDropDownButton(const SwPaM &rPaM)
Definition: bookmrk.cxx:637
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
MarkBase(const SwPaM &rPaM, const OUString &rName)
Definition: bookmrk.cxx:251
void SetXBookmark(css::uno::Reference< css::text::XTextContent > const &xBkmk)
Definition: bookmrk.hxx:112
virtual bool IsInContent() const override
Definition: bookmrk.cxx:468
bool IsVisible() const
virtual bool IsInClipboard() const override
Definition: bookmrk.cxx:456
#define SAL_INFO(area, stream)
sal_Int32 GetIndex() const
Definition: index.hxx:95
virtual void InitDoc(SwDoc *const io_pDoc, sw::mark::InsertMode eMode, SwPosition const *pSepPos) override
Definition: bookmrk.cxx:579
bool IsClipBoard() const
Definition: doc.hxx:962
virtual SwPosition & GetMarkPos() const override
Definition: bookmrk.hxx:56
static VclPtr< reference_type > Create(Arg &&...arg)
virtual void SetMarkPos(const SwPosition &rNewPos)
Definition: bookmrk.cxx:273
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: pam.cxx:182
void * p
QPRO_FUNC_TYPE nType
void SetPortionPaintArea(const SwRect &rPortionPaintArea)
Definition: bookmrk.cxx:680
IFieldmark::parameter_map_t m_vParams
Definition: bookmrk.hxx:241
virtual const SwPosition & GetMarkEnd() const =0
virtual ~DateFieldmark() override
Definition: bookmrk.cxx:702
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:147
virtual void SetCurrentDate(double fDate) override
Definition: bookmrk.cxx:859
sal_uInt32 GetEntryKey(const OUString &sStr, LanguageType eLnge=LANGUAGE_DONTKNOW)
virtual OUString GetContent() const override
Definition: bookmrk.cxx:774
Fieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:484
virtual sfx2::LinkManager & GetLinkManager()=0
virtual void SetHideCondition(const OUString &rHideCondition) override
Definition: bookmrk.cxx:440
virtual void DeregisterFromDoc(SwDoc *const pDoc)
Definition: bookmrk.cxx:366
tools::SvRef< SwServerObject > m_aRefObj
Definition: bookmrk.hxx:159
virtual const SwPosition & GetMarkStart() const =0
bool ReplaceRange(SwPaM &rPam, const OUString &rNewStr, const bool bRegExReplace) override
Replace selected range in a TextNode with string.
InsertMode
Definition: IMark.hxx:31
virtual void SetOtherMarkPos(const SwPosition &rNewPos)
Definition: bookmrk.cxx:279
virtual ~FieldmarkWithDropDownButton() override
Definition: bookmrk.cxx:643
#define CH_TXT_ATR_FIELDSEP
Definition: hintids.hxx:146
bool IsTextNode() const
Definition: node.hxx:636
sal_uInt16 Which() const
virtual void Invalidate() override
Definition: bookmrk.cxx:516
VclPtr< FormFieldButton > m_pButton
Definition: bookmrk.hxx:287
virtual IFieldmark::parameter_map_t * GetParameters() override
Definition: bookmrk.hxx:218
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:836
OUString anyToString(uno::Any const &value)
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Base class of the Writer document model elements.
Definition: node.hxx:79
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo
virtual OUString GetDateInStandardDateFormat(double fDate) const override
Definition: bookmrk.cxx:869