LibreOffice Module sw (master)  1
docbm.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 <MarkManager.hxx>
22 #include <bookmrk.hxx>
23 #include <cntfrm.hxx>
24 #include <crossrefbookmark.hxx>
25 #include <annotationmark.hxx>
26 #include <dcontact.hxx>
27 #include <doc.hxx>
29 #include <IDocumentState.hxx>
30 #include <IDocumentUndoRedo.hxx>
31 #include <docary.hxx>
32 #include <xmloff/odffields.hxx>
33 #include <editsh.hxx>
34 #include <fmtanchr.hxx>
35 #include <frmfmt.hxx>
36 #include <functional>
37 #include <hintids.hxx>
38 #include <mvsave.hxx>
39 #include <ndtxt.hxx>
40 #include <node.hxx>
41 #include <pam.hxx>
42 #include <redline.hxx>
43 #include <rolbck.hxx>
44 #include <rtl/ustrbuf.hxx>
45 #include <rtl/ustring.hxx>
46 #include <sal/types.h>
47 #include <sal/log.hxx>
48 #include <sortedobjs.hxx>
49 #include <sfx2/linkmgr.hxx>
50 #include <swserv.hxx>
51 #include <swundo.hxx>
52 #include <UndoBookmark.hxx>
53 #include <unocrsr.hxx>
54 #include <viscrs.hxx>
55 #include <edimp.hxx>
56 #include <tools/datetimeutils.hxx>
57 #include <view.hxx>
58 
59 using namespace ::sw::mark;
60 
61 std::vector<::sw::mark::MarkBase*>::const_iterator const&
63 {
64  return *m_pIter;
65 }
66 
67 IDocumentMarkAccess::iterator::iterator(std::vector<::sw::mark::MarkBase*>::const_iterator const& rIter)
68  : m_pIter(new std::vector<::sw::mark::MarkBase*>::const_iterator(rIter))
69 {
70 }
71 
73  : m_pIter(new std::vector<::sw::mark::MarkBase*>::const_iterator(*rOther.m_pIter))
74 {
75 }
76 
78 {
79  m_pIter.reset(new std::vector<::sw::mark::MarkBase*>::const_iterator(*rOther.m_pIter));
80  return *this;
81 }
82 
84  : m_pIter(std::move(rOther.m_pIter))
85 {
86 }
87 
89 {
90  m_pIter = std::move(rOther.m_pIter);
91  return *this;
92 }
93 
95 {
96 }
97 
98 // ARGH why does it *need* to return const& ?
99 ::sw::mark::IMark* /*const&*/
101 {
102  return static_cast<sw::mark::IMark*>(**m_pIter);
103 }
104 
106 {
107  ++(*m_pIter);
108  return *this;
109 }
111 {
112  iterator tmp(*this);
113  ++(*m_pIter);
114  return tmp;
115 }
116 
118 {
119  return *m_pIter == *rOther.m_pIter;
120 }
121 
123 {
124  return *m_pIter != *rOther.m_pIter;
125 }
126 
128  : m_pIter(new std::vector<::sw::mark::MarkBase*>::const_iterator())
129 {
130 }
131 
133 {
134  --(*m_pIter);
135  return *this;
136 }
137 
139 {
140  iterator tmp(*this);
141  --(*m_pIter);
142  return tmp;
143 }
144 
146 {
147  (*m_pIter) += n;
148  return *this;
149 }
150 
152 {
153  return iterator(*m_pIter + n);
154 }
155 
157 {
158  (*m_pIter) -= n;
159  return *this;
160 }
161 
163 {
164  return iterator(*m_pIter - n);
165 }
166 
168 {
169  return *m_pIter - *rOther.m_pIter;
170 }
171 
173 {
174  return static_cast<sw::mark::IMark*>((*m_pIter)[n]);
175 }
176 
178 {
179  return *m_pIter < *rOther.m_pIter;
180 }
182 {
183  return *m_pIter > *rOther.m_pIter;
184 }
186 {
187  return *m_pIter <= *rOther.m_pIter;
188 }
190 {
191  return *m_pIter >= *rOther.m_pIter;
192 }
193 
194 
195 namespace
196 {
197  bool lcl_GreaterThan( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
198  {
199  return pIdx != nullptr
200  ? ( rPos.nNode > rNdIdx
201  || ( rPos.nNode == rNdIdx
202  && rPos.nContent >= pIdx->GetIndex() ) )
203  : rPos.nNode >= rNdIdx;
204  }
205 
206  bool lcl_Lower( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
207  {
208  return rPos.nNode < rNdIdx
209  || ( pIdx != nullptr
210  && rPos.nNode == rNdIdx
211  && rPos.nContent < pIdx->GetIndex() );
212  }
213 
214  bool lcl_MarkOrderingByStart(const ::sw::mark::MarkBase *const pFirst,
215  const ::sw::mark::MarkBase *const pSecond)
216  {
217  auto const& rFirstStart(pFirst->GetMarkStart());
218  auto const& rSecondStart(pSecond->GetMarkStart());
219  if (rFirstStart.nNode != rSecondStart.nNode)
220  {
221  return rFirstStart.nNode < rSecondStart.nNode;
222  }
223  const sal_Int32 nFirstContent = rFirstStart.nContent.GetIndex();
224  const sal_Int32 nSecondContent = rSecondStart.nContent.GetIndex();
225  if (nFirstContent != 0 || nSecondContent != 0)
226  {
227  return nFirstContent < nSecondContent;
228  }
229  auto *const pCRFirst (dynamic_cast<::sw::mark::CrossRefBookmark const*>(pFirst));
230  auto *const pCRSecond(dynamic_cast<::sw::mark::CrossRefBookmark const*>(pSecond));
231  if ((pCRFirst == nullptr) == (pCRSecond == nullptr))
232  {
233  return false; // equal
234  }
235  return pCRFirst != nullptr; // cross-ref sorts *before*
236  }
237 
238  bool lcl_MarkOrderingByEnd(const ::sw::mark::MarkBase *const pFirst,
239  const ::sw::mark::MarkBase *const pSecond)
240  {
241  return pFirst->GetMarkEnd() < pSecond->GetMarkEnd();
242  }
243 
244  void lcl_InsertMarkSorted(MarkManager::container_t& io_vMarks,
245  ::sw::mark::MarkBase *const pMark)
246  {
247  io_vMarks.insert(
248  lower_bound(
249  io_vMarks.begin(),
250  io_vMarks.end(),
251  pMark,
252  &lcl_MarkOrderingByStart),
253  pMark);
254  }
255 
256  std::unique_ptr<SwPosition> lcl_PositionFromContentNode(
257  SwContentNode * const pContentNode,
258  const bool bAtEnd)
259  {
260  std::unique_ptr<SwPosition> pResult(new SwPosition(*pContentNode));
261  pResult->nContent.Assign(pContentNode, bAtEnd ? pContentNode->Len() : 0);
262  return pResult;
263  }
264 
265  // return a position at the begin of rEnd, if it is a ContentNode
266  // else set it to the begin of the Node after rEnd, if there is one
267  // else set it to the end of the node before rStt
268  // else set it to the ContentNode of the Pos outside the Range
269  std::unique_ptr<SwPosition> lcl_FindExpelPosition(
270  const SwNodeIndex& rStt,
271  const SwNodeIndex& rEnd,
272  const SwPosition& rOtherPosition)
273  {
274  SwContentNode * pNode = rEnd.GetNode().GetContentNode();
275  bool bPosAtEndOfNode = false;
276  if ( pNode == nullptr)
277  {
278  SwNodeIndex aEnd = rEnd;
279  pNode = rEnd.GetNodes().GoNext( &aEnd );
280  bPosAtEndOfNode = false;
281  }
282  if ( pNode == nullptr )
283  {
284  SwNodeIndex aStt = rStt;
285  pNode = SwNodes::GoPrevious(&aStt);
286  bPosAtEndOfNode = true;
287  }
288  if ( pNode != nullptr )
289  {
290  return lcl_PositionFromContentNode( pNode, bPosAtEndOfNode );
291  }
292 
293  return std::make_unique<SwPosition>(rOtherPosition);
294  }
295 
296  struct CompareIMarkStartsBefore
297  {
298  bool operator()(SwPosition const& rPos,
299  const sw::mark::IMark* pMark)
300  {
301  return rPos < pMark->GetMarkStart();
302  }
303  bool operator()(const sw::mark::IMark* pMark,
304  SwPosition const& rPos)
305  {
306  return pMark->GetMarkStart() < rPos;
307  }
308  };
309 
310  // Apple llvm-g++ 4.2.1 with _GLIBCXX_DEBUG won't eat boost::bind for this
311  // Neither will MSVC 2008 with _DEBUG
312  struct CompareIMarkStartsAfter
313  {
314  bool operator()(SwPosition const& rPos,
315  const sw::mark::IMark* pMark)
316  {
317  return pMark->GetMarkStart() > rPos;
318  }
319  };
320 
321 
322  IMark* lcl_getMarkAfter(const MarkManager::container_t& rMarks, const SwPosition& rPos)
323  {
324  auto const pMarkAfter = upper_bound(
325  rMarks.begin(),
326  rMarks.end(),
327  rPos,
328  CompareIMarkStartsAfter());
329  if(pMarkAfter == rMarks.end())
330  return nullptr;
331  return *pMarkAfter;
332  };
333 
334  IMark* lcl_getMarkBefore(const MarkManager::container_t& rMarks, const SwPosition& rPos)
335  {
336  // candidates from which to choose the mark before
337  MarkManager::container_t vCandidates;
338  // no need to consider marks starting after rPos
339  auto const pCandidatesEnd = upper_bound(
340  rMarks.begin(),
341  rMarks.end(),
342  rPos,
343  CompareIMarkStartsAfter());
344  vCandidates.reserve(pCandidatesEnd - rMarks.begin());
345  // only marks ending before are candidates
346  remove_copy_if(
347  rMarks.begin(),
348  pCandidatesEnd,
349  back_inserter(vCandidates),
350  [&rPos] (const ::sw::mark::MarkBase *const pMark) { return !(pMark->GetMarkEnd() < rPos); } );
351  // no candidate left => we are in front of the first mark or there are none
352  if(vCandidates.empty()) return nullptr;
353  // return the highest (last) candidate using mark end ordering
354  return *max_element(vCandidates.begin(), vCandidates.end(), &lcl_MarkOrderingByEnd);
355  }
356 
357  bool lcl_FixCorrectedMark(
358  const bool bChangedPos,
359  const bool bChangedOPos,
360  MarkBase* io_pMark )
361  {
363  {
364  // annotation marks are allowed to span a table cell range.
365  // but trigger sorting to be save
366  return true;
367  }
368 
369  if ( ( bChangedPos || bChangedOPos )
370  && io_pMark->IsExpanded()
371  && io_pMark->GetOtherMarkPos().nNode.GetNode().FindTableBoxStartNode() !=
372  io_pMark->GetMarkPos().nNode.GetNode().FindTableBoxStartNode() )
373  {
374  if ( !bChangedOPos )
375  {
376  io_pMark->SetMarkPos( io_pMark->GetOtherMarkPos() );
377  }
378  io_pMark->ClearOtherMarkPos();
379  DdeBookmark * const pDdeBkmk = dynamic_cast< DdeBookmark*>(io_pMark);
380  if ( pDdeBkmk != nullptr
381  && pDdeBkmk->IsServer() )
382  {
383  pDdeBkmk->SetRefObject(nullptr);
384  }
385  return true;
386  }
387  return false;
388  }
389 
390  bool lcl_MarkEqualByStart(const ::sw::mark::MarkBase *const pFirst,
391  const ::sw::mark::MarkBase *const pSecond)
392  {
393  return !lcl_MarkOrderingByStart(pFirst, pSecond) &&
394  !lcl_MarkOrderingByStart(pSecond, pFirst);
395  }
396 
397  MarkManager::container_t::const_iterator lcl_FindMark(
398  MarkManager::container_t& rMarks,
399  const ::sw::mark::MarkBase *const pMarkToFind)
400  {
401  auto ppCurrentMark = lower_bound(
402  rMarks.begin(), rMarks.end(),
403  pMarkToFind, &lcl_MarkOrderingByStart);
404  // since there are usually not too many marks on the same start
405  // position, we are not doing a bisect search for the upper bound
406  // but instead start to iterate from pMarkLow directly
407  while (ppCurrentMark != rMarks.end() && lcl_MarkEqualByStart(*ppCurrentMark, pMarkToFind))
408  {
409  if(*ppCurrentMark == pMarkToFind)
410  {
411  return ppCurrentMark;
412  }
413  ++ppCurrentMark;
414  }
415  // reached a mark starting on a later start pos or the end of the
416  // vector => not found
417  return rMarks.end();
418  };
419 
420  MarkManager::container_t::const_iterator lcl_FindMarkAtPos(
421  MarkManager::container_t& rMarks,
422  const SwPosition& rPos,
423  const IDocumentMarkAccess::MarkType eType)
424  {
425  for (auto ppCurrentMark = lower_bound(
426  rMarks.begin(), rMarks.end(),
427  rPos,
428  CompareIMarkStartsBefore());
429  ppCurrentMark != rMarks.end();
430  ++ppCurrentMark)
431  {
432  // Once we reach a mark starting after the target pos
433  // we do not need to continue
434  if((*ppCurrentMark)->GetMarkStart() > rPos)
435  break;
436  if(IDocumentMarkAccess::GetType(**ppCurrentMark) == eType)
437  {
438  return ppCurrentMark;
439  }
440  }
441  // reached a mark starting on a later start pos or the end of the
442  // vector => not found
443  return rMarks.end();
444  };
445 
446  MarkManager::container_t::const_iterator lcl_FindMarkByName(
447  const OUString& rName,
448  const MarkManager::container_t::const_iterator& ppMarksBegin,
449  const MarkManager::container_t::const_iterator& ppMarksEnd)
450  {
451  return find_if(
452  ppMarksBegin,
453  ppMarksEnd,
454  [&rName] (::sw::mark::MarkBase const*const pMark) { return pMark->GetName() == rName; } );
455  }
456 
457  void lcl_DebugMarks(MarkManager::container_t const& rMarks)
458  {
459 #if OSL_DEBUG_LEVEL > 0
460  SAL_INFO("sw.core", rMarks.size() << " Marks");
461  for (auto ppMark = rMarks.begin();
462  ppMark != rMarks.end();
463  ++ppMark)
464  {
465  IMark* pMark = *ppMark;
466  const SwPosition* const pStPos = &pMark->GetMarkStart();
467  const SwPosition* const pEndPos = &pMark->GetMarkEnd();
468  SAL_INFO("sw.core",
469  pStPos->nNode.GetIndex() << "," <<
470  pStPos->nContent.GetIndex() << " " <<
471  pEndPos->nNode.GetIndex() << "," <<
472  pEndPos->nContent.GetIndex() << " " <<
473  typeid(*pMark).name() << " " <<
474  pMark->GetName());
475  }
476 #else
477  (void) rMarks;
478 #endif
479  assert(std::is_sorted(rMarks.begin(), rMarks.end(), lcl_MarkOrderingByStart));
480  };
481 }
482 
484 {
485  const std::type_info* const pMarkTypeInfo = &typeid(rBkmk);
486  // not using dynamic_cast<> here for performance
487  if(*pMarkTypeInfo == typeid(UnoMark))
488  return MarkType::UNO_BOOKMARK;
489  else if(*pMarkTypeInfo == typeid(DdeBookmark))
490  return MarkType::DDE_BOOKMARK;
491  else if(*pMarkTypeInfo == typeid(Bookmark))
492  return MarkType::BOOKMARK;
493  else if(*pMarkTypeInfo == typeid(CrossRefHeadingBookmark))
495  else if(*pMarkTypeInfo == typeid(CrossRefNumItemBookmark))
497  else if(*pMarkTypeInfo == typeid(AnnotationMark))
499  else if(*pMarkTypeInfo == typeid(TextFieldmark))
501  else if(*pMarkTypeInfo == typeid(CheckboxFieldmark))
503  else if(*pMarkTypeInfo == typeid(DropDownFieldmark))
505  else if(*pMarkTypeInfo == typeid(DateFieldmark))
507  else if(*pMarkTypeInfo == typeid(NavigatorReminder))
509  else
510  {
511  assert(false && "IDocumentMarkAccess::GetType(..)"
512  " - unknown MarkType. This needs to be fixed!");
513  return MarkType::UNO_BOOKMARK;
514  }
515 }
516 
518 {
519  return "__RefHeading__";
520 }
521 
523 {
524  return rPaM.Start()->nNode.GetNode().IsTextNode() &&
525  rPaM.Start()->nContent.GetIndex() == 0 &&
526  ( !rPaM.HasMark() ||
527  ( rPaM.GetMark()->nNode == rPaM.GetPoint()->nNode &&
528  rPaM.End()->nContent.GetIndex() == rPaM.End()->nNode.GetNode().GetTextNode()->Len() ) );
529 }
530 
531 namespace sw { namespace mark
532 {
533  MarkManager::MarkManager(SwDoc& rDoc)
534  : m_vAllMarks()
535  , m_vBookmarks()
536  , m_vFieldmarks()
537  , m_vAnnotationMarks()
538  , m_pDoc(&rDoc)
539  , m_pLastActiveFieldmark(nullptr)
540  { }
541 
543  const OUString& rName,
544  const IDocumentMarkAccess::MarkType eType,
545  sw::mark::InsertMode const eMode)
546  {
547 #if OSL_DEBUG_LEVEL > 0
548  {
549  const SwPosition* const pPos1 = rPaM.GetPoint();
550  const SwPosition* pPos2 = pPos1;
551  if(rPaM.HasMark())
552  pPos2 = rPaM.GetMark();
553  SAL_INFO("sw.core",
554  rName << " " <<
555  pPos1->nNode.GetIndex() << "," <<
556  pPos1->nContent.GetIndex() << " " <<
557  pPos2->nNode.GetIndex() << "," <<
558  pPos2->nContent.GetIndex());
559  }
560 #endif
561  // There should only be one CrossRefBookmark per Textnode per Type
563  && (lcl_FindMarkAtPos(m_vBookmarks, *rPaM.Start(), eType) != m_vBookmarks.end()))
564  { // this can happen via UNO API
565  SAL_WARN("sw.core", "MarkManager::makeMark(..)"
566  " - refusing to create duplicate CrossRefBookmark");
567  return nullptr;
568  }
569 
570  // create mark
571  std::unique_ptr<::sw::mark::MarkBase> pMark;
572  switch(eType)
573  {
575  pMark = std::make_unique<TextFieldmark>(rPaM, rName);
576  break;
578  pMark = std::make_unique<CheckboxFieldmark>(rPaM);
579  break;
581  pMark = std::make_unique<DropDownFieldmark>(rPaM);
582  break;
584  pMark = std::make_unique<DateFieldmark>(rPaM);
585  break;
587  pMark = std::make_unique<NavigatorReminder>(rPaM);
588  break;
590  pMark = std::make_unique<Bookmark>(rPaM, vcl::KeyCode(), rName);
591  break;
593  pMark = std::make_unique<DdeBookmark>(rPaM);
594  break;
596  pMark = std::make_unique<CrossRefHeadingBookmark>(rPaM, vcl::KeyCode(), rName);
597  break;
599  pMark = std::make_unique<CrossRefNumItemBookmark>(rPaM, vcl::KeyCode(), rName);
600  break;
602  pMark = std::make_unique<UnoMark>(rPaM);
603  break;
605  pMark = std::make_unique<AnnotationMark>( rPaM, rName );
606  break;
607  }
608  assert(pMark.get() &&
609  "MarkManager::makeMark(..)"
610  " - Mark was not created.");
611 
612  if(pMark->GetMarkPos() != pMark->GetMarkStart())
613  pMark->Swap();
614 
615  // for performance reasons, we trust UnoMarks to have a (generated) unique name
617  pMark->SetName( getUniqueMarkName( pMark->GetName() ) );
618 
619  // register mark
620  lcl_InsertMarkSorted(m_vAllMarks, pMark.get());
621  switch(eType)
622  {
626  lcl_InsertMarkSorted(m_vBookmarks, pMark.get());
627  break;
632  lcl_InsertMarkSorted(m_vFieldmarks, pMark.get());
633  break;
635  lcl_InsertMarkSorted( m_vAnnotationMarks, pMark.get() );
636  break;
640  // no special array for these
641  break;
642  }
643  pMark->InitDoc(m_pDoc, eMode);
644  SAL_INFO("sw.core", "--- makeType ---");
645  SAL_INFO("sw.core", "Marks");
646  lcl_DebugMarks(m_vAllMarks);
647  SAL_INFO("sw.core", "Bookmarks");
648  lcl_DebugMarks(m_vBookmarks);
649  SAL_INFO("sw.core", "Fieldmarks");
650  lcl_DebugMarks(m_vFieldmarks);
651 
652  return pMark.release();
653  }
654 
656  const SwPaM& rPaM,
657  const OUString& rName,
658  const OUString& rType )
659  {
660  // Disable undo, because we handle it using SwUndoInsTextFieldmark
661  bool bUndoIsEnabled = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
663 
664  sw::mark::IMark* pMark = nullptr;
665  if(rType == ODF_FORMDATE)
666  {
667  pMark = makeMark(rPaM, rName,
670  }
671  else
672  {
673  pMark = makeMark(rPaM, rName,
676  }
677  sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
678  if (pFieldMark)
679  pFieldMark->SetFieldname( rType );
680 
681  if (bUndoIsEnabled)
682  {
683  m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoIsEnabled);
684  if (pFieldMark)
685  m_pDoc->GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoInsTextFieldmark>(*pFieldMark));
686  }
687 
688  return pFieldMark;
689  }
690 
692  const SwPaM& rPaM,
693  const OUString& rName,
694  const OUString& rType)
695  {
696  // Disable undo, because we handle it using SwUndoInsNoTextFieldmark
697  bool bUndoIsEnabled = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
699 
700  bool bEnableSetModified = m_pDoc->getIDocumentState().IsEnableSetModified();
702 
703  sw::mark::IMark* pMark = nullptr;
704  if(rType == ODF_FORMCHECKBOX)
705  {
706  pMark = makeMark( rPaM, rName,
709  }
710  else if(rType == ODF_FORMDROPDOWN)
711  {
712  pMark = makeMark( rPaM, rName,
715  }
716  else if(rType == ODF_FORMDATE)
717  {
718  pMark = makeMark( rPaM, rName,
721  }
722 
723  sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
724  if (pFieldMark)
725  pFieldMark->SetFieldname( rType );
726 
727  if (bUndoIsEnabled)
728  {
729  m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoIsEnabled);
730  if (pFieldMark)
731  m_pDoc->GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoInsNoTextFieldmark>(*pFieldMark));
732  }
733 
734  m_pDoc->getIDocumentState().SetEnableSetModified(bEnableSetModified);
736 
737  return pFieldMark;
738  }
739 
741  const SwTextNode& rTextNode,
742  const IDocumentMarkAccess::MarkType eType )
743  {
744  SwPosition aPos(rTextNode);
745  aPos.nContent.Assign(&const_cast<SwTextNode&>(rTextNode), 0);
746  auto const ppExistingMark = lcl_FindMarkAtPos(m_vBookmarks, aPos, eType);
747  if(ppExistingMark != m_vBookmarks.end())
748  return *ppExistingMark;
749  const SwPaM aPaM(aPos);
750  return makeMark(aPaM, OUString(), eType, sw::mark::InsertMode::New);
751  }
752 
754  const SwPaM& rPaM,
755  const OUString& rName )
756  {
759  }
760 
762  ::sw::mark::IMark* const io_pMark,
763  const SwPaM& rPaM)
764  {
765  assert(io_pMark->GetMarkPos().GetDoc() == m_pDoc &&
766  "<MarkManager::repositionMark(..)>"
767  " - Mark is not in my doc.");
768  MarkBase* const pMarkBase = dynamic_cast< MarkBase* >(io_pMark);
769  if (!pMarkBase)
770  return;
771 
772  pMarkBase->SetMarkPos(*(rPaM.GetPoint()));
773  if(rPaM.HasMark())
774  pMarkBase->SetOtherMarkPos(*(rPaM.GetMark()));
775  else
776  pMarkBase->ClearOtherMarkPos();
777 
778  if(pMarkBase->GetMarkPos() != pMarkBase->GetMarkStart())
779  pMarkBase->Swap();
780 
781  sortMarks();
782  }
783 
785  ::sw::mark::IMark* io_pMark,
786  const OUString& rNewName )
787  {
788  assert(io_pMark->GetMarkPos().GetDoc() == m_pDoc &&
789  "<MarkManager::renameMark(..)>"
790  " - Mark is not in my doc.");
791  if ( io_pMark->GetName() == rNewName )
792  return true;
793  if (lcl_FindMarkByName(rNewName, m_vAllMarks.begin(), m_vAllMarks.end()) != m_vAllMarks.end())
794  return false;
795  if (::sw::mark::MarkBase* pMarkBase = dynamic_cast< ::sw::mark::MarkBase* >(io_pMark))
796  {
797  const OUString sOldName(pMarkBase->GetName());
798  pMarkBase->SetName(rNewName);
799 
800  if (dynamic_cast< ::sw::mark::Bookmark* >(io_pMark))
801  {
803  {
805  std::make_unique<SwUndoRenameBookmark>(sOldName, rNewName, m_pDoc));
806  }
808  }
809  }
810  return true;
811  }
812 
814  const SwNodeIndex& rOldNode,
815  const SwPosition& rNewPos,
816  const sal_Int32 nOffset)
817  {
818  const SwNode* const pOldNode = &rOldNode.GetNode();
819  SwPosition aNewPos(rNewPos);
820  aNewPos.nContent += nOffset;
821  bool isSortingNeeded = false;
822 
823  for (auto ppMark = m_vAllMarks.begin();
824  ppMark != m_vAllMarks.end();
825  ++ppMark)
826  {
827  ::sw::mark::MarkBase *const pMark = *ppMark;
828  // correction of non-existent non-MarkBase instances cannot be done
829  assert(pMark);
830  // is on position ??
831  bool bChangedPos = false;
832  if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
833  {
834  pMark->SetMarkPos(aNewPos);
835  bChangedPos = true;
836  isSortingNeeded = true;
837  }
838  bool bChangedOPos = false;
839  if (pMark->IsExpanded() &&
840  &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
841  {
842  // shift the OtherMark to aNewPos
843  pMark->SetOtherMarkPos(aNewPos);
844  bChangedOPos= true;
845  isSortingNeeded = true;
846  }
847  // illegal selection? collapse the mark and restore sorting later
848  isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
849  }
850 
851  // restore sorting if needed
852  if(isSortingNeeded)
853  sortMarks();
854 
855  SAL_INFO("sw.core", "correctMarksAbsolute");
856  lcl_DebugMarks(m_vAllMarks);
857  }
858 
859  void MarkManager::correctMarksRelative(const SwNodeIndex& rOldNode, const SwPosition& rNewPos, const sal_Int32 nOffset)
860  {
861  const SwNode* const pOldNode = &rOldNode.GetNode();
862  SwPosition aNewPos(rNewPos);
863  aNewPos.nContent += nOffset;
864  bool isSortingNeeded = false;
865 
866  for (auto ppMark = m_vAllMarks.begin();
867  ppMark != m_vAllMarks.end();
868  ++ppMark)
869  {
870  // is on position ??
871  bool bChangedPos = false, bChangedOPos = false;
872  ::sw::mark::MarkBase* const pMark = *ppMark;
873  // correction of non-existent non-MarkBase instances cannot be done
874  assert(pMark);
875  if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
876  {
877  SwPosition aNewPosRel(aNewPos);
878  if (dynamic_cast< ::sw::mark::CrossRefBookmark *>(pMark))
879  {
880  // ensure that cross ref bookmark always starts at 0
881  aNewPosRel.nContent = 0; // HACK for WW8 import
882  isSortingNeeded = true; // and sort them to be safe...
883  }
884  aNewPosRel.nContent += pMark->GetMarkPos().nContent.GetIndex();
885  pMark->SetMarkPos(aNewPosRel);
886  bChangedPos = true;
887  }
888  if(pMark->IsExpanded() &&
889  &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
890  {
891  SwPosition aNewPosRel(aNewPos);
892  aNewPosRel.nContent += pMark->GetOtherMarkPos().nContent.GetIndex();
893  pMark->SetOtherMarkPos(aNewPosRel);
894  bChangedOPos = true;
895  }
896  // illegal selection? collapse the mark and restore sorting later
897  isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
898  }
899 
900  // restore sorting if needed
901  if(isSortingNeeded)
902  sortMarks();
903 
904  SAL_INFO("sw.core", "correctMarksRelative");
905  lcl_DebugMarks(m_vAllMarks);
906  }
907 
909  const SwNodeIndex& rStt,
910  const SwNodeIndex& rEnd,
911  std::vector<SaveBookmark>* pSaveBkmk,
912  const SwIndex* pSttIdx,
913  const SwIndex* pEndIdx )
914  {
915  std::vector<const_iterator_t> vMarksToDelete;
916  bool bIsSortingNeeded = false;
917 
918  // boolean indicating, if at least one mark has been moved while collecting marks for deletion
919  bool bMarksMoved = false;
920  // have marks in the range been skipped instead of deleted
921  bool bMarksSkipDeletion = false;
922 
923  // copy all bookmarks in the move area to a vector storing all position data as offset
924  // reassignment is performed after the move
925  for (auto ppMark = m_vAllMarks.begin();
926  ppMark != m_vAllMarks.end();
927  ++ppMark)
928  {
929  // navigator marks should not be moved
930  // TODO: Check if this might make them invalid
932  continue;
933 
934  ::sw::mark::MarkBase *const pMark = *ppMark;
935 
936  if (!pMark)
937  continue;
938 
939  // on position ??
940  bool bIsPosInRange = lcl_GreaterThan(pMark->GetMarkPos(), rStt, pSttIdx)
941  && lcl_Lower(pMark->GetMarkPos(), rEnd, pEndIdx);
942  bool bIsOtherPosInRange = pMark->IsExpanded()
943  && lcl_GreaterThan(pMark->GetOtherMarkPos(), rStt, pSttIdx)
944  && lcl_Lower(pMark->GetOtherMarkPos(), rEnd, pEndIdx);
945  // special case: completely in range, touching the end?
946  if ( pEndIdx != nullptr
947  && ( ( bIsOtherPosInRange
948  && pMark->GetMarkPos().nNode == rEnd
949  && pMark->GetMarkPos().nContent == *pEndIdx )
950  || ( bIsPosInRange
951  && pMark->IsExpanded()
952  && pMark->GetOtherMarkPos().nNode == rEnd
953  && pMark->GetOtherMarkPos().nContent == *pEndIdx ) ) )
954  {
955  bIsPosInRange = true;
956  bIsOtherPosInRange = true;
957  }
958 
959  if ( bIsPosInRange
960  && ( bIsOtherPosInRange
961  || !pMark->IsExpanded() ) )
962  {
963  // completely in range
964 
965  bool bDeleteMark = true;
966  {
967  switch ( IDocumentMarkAccess::GetType( *pMark ) )
968  {
971  // no delete of cross-reference bookmarks, if range is inside one paragraph
972  bDeleteMark = rStt != rEnd;
973  break;
975  // no delete of UNO mark, if it is not expanded and only touches the start of the range
976  bDeleteMark = bIsOtherPosInRange
977  || pMark->IsExpanded()
978  || pSttIdx == nullptr
979  || !( pMark->GetMarkPos().nNode == rStt
980  && pMark->GetMarkPos().nContent == *pSttIdx );
981  break;
982  default:
983  bDeleteMark = true;
984  break;
985  }
986  }
987 
988  if ( bDeleteMark )
989  {
990  if ( pSaveBkmk )
991  {
992  pSaveBkmk->push_back( SaveBookmark( *pMark, rStt, pSttIdx ) );
993  }
994  vMarksToDelete.emplace_back(ppMark);
995  }
996  else
997  {
998  bMarksSkipDeletion = true;
999  }
1000  }
1001  else if ( bIsPosInRange != bIsOtherPosInRange )
1002  {
1003  // the bookmark is partially in the range
1004  // move position of that is in the range out of it
1005 
1006  std::unique_ptr< SwPosition > pNewPos;
1007  {
1008  if ( pEndIdx != nullptr )
1009  {
1010  pNewPos = std::make_unique< SwPosition >( rEnd, *pEndIdx );
1011  }
1012  else
1013  {
1014  pNewPos =
1015  lcl_FindExpelPosition( rStt, rEnd, bIsPosInRange ? pMark->GetOtherMarkPos() : pMark->GetMarkPos() );
1016  }
1017  }
1018 
1019  bool bMoveMark = true;
1020  {
1021  switch ( IDocumentMarkAccess::GetType( *pMark ) )
1022  {
1025  // no move of cross-reference bookmarks, if move occurs inside a certain node
1026  bMoveMark = pMark->GetMarkPos().nNode != pNewPos->nNode;
1027  break;
1029  // no move of annotation marks, if method is called to collect deleted marks
1030  bMoveMark = pSaveBkmk == nullptr;
1031  break;
1032  default:
1033  bMoveMark = true;
1034  break;
1035  }
1036  }
1037  if ( bMoveMark )
1038  {
1039  if ( bIsPosInRange )
1040  pMark->SetMarkPos(*pNewPos);
1041  else
1042  pMark->SetOtherMarkPos(*pNewPos);
1043  bMarksMoved = true;
1044 
1045  // illegal selection? collapse the mark and restore sorting later
1046  bIsSortingNeeded |= lcl_FixCorrectedMark( bIsPosInRange, bIsOtherPosInRange, pMark );
1047  }
1048  }
1049  }
1050 
1051  {
1052  // fdo#61016 delay the deletion of the fieldmark characters
1053  // to prevent that from deleting the marks on that position
1054  // which would invalidate the iterators in vMarksToDelete
1055  std::vector< std::unique_ptr<ILazyDeleter> > vDelay;
1056  vDelay.reserve(vMarksToDelete.size());
1057 
1058  // If needed, sort mark containers containing subsets of the marks
1059  // in order to assure sorting. The sorting is critical for the
1060  // deletion of a mark as it is searched in these container for
1061  // deletion.
1062  if ( !vMarksToDelete.empty() && bMarksMoved )
1063  {
1064  sortSubsetMarks();
1065  }
1066  // we just remembered the iterators to delete, so we do not need to search
1067  // for the shared_ptr<> (the entry in m_vAllMarks) again
1068  // reverse iteration, since erasing an entry invalidates iterators
1069  // behind it (the iterators in vMarksToDelete are sorted)
1070  for ( std::vector< const_iterator_t >::reverse_iterator pppMark = vMarksToDelete.rbegin();
1071  pppMark != vMarksToDelete.rend();
1072  ++pppMark )
1073  {
1074  vDelay.push_back(deleteMark(*pppMark));
1075  }
1076  } // scope to kill vDelay
1077 
1078  // also need to sort if both marks were moved and not-deleted because
1079  // the not-deleted marks could be in wrong order vs. the moved ones
1080  if (bIsSortingNeeded || (bMarksMoved && bMarksSkipDeletion))
1081  {
1082  sortMarks();
1083  }
1084 
1085  SAL_INFO("sw.core", "deleteMarks");
1086  lcl_DebugMarks(m_vAllMarks);
1087  }
1088 
1090  {
1091  std::unique_ptr<Fieldmark> m_pFieldmark;
1093  LazyFieldmarkDeleter(Fieldmark* pMark, SwDoc *const pDoc)
1094  : m_pFieldmark(pMark), m_pDoc(pDoc)
1095  {
1096  assert(m_pFieldmark);
1097  }
1098  virtual ~LazyFieldmarkDeleter() override
1099  {
1100  m_pFieldmark->ReleaseDoc(m_pDoc);
1101  }
1102  };
1103 
1104  std::unique_ptr<IDocumentMarkAccess::ILazyDeleter>
1106  {
1107  std::unique_ptr<ILazyDeleter> ret;
1108  if (ppMark.get() == m_vAllMarks.end())
1109  return ret;
1110  IMark* pMark = *ppMark;
1111 
1112  switch(IDocumentMarkAccess::GetType(*pMark))
1113  {
1117  {
1118  auto const ppBookmark = lcl_FindMark(m_vBookmarks, *ppMark.get());
1119  if ( ppBookmark != m_vBookmarks.end() )
1120  {
1121  m_vBookmarks.erase(ppBookmark);
1122  }
1123  else
1124  {
1125  assert(false &&
1126  "<MarkManager::deleteMark(..)> - Bookmark not found in Bookmark container.");
1127  }
1128  }
1129  break;
1130 
1135  {
1136  auto const ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark.get());
1137  if ( ppFieldmark != m_vFieldmarks.end() )
1138  {
1139  if(m_pLastActiveFieldmark == *ppFieldmark)
1141 
1142  m_vFieldmarks.erase(ppFieldmark);
1143  ret.reset(new LazyFieldmarkDeleter(dynamic_cast<Fieldmark*>(pMark), m_pDoc));
1144  }
1145  else
1146  {
1147  assert(false &&
1148  "<MarkManager::deleteMark(..)> - Fieldmark not found in Fieldmark container.");
1149  }
1150  }
1151  break;
1152 
1154  {
1155  auto const ppAnnotationMark = lcl_FindMark(m_vAnnotationMarks, *ppMark.get());
1156  assert(ppAnnotationMark != m_vAnnotationMarks.end() &&
1157  "<MarkManager::deleteMark(..)> - Annotation Mark not found in Annotation Mark container.");
1158  m_vAnnotationMarks.erase(ppAnnotationMark);
1159  }
1160  break;
1161 
1165  // no special marks container
1166  break;
1167  }
1168  DdeBookmark* const pDdeBookmark = dynamic_cast<DdeBookmark*>(pMark);
1169  if (pDdeBookmark)
1170  pDdeBookmark->DeregisterFromDoc(m_pDoc);
1171  //Effective STL Item 27, get a non-const iterator aI at the same
1172  //position as const iterator ppMark was
1173  auto aI = m_vAllMarks.begin();
1174  std::advance(aI, std::distance<container_t::const_iterator>(aI, ppMark.get()));
1175 
1176  m_vAllMarks.erase(aI);
1177  // If we don't have a lazy deleter
1178  if (!ret)
1179  // delete after we remove from the list, because the destructor can
1180  // recursively call into this method.
1181  delete pMark;
1182  return ret;
1183  }
1184 
1185  void MarkManager::deleteMark(const IMark* const pMark)
1186  {
1187  assert(pMark->GetMarkPos().GetDoc() == m_pDoc &&
1188  "<MarkManager::deleteMark(..)>"
1189  " - Mark is not in my doc.");
1190  // finds the last Mark that is starting before pMark
1191  // (pMarkLow < pMark)
1192  auto [it, endIt] = equal_range(
1193  m_vAllMarks.begin(),
1194  m_vAllMarks.end(),
1195  pMark->GetMarkStart(),
1196  CompareIMarkStartsBefore());
1197  for ( ; it != endIt; ++it)
1198  if (*it == pMark)
1199  {
1200  deleteMark(iterator(it));
1201  break;
1202  }
1203  }
1204 
1206  {
1208  m_vFieldmarks.clear();
1209  m_vBookmarks.clear();
1210  m_vAnnotationMarks.clear();
1211  for (const auto & p : m_vAllMarks)
1212  delete p;
1213  m_vAllMarks.clear();
1214  }
1215 
1217  {
1218  auto const ret = lcl_FindMarkByName(rName, m_vAllMarks.begin(), m_vAllMarks.end());
1219  return IDocumentMarkAccess::iterator(ret);
1220  }
1221 
1223  {
1224  auto const ret = lcl_FindMarkByName(rName, m_vBookmarks.begin(), m_vBookmarks.end());
1225  return IDocumentMarkAccess::iterator(ret);
1226  }
1227 
1229  { return m_vAllMarks.begin(); }
1230 
1232  { return m_vAllMarks.end(); }
1233 
1235  { return m_vAllMarks.size(); }
1236 
1238  { return m_vBookmarks.begin(); }
1239 
1241  { return m_vBookmarks.end(); }
1242 
1244  { return m_vBookmarks.size(); }
1245 
1246  // finds the first that is starting after
1248  {
1249  return std::upper_bound(
1250  m_vBookmarks.begin(),
1251  m_vBookmarks.end(),
1252  rPos,
1253  CompareIMarkStartsAfter());
1254  }
1255 
1257  {
1258  auto const pFieldmark = find_if(
1259  m_vFieldmarks.begin(),
1260  m_vFieldmarks.end(),
1261  [&rPos] (const ::sw::mark::MarkBase *const pMark) { return pMark->IsCoveringPosition(rPos); } );
1262  if(pFieldmark == m_vFieldmarks.end())
1263  return nullptr;
1264  return dynamic_cast<IFieldmark*>(*pFieldmark);
1265  }
1266 
1268  {
1269  auto const pFieldmark = find_if(
1270  m_vFieldmarks.begin(),
1271  m_vFieldmarks.end(),
1272  [&rPos] (const ::sw::mark::IMark* pMark) { return pMark->IsCoveringPosition(rPos); } );
1273  if(pFieldmark == m_vFieldmarks.end())
1274  return;
1275 
1276  deleteMark(lcl_FindMark(m_vAllMarks, *pFieldmark));
1277  }
1278 
1280  {
1281  bool bActualChange = false;
1282  if(rNewType == ODF_FORMDROPDOWN)
1283  {
1284  if (!dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark))
1285  bActualChange = true;
1286  if (!dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark)) // only allowed converting between checkbox <-> dropdown
1287  return nullptr;
1288  }
1289  else if(rNewType == ODF_FORMCHECKBOX)
1290  {
1291  if (!dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark))
1292  bActualChange = true;
1293  if (!dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark)) // only allowed converting between checkbox <-> dropdown
1294  return nullptr;
1295  }
1296  else if(rNewType == ODF_FORMDATE)
1297  {
1298  if (!dynamic_cast<::sw::mark::DateFieldmark*>(pFieldmark))
1299  bActualChange = true;
1300  if (!dynamic_cast<::sw::mark::TextFieldmark*>(pFieldmark)) // only allowed converting between date field <-> text field
1301  return nullptr;
1302  }
1303 
1304  if (!bActualChange)
1305  return nullptr;
1306 
1307  // Store attributes needed to create the new fieldmark
1308  OUString sName = pFieldmark->GetName();
1309  SwPaM aPaM(pFieldmark->GetMarkPos());
1310 
1311  // Remove the old fieldmark and create a new one with the new type
1312  if(aPaM.GetPoint()->nContent > 0 && (rNewType == ODF_FORMDROPDOWN || rNewType == ODF_FORMCHECKBOX))
1313  {
1314  --aPaM.GetPoint()->nContent;
1315  SwPosition aNewPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent);
1316  deleteFieldmarkAt(aNewPos);
1317  return makeNoTextFieldBookmark(aPaM, sName, rNewType);
1318  }
1319  else if(rNewType == ODF_FORMDATE)
1320  {
1321  SwPosition aPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent);
1322  SwPaM aNewPaM(pFieldmark->GetMarkStart(), pFieldmark->GetMarkEnd());
1323  deleteFieldmarkAt(aPos);
1324  return makeFieldBookmark(aNewPaM, sName, rNewType);
1325  }
1326  return nullptr;
1327  }
1328 
1330  {
1331  SwView* pSwView = dynamic_cast<SwView *>(rCursorShell.GetSfxViewShell());
1332  if(!pSwView)
1333  return;
1334 
1335  SwEditWin& rEditWin = pSwView->GetEditWin();
1336  SwPosition aPos(*rCursorShell.GetCursor()->GetPoint());
1337  IFieldmark* pFieldBM = getFieldmarkFor(aPos);
1338  FieldmarkWithDropDownButton* pNewActiveFieldmark = nullptr;
1339  if ((!pFieldBM || (pFieldBM->GetFieldname() != ODF_FORMDROPDOWN && pFieldBM->GetFieldname() != ODF_FORMDATE))
1340  && aPos.nContent.GetIndex() > 0 )
1341  {
1342  --aPos.nContent;
1343  pFieldBM = getFieldmarkFor(aPos);
1344  }
1345 
1346  if ( pFieldBM && (pFieldBM->GetFieldname() == ODF_FORMDROPDOWN ||
1347  pFieldBM->GetFieldname() == ODF_FORMDATE))
1348  {
1349  if (m_pLastActiveFieldmark != pFieldBM)
1350  {
1351  FieldmarkWithDropDownButton& rFormField = dynamic_cast<FieldmarkWithDropDownButton&>(*pFieldBM);
1352  rFormField.ShowButton(&rEditWin);
1353  pNewActiveFieldmark = &rFormField;
1354  }
1355  else
1356  {
1357  pNewActiveFieldmark = m_pLastActiveFieldmark;
1358  }
1359  }
1360 
1361  if(pNewActiveFieldmark != m_pLastActiveFieldmark)
1362  {
1364  m_pLastActiveFieldmark = pNewActiveFieldmark;
1365  }
1366  }
1367 
1369  {
1372 
1373  m_pLastActiveFieldmark = nullptr;
1374  }
1375 
1377  {
1378  IFieldmark *pMark = getFieldmarkFor(rPos);
1379  if (!pMark || pMark->GetFieldname() != ODF_FORMDROPDOWN)
1380  return nullptr;
1381  return pMark;
1382  }
1383 
1384  std::vector<IFieldmark*> MarkManager::getDropDownsFor(const SwPaM &rPaM) const
1385  {
1386  std::vector<IFieldmark*> aRet;
1387 
1388  for (auto aI = m_vFieldmarks.begin(),
1389  aEnd = m_vFieldmarks.end(); aI != aEnd; ++aI)
1390  {
1391  ::sw::mark::IMark* pI = *aI;
1392  const SwPosition &rStart = pI->GetMarkPos();
1393  if (!rPaM.ContainsPosition(rStart))
1394  continue;
1395 
1396  IFieldmark *pMark = dynamic_cast<IFieldmark*>(pI);
1397  if (!pMark || pMark->GetFieldname() != ODF_FORMDROPDOWN)
1398  continue;
1399 
1400  aRet.push_back(pMark);
1401  }
1402 
1403  return aRet;
1404  }
1405 
1407  { return dynamic_cast<IFieldmark*>(lcl_getMarkAfter(m_vFieldmarks, rPos)); }
1408 
1410  { return dynamic_cast<IFieldmark*>(lcl_getMarkBefore(m_vFieldmarks, rPos)); }
1411 
1413  {
1414  return m_vAnnotationMarks.begin();
1415  }
1416 
1418  {
1419  return m_vAnnotationMarks.end();
1420  }
1421 
1423  {
1424  return m_vAnnotationMarks.size();
1425  }
1426 
1428  {
1429  auto const ret = lcl_FindMarkByName( rName, m_vAnnotationMarks.begin(), m_vAnnotationMarks.end() );
1430  return IDocumentMarkAccess::iterator(ret);
1431  }
1432 
1434  {
1435  auto const pAnnotationMark = find_if(
1436  m_vAnnotationMarks.begin(),
1437  m_vAnnotationMarks.end(),
1438  [&rPos] (const ::sw::mark::MarkBase *const pMark) { return pMark->IsCoveringPosition(rPos); } );
1439  if (pAnnotationMark == m_vAnnotationMarks.end())
1440  return nullptr;
1441  return *pAnnotationMark;
1442  }
1443 
1444  // finds the first that is starting after
1446  {
1447  return std::upper_bound(
1448  m_vAnnotationMarks.begin(),
1449  m_vAnnotationMarks.end(),
1450  rPos,
1451  CompareIMarkStartsAfter());
1452  }
1453 
1454  OUString MarkManager::getUniqueMarkName(const OUString& rName) const
1455  {
1456  OSL_ENSURE(rName.getLength(),
1457  "<MarkManager::getUniqueMarkName(..)> - a name should be proposed");
1458  if( m_pDoc->IsInMailMerge())
1459  {
1460  OUString newName = rName + "MailMergeMark"
1461  + OStringToOUString( DateTimeToOString( DateTime( DateTime::SYSTEM )), RTL_TEXTENCODING_ASCII_US )
1462  + OUString::number( m_vAllMarks.size() + 1 );
1463  return newName;
1464  }
1465 
1466  if (lcl_FindMarkByName(rName, m_vAllMarks.begin(), m_vAllMarks.end()) == m_vAllMarks.end())
1467  {
1468  return rName;
1469  }
1470  OUStringBuffer sBuf;
1471  OUString sTmp;
1472 
1473  // try the name "<rName>XXX" (where XXX is a number starting from 1) unless there is
1474  // an unused name. Due to performance-reasons (especially in mailmerge-scenarios) there
1475  // is a map m_aMarkBasenameMapUniqueOffset which holds the next possible offset (XXX) for
1476  // rName (so there is no need to test for nCnt-values smaller than the offset).
1477  sal_Int32 nCnt = 1;
1478  MarkBasenameMapUniqueOffset_t::const_iterator aIter = m_aMarkBasenameMapUniqueOffset.find(rName);
1479  if(aIter != m_aMarkBasenameMapUniqueOffset.end()) nCnt = aIter->second;
1480  while(nCnt < SAL_MAX_INT32)
1481  {
1482  sTmp = sBuf.append(rName).append(nCnt).makeStringAndClear();
1483  nCnt++;
1484  if (lcl_FindMarkByName(sTmp, m_vAllMarks.begin(), m_vAllMarks.end()) == m_vAllMarks.end())
1485  {
1486  break;
1487  }
1488  }
1489  m_aMarkBasenameMapUniqueOffset[rName] = nCnt;
1490 
1491  return sTmp;
1492  }
1493 
1495  {
1496  const_cast< MarkManager* >(this)->sortMarks();
1497  }
1498 
1500  {
1501  sort(m_vBookmarks.begin(), m_vBookmarks.end(), &lcl_MarkOrderingByStart);
1502  sort(m_vFieldmarks.begin(), m_vFieldmarks.end(), &lcl_MarkOrderingByStart);
1503  sort(m_vAnnotationMarks.begin(), m_vAnnotationMarks.end(), &lcl_MarkOrderingByStart);
1504  }
1505 
1507  {
1508  sort(m_vAllMarks.begin(), m_vAllMarks.end(), &lcl_MarkOrderingByStart);
1509  sortSubsetMarks();
1510  }
1511 
1513 {
1514  struct
1515  {
1516  const char* pName;
1517  const container_t* pContainer;
1518  } aContainers[] =
1519  {
1520  // UNO marks are only part of all marks.
1521  {"allmarks", &m_vAllMarks},
1522  {"bookmarks", &m_vBookmarks},
1523  {"fieldmarks", &m_vFieldmarks},
1524  {"annotationmarks", &m_vAnnotationMarks}
1525  };
1526 
1527  xmlTextWriterStartElement(pWriter, BAD_CAST("MarkManager"));
1528  for (const auto & rContainer : aContainers)
1529  {
1530  if (!rContainer.pContainer->empty())
1531  {
1532  xmlTextWriterStartElement(pWriter, BAD_CAST(rContainer.pName));
1533  for (auto it = rContainer.pContainer->begin(); it != rContainer.pContainer->end(); ++it)
1534  (*it)->dumpAsXml(pWriter);
1535  xmlTextWriterEndElement(pWriter);
1536  }
1537  }
1538  xmlTextWriterEndElement(pWriter);
1539 }
1540 
1541 }} // namespace ::sw::mark
1542 
1543 namespace
1544 {
1545  bool lcl_Greater( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
1546  {
1547  return rPos.nNode > rNdIdx || ( pIdx && rPos.nNode == rNdIdx && rPos.nContent > pIdx->GetIndex() );
1548  }
1549 }
1550 
1551 // IDocumentMarkAccess for SwDoc
1553  { return static_cast< IDocumentMarkAccess* >(mpMarkManager.get()); }
1554 
1556  { return static_cast< IDocumentMarkAccess* >(mpMarkManager.get()); }
1557 
1558 SaveBookmark::SaveBookmark(
1559  const IMark& rBkmk,
1560  const SwNodeIndex & rMvPos,
1561  const SwIndex* pIdx)
1562  : m_aName(rBkmk.GetName())
1563  , m_aShortName()
1564  , m_aCode()
1565  , m_eOrigBkmType(IDocumentMarkAccess::GetType(rBkmk))
1566 {
1567  const IBookmark* const pBookmark = dynamic_cast< const IBookmark* >(&rBkmk);
1568  if(pBookmark)
1569  {
1570  m_aShortName = pBookmark->GetShortName();
1571  m_aCode = pBookmark->GetKeyCode();
1572 
1573  ::sfx2::Metadatable const*const pMetadatable(
1574  dynamic_cast< ::sfx2::Metadatable const* >(pBookmark));
1575  if (pMetadatable)
1576  {
1577  m_pMetadataUndo = pMetadatable->CreateUndo();
1578  }
1579  }
1580  m_nNode1 = rBkmk.GetMarkPos().nNode.GetIndex();
1582 
1583  m_nNode1 -= rMvPos.GetIndex();
1584  if(pIdx && !m_nNode1)
1585  m_nContent1 -= pIdx->GetIndex();
1586 
1587  if(rBkmk.IsExpanded())
1588  {
1589  m_nNode2 = rBkmk.GetOtherMarkPos().nNode.GetIndex();
1591 
1592  m_nNode2 -= rMvPos.GetIndex();
1593  if(pIdx && !m_nNode2)
1594  m_nContent2 -= pIdx->GetIndex();
1595  }
1596  else
1597  {
1598  m_nNode2 = ULONG_MAX;
1599  m_nContent2 = -1;
1600  }
1601 }
1602 
1604  SwDoc* pDoc,
1605  const SwNodeIndex& rNewPos,
1606  const SwIndex* pIdx)
1607 {
1608  SwPaM aPam(rNewPos.GetNode());
1609  if(pIdx)
1610  aPam.GetPoint()->nContent = *pIdx;
1611 
1612  if(ULONG_MAX != m_nNode2)
1613  {
1614  aPam.SetMark();
1615 
1616  aPam.GetMark()->nNode += m_nNode2;
1617  if(pIdx && !m_nNode2)
1618  aPam.GetMark()->nContent += m_nContent2;
1619  else
1620  aPam.GetMark()->nContent.Assign(aPam.GetContentNode(false), m_nContent2);
1621  }
1622 
1623  aPam.GetPoint()->nNode += m_nNode1;
1624 
1625  if(pIdx && !m_nNode1)
1626  aPam.GetPoint()->nContent += m_nContent1;
1627  else
1628  aPam.GetPoint()->nContent.Assign(aPam.GetContentNode(), m_nContent1);
1629 
1630  if(!aPam.HasMark()
1631  || CheckNodesRange(aPam.GetPoint()->nNode, aPam.GetMark()->nNode, true))
1632  {
1633  ::sw::mark::IBookmark* const pBookmark = dynamic_cast<::sw::mark::IBookmark*>(
1634  pDoc->getIDocumentMarkAccess()->makeMark(aPam, m_aName,
1636  if(pBookmark)
1637  {
1638  pBookmark->SetKeyCode(m_aCode);
1639  pBookmark->SetShortName(m_aShortName);
1640  if (m_pMetadataUndo)
1641  {
1642  ::sfx2::Metadatable * const pMeta(
1643  dynamic_cast< ::sfx2::Metadatable* >(pBookmark));
1644  assert(pMeta && "metadata undo, but not metadatable?");
1645  if (pMeta)
1646  {
1648  }
1649  }
1650  }
1651  }
1652 }
1653 
1654 // DelBookmarks
1655 
1657  const SwNodeIndex& rStt,
1658  const SwNodeIndex& rEnd,
1659  std::vector<SaveBookmark> * pSaveBkmk,
1660  const SwIndex* pSttIdx,
1661  const SwIndex* pEndIdx)
1662 {
1663  // illegal range ??
1664  if(rStt.GetIndex() > rEnd.GetIndex()
1665  || (rStt == rEnd && (!pSttIdx || !pEndIdx || pSttIdx->GetIndex() >= pEndIdx->GetIndex())))
1666  return;
1667  SwDoc* const pDoc = rStt.GetNode().GetDoc();
1668 
1669  pDoc->getIDocumentMarkAccess()->deleteMarks(rStt, rEnd, pSaveBkmk, pSttIdx, pEndIdx);
1670 
1671  // Copy all Redlines which are in the move area into an array
1672  // which holds all position information as offset.
1673  // Assignment happens after moving.
1675  for(SwRangeRedline* pRedl : rTable)
1676  {
1677  // Is at position?
1678  SwPosition *const pRStt = pRedl->Start();
1679  SwPosition *const pREnd = pRedl->End();
1680 
1681  if( lcl_Greater( *pRStt, rStt, pSttIdx ) && lcl_Lower( *pRStt, rEnd, pEndIdx ))
1682  {
1683  pRStt->nNode = rEnd;
1684  if( pEndIdx )
1685  pRStt->nContent = *pEndIdx;
1686  else
1687  {
1688  bool bStt = true;
1689  SwContentNode* pCNd = pRStt->nNode.GetNode().GetContentNode();
1690  if( !pCNd && nullptr == ( pCNd = pDoc->GetNodes().GoNext( &pRStt->nNode )) )
1691  {
1692  bStt = false;
1693  pRStt->nNode = rStt;
1694  if( nullptr == ( pCNd = SwNodes::GoPrevious( &pRStt->nNode )) )
1695  {
1696  pRStt->nNode = pREnd->nNode;
1697  pCNd = pRStt->nNode.GetNode().GetContentNode();
1698  }
1699  }
1700  pRStt->nContent.Assign( pCNd, bStt ? 0 : pCNd->Len() );
1701  }
1702  }
1703  if( lcl_Greater( *pREnd, rStt, pSttIdx ) && lcl_Lower( *pREnd, rEnd, pEndIdx ))
1704  {
1705  pREnd->nNode = rStt;
1706  if( pSttIdx )
1707  pREnd->nContent = *pSttIdx;
1708  else
1709  {
1710  bool bStt = false;
1711  SwContentNode* pCNd = pREnd->nNode.GetNode().GetContentNode();
1712  if( !pCNd && nullptr == ( pCNd = SwNodes::GoPrevious( &pREnd->nNode )) )
1713  {
1714  bStt = true;
1715  pREnd->nNode = rEnd;
1716  if( nullptr == ( pCNd = pDoc->GetNodes().GoNext( &pREnd->nNode )) )
1717  {
1718  pREnd->nNode = pRStt->nNode;
1719  pCNd = pREnd->nNode.GetNode().GetContentNode();
1720  }
1721  }
1722  pREnd->nContent.Assign( pCNd, bStt ? 0 : pCNd->Len() );
1723  }
1724  }
1725  }
1726 }
1727 
1728 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual sw::mark::IMark * getAnnotationMarkFor(const SwPosition &rPos) const override
Definition: docbm.cxx:1433
virtual sal_Int32 Len() const
Definition: node.cxx:1181
virtual void ShowButton(SwEditWin *pEditWin)=0
bool IsInMailMerge() const
Definition: doc.hxx:952
virtual const_iterator_t findFirstAnnotationStartsAfter(const SwPosition &rPos) const override
Finds the first mark that is starting after.
Definition: docbm.cxx:1445
virtual sal_Int32 getAllMarksCount() const override
returns the number of marks.
Definition: docbm.cxx:1234
virtual const OUString & GetName() const =0
Marks a position in the document model.
Definition: pam.hxx:35
void DelBookmarks(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, std::vector< SaveBookmark > *pSaveBkmk, const SwIndex *pSttIdx, const SwIndex *pEndIdx)
Definition: docbm.cxx:1656
sw::mark::FieldmarkWithDropDownButton * m_pLastActiveFieldmark
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:184
virtual const_iterator_t findFirstBookmarkStartsAfter(const SwPosition &rPos) const override
Finds the first mark that is starting after.
Definition: docbm.cxx:1247
sal_uLong m_nNode2
Definition: mvsave.hxx:64
virtual void SetFieldname(const OUString &rFieldname)=0
To avoid recursive calls of deleteMark, the removal of dummy characters of fieldmarks has to be delay...
SwNodeIndex nNode
Definition: pam.hxx:37
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:284
virtual void SetModified()=0
Must be called manually at changes of format.
std::unique_ptr< std::vector<::sw::mark::MarkBase * >::const_iterator > m_pIter
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:483
container_t m_vFieldmarks
const SwPosition * GetMark() const
Definition: pam.hxx:209
OUString getUniqueMarkName(const OUString &rName) const
Definition: docbm.cxx:1454
Provides access to the marks of a document.
Definition: doc.hxx:185
#define ODF_FORMCHECKBOX
void SetInDoc(SwDoc *pDoc, const SwNodeIndex &, const SwIndex *pIdx=nullptr)
Definition: docbm.cxx:1603
virtual const SwPosition & GetMarkPos() const =0
virtual ::sw::mark::IFieldmark * getFieldmarkAfter(const SwPosition &rPos) const override
Definition: docbm.cxx:1406
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1290
SwNode & GetNode() const
Definition: ndindex.hxx:118
virtual ::sw::mark::IMark * makeMark(const SwPaM &rPaM, const OUString &rProposedName, MarkType eMark,::sw::mark::InsertMode eMode)=0
Generates a new mark in the document for a certain selection.
SwEditWin & GetEditWin()
Definition: view.hxx:403
virtual const_iterator_t getAllMarksBegin() const override
returns a STL-like random access iterator to the begin of the sequence of marks.
Definition: docbm.cxx:1228
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1552
Dialog to specify the properties of date form field.
Definition: accfrmobj.cxx:38
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:176
virtual const_iterator_t getAnnotationMarksBegin() const override
Definition: docbm.cxx:1412
IDocumentMarkAccess::MarkType const m_eOrigBkmType
Definition: mvsave.hxx:62
SfxViewShell * GetSfxViewShell() const
Definition: viewsh.hxx:444
virtual ~LazyFieldmarkDeleter() override
Definition: docbm.cxx:1098
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &rPos) const override
Definition: docbm.cxx:1256
Fieldmark with a drop down button (e.g. this button opens the date picker for a date field) ...
Definition: bookmrk.hxx:273
virtual sw::mark::IFieldmark * makeNoTextFieldBookmark(const SwPaM &rPaM, const OUString &rName, const OUString &rType) override
Definition: docbm.cxx:691
virtual bool IsExpanded() const override
Definition: bookmrk.hxx:83
virtual const_iterator_t getBookmarksEnd() const override
returns a STL-like random access iterator to the end of the sequence of IBookmarks.
Definition: docbm.cxx:1240
virtual const OUString & GetName() const override
Definition: bookmrk.hxx:58
virtual void clearAllMarks() override
Clear (deletes) all marks.
Definition: docbm.cxx:1205
static SW_DLLPUBLIC OUString GetCrossRefHeadingBookmarkNamePrefix()
Definition: docbm.cxx:517
static SW_DLLPUBLIC bool IsLegalPaMForCrossRefHeadingBookmark(const SwPaM &rPaM)
Definition: docbm.cxx:522
bool operator==(iterator const &rOther) const
Definition: docbm.cxx:117
SwIndex nContent
Definition: pam.hxx:38
container_t m_vBookmarks
SwDoc * GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:176
sal_Int32 m_nContent1
Definition: mvsave.hxx:65
iterator & operator-=(difference_type)
Definition: docbm.cxx:156
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
virtual void DoUndo(bool const bDoUndo)=0
Enable/Disable Undo.
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: docbm.cxx:1512
sal_uLong m_nNode1
Definition: mvsave.hxx:63
bool CheckNodesRange(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, bool bChkSection)
Definition: pam.cxx:236
virtual bool IsEnableSetModified() const =0
virtual ::sw::mark::IMark * getMarkForTextNode(const SwTextNode &rTextNode, IDocumentMarkAccess::MarkType eMark) override
Returns a mark in the document for a paragraph.
Definition: docbm.cxx:740
bool operator!=(iterator const &rOther) const
Definition: docbm.cxx:122
virtual void deleteMarks(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, std::vector< ::sw::mark::SaveBookmark > *pSaveBkmk, const SwIndex *pSttIdx, const SwIndex *pEndIdx) override
Deletes marks in a range.
Definition: docbm.cxx:908
virtual bool DoesUndo() const =0
Is Undo enabled?
virtual void SetKeyCode(const vcl::KeyCode &)=0
virtual void SetShortName(const OUString &)=0
bool ContainsPosition(const SwPosition &rPos) const
Definition: pam.hxx:257
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
struct _xmlTextWriter * xmlTextWriterPtr
virtual void AppendUndo(std::unique_ptr< SwUndo > pUndo)=0
Add new Undo action.
virtual sal_Int32 getAnnotationMarksCount() const override
Definition: docbm.cxx:1422
container_t m_vAnnotationMarks
#define SAL_MAX_INT32
OUString m_aShortName
Definition: mvsave.hxx:60
virtual void deleteMarks(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, std::vector< ::sw::mark::SaveBookmark > *pSaveBkmk, const SwIndex *pSttIdx, const SwIndex *pEndIdx)=0
Deletes marks in a range.
OUString const m_aName
Definition: mvsave.hxx:59
virtual const_iterator_t getAnnotationMarksEnd() const override
Definition: docbm.cxx:1417
const SwPosition * GetPoint() const
Definition: pam.hxx:207
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
const std::unique_ptr< ::sw::mark::MarkManager > mpMarkManager
Definition: doc.hxx:208
std::vector< sw::mark::MarkBase * > container_t
std::unique_ptr< Fieldmark > m_pFieldmark
Definition: docbm.cxx:1091
OUString sName
virtual void assureSortedMarkContainers() const override
Definition: docbm.cxx:1494
MarkBasenameMapUniqueOffset_t m_aMarkBasenameMapUniqueOffset
SwContentNode * GetContentNode()
Definition: node.hxx:615
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
virtual const_iterator_t findMark(const OUString &rName) const override
Finds a mark by name.
Definition: docbm.cxx:1216
SwDoc * GetDoc()
Definition: node.hxx:702
virtual std::unique_ptr< ILazyDeleter > deleteMark(const const_iterator_t &ppMark) override
Deletes a mark.
Definition: docbm.cxx:1105
virtual const OUString & GetShortName() const =0
virtual bool renameMark(::sw::mark::IMark *io_pMark, const OUString &rNewName) override
Renames an existing Mark, if possible.
Definition: docbm.cxx:784
iterator operator-(difference_type) const
Definition: docbm.cxx:162
iterator operator+(difference_type) const
Definition: docbm.cxx:151
Marks a character position inside a document model node.
Definition: index.hxx:37
virtual bool IsCoveringPosition(const SwPosition &rPos) const =0
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:426
std::shared_ptr< MetadatableUndo > CreateUndo() const
std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndo
Definition: mvsave.hxx:67
Marks a node in the document model.
Definition: ndindex.hxx:31
sal_uInt16 sal_Char * pName
virtual const vcl::KeyCode & GetKeyCode() const =0
OUString newName(const OUString &aNewPrefix, const OUString &aOldPrefix, const OUString &old_Name)
iterator & operator=(iterator const &rOther)
Definition: docbm.cxx:77
virtual const_iterator_t getAllMarksEnd() const override
returns a STL-like random access iterator to the end of the sequence of marks.
Definition: docbm.cxx:1231
virtual const_iterator_t findAnnotationMark(const OUString &rName) const override
Definition: docbm.cxx:1427
const SwPosition * Start() const
Definition: pam.hxx:212
void SetMark(const sw::mark::IMark *pMark)
Definition: index.cxx:214
virtual sw::mark::IMark * makeAnnotationMark(const SwPaM &rPaM, const OUString &rName) override
Definition: docbm.cxx:753
virtual SwPosition & GetOtherMarkPos() const override
Definition: bookmrk.hxx:60
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
virtual sal_Int32 getBookmarksCount() const override
returns the number of IBookmarks.
Definition: docbm.cxx:1243
bool operator<=(iterator const &rOther) const
Definition: docbm.cxx:185
virtual void correctMarksAbsolute(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset) override
Corrects marks (absolute) This method ignores the previous position of the mark in the paragraph...
Definition: docbm.cxx:813
virtual void NotifyCursorUpdate(const SwCursorShell &rCursorShell) override
Definition: docbm.cxx:1329
const SwNodes & GetNodes() const
Definition: ndindex.hxx:155
#define SAL_INFO(area, stream)
sal_Int32 GetIndex() const
Definition: index.hxx:95
OString DateTimeToOString(const DateTime &rDateTime)
virtual sw::mark::IFieldmark * makeFieldBookmark(const SwPaM &rPaM, const OUString &rName, const OUString &rType) override
Definition: docbm.cxx:655
virtual SwPosition & GetMarkPos() const override
Definition: bookmrk.hxx:56
SwNodes & GetNodes()
Definition: doc.hxx:402
bool operator>(iterator const &rOther) const
Definition: docbm.cxx:181
virtual const_iterator_t findBookmark(const OUString &rName) const override
Finds a bookmark by name.
Definition: docbm.cxx:1222
const SwPosition * End() const
Definition: pam.hxx:217
virtual void correctMarksRelative(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset) override
Corrects marks (relative) This method uses the previous position of the mark in the paragraph as offs...
Definition: docbm.cxx:859
virtual void SetMarkPos(const SwPosition &rNewPos)
Definition: bookmrk.cxx:175
iterator & operator+=(difference_type)
Definition: docbm.cxx:145
virtual ::sw::mark::IFieldmark * getFieldmarkBefore(const SwPosition &rPos) const override
Definition: docbm.cxx:1409
virtual ::sw::mark::IFieldmark * getDropDownFor(const SwPosition &rPos) const override
Definition: docbm.cxx:1376
virtual const SwPosition & GetMarkEnd() const =0
virtual void deleteFieldmarkAt(const SwPosition &rPos) override
Definition: docbm.cxx:1267
virtual std::vector< ::sw::mark::IFieldmark * > getDropDownsFor(const SwPaM &rPaM) const override
Definition: docbm.cxx:1384
#define ODF_FORMDATE
virtual void SetEnableSetModified(bool bEnableSetModified)=0
virtual OUString GetFieldname() const =0
virtual ::sw::mark::IFieldmark * changeFormFieldmarkType(::sw::mark::IFieldmark *pFieldmark, const OUString &rNewType) override
Definition: docbm.cxx:1279
#define SAL_WARN(area, stream)
virtual void ClearFieldActivation() override
Definition: docbm.cxx:1368
vcl::KeyCode m_aCode
Definition: mvsave.hxx:61
virtual void DeregisterFromDoc(SwDoc *const pDoc)
Definition: bookmrk.cxx:266
virtual const SwPosition & GetMarkStart() const =0
::sw::mark::IMark * operator*() const
Definition: docbm.cxx:100
sal_Int32 m_nContent2
Definition: mvsave.hxx:66
InsertMode
Definition: IMark.hxx:31
virtual void SetOtherMarkPos(const SwPosition &rNewPos)
Definition: bookmrk.cxx:181
virtual const SwRedlineTable & GetRedlineTable() const =0
virtual const_iterator_t getBookmarksBegin() const override
returns a STL-like random access iterator to the begin of the sequence the IBookmarks.
Definition: docbm.cxx:1237
bool operator<(iterator const &rOther) const
Definition: docbm.cxx:177
bool operator>=(iterator const &rOther) const
Definition: docbm.cxx:189
virtual bool IsExpanded() const =0
std::vector<::sw::mark::MarkBase * >::const_iterator const & get() const
Definition: docbm.cxx:62
bool IsTextNode() const
Definition: node.hxx:636
value_type operator[](difference_type) const
Definition: docbm.cxx:172
virtual void repositionMark(::sw::mark::IMark *io_pMark, const SwPaM &rPaM) override
Moves an existing mark to a new selection and performs needed updates.
Definition: docbm.cxx:761
void RestoreMetadata(std::shared_ptr< MetadatableUndo > const &i_pUndo)
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1273
LazyFieldmarkDeleter(Fieldmark *pMark, SwDoc *const pDoc)
Definition: docbm.cxx:1093
Definition: view.hxx:146
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
#define ODF_FORMDROPDOWN
virtual const SwPosition & GetOtherMarkPos() const =0
virtual ::sw::mark::IMark * makeMark(const SwPaM &rPaM, const OUString &rName, IDocumentMarkAccess::MarkType eMark, sw::mark::InsertMode eMode) override
Definition: docbm.cxx:542
Base class of the Writer document model elements.
Definition: node.hxx:79
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo