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 OUString("__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  m_pDoc->GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoInsTextFieldmark>(*pFieldMark));
685  }
686 
687  return pFieldMark;
688  }
689 
691  const SwPaM& rPaM,
692  const OUString& rName,
693  const OUString& rType)
694  {
695  // Disable undo, because we handle it using SwUndoInsNoTextFieldmark
696  bool bUndoIsEnabled = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
698 
699  bool bEnableSetModified = m_pDoc->getIDocumentState().IsEnableSetModified();
701 
702  sw::mark::IMark* pMark = nullptr;
703  if(rType == ODF_FORMCHECKBOX)
704  {
705  pMark = makeMark( rPaM, rName,
708  }
709  else if(rType == ODF_FORMDROPDOWN)
710  {
711  pMark = makeMark( rPaM, rName,
714  }
715  else if(rType == ODF_FORMDATE)
716  {
717  pMark = makeMark( rPaM, rName,
720  }
721 
722  sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
723  if (pFieldMark)
724  pFieldMark->SetFieldname( rType );
725 
726  if (bUndoIsEnabled)
727  {
728  m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoIsEnabled);
729  m_pDoc->GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoInsNoTextFieldmark>(*pFieldMark));
730  }
731 
732  m_pDoc->getIDocumentState().SetEnableSetModified(bEnableSetModified);
734 
735  return pFieldMark;
736  }
737 
739  const SwTextNode& rTextNode,
740  const IDocumentMarkAccess::MarkType eType )
741  {
742  SwPosition aPos(rTextNode);
743  aPos.nContent.Assign(&const_cast<SwTextNode&>(rTextNode), 0);
744  auto const ppExistingMark = lcl_FindMarkAtPos(m_vBookmarks, aPos, eType);
745  if(ppExistingMark != m_vBookmarks.end())
746  return *ppExistingMark;
747  const SwPaM aPaM(aPos);
748  return makeMark(aPaM, OUString(), eType, sw::mark::InsertMode::New);
749  }
750 
752  const SwPaM& rPaM,
753  const OUString& rName )
754  {
757  }
758 
760  ::sw::mark::IMark* const io_pMark,
761  const SwPaM& rPaM)
762  {
763  assert(io_pMark->GetMarkPos().GetDoc() == m_pDoc &&
764  "<MarkManager::repositionMark(..)>"
765  " - Mark is not in my doc.");
766  MarkBase* const pMarkBase = dynamic_cast< MarkBase* >(io_pMark);
767  if (!pMarkBase)
768  return;
769 
770  pMarkBase->SetMarkPos(*(rPaM.GetPoint()));
771  if(rPaM.HasMark())
772  pMarkBase->SetOtherMarkPos(*(rPaM.GetMark()));
773  else
774  pMarkBase->ClearOtherMarkPos();
775 
776  if(pMarkBase->GetMarkPos() != pMarkBase->GetMarkStart())
777  pMarkBase->Swap();
778 
779  sortMarks();
780  }
781 
783  ::sw::mark::IMark* io_pMark,
784  const OUString& rNewName )
785  {
786  assert(io_pMark->GetMarkPos().GetDoc() == m_pDoc &&
787  "<MarkManager::renameMark(..)>"
788  " - Mark is not in my doc.");
789  if ( io_pMark->GetName() == rNewName )
790  return true;
791  if (lcl_FindMarkByName(rNewName, m_vAllMarks.begin(), m_vAllMarks.end()) != m_vAllMarks.end())
792  return false;
793  if (::sw::mark::MarkBase* pMarkBase = dynamic_cast< ::sw::mark::MarkBase* >(io_pMark))
794  {
795  const OUString sOldName(pMarkBase->GetName());
796  pMarkBase->SetName(rNewName);
797 
798  if (dynamic_cast< ::sw::mark::Bookmark* >(io_pMark))
799  {
801  {
803  std::make_unique<SwUndoRenameBookmark>(sOldName, rNewName, m_pDoc));
804  }
806  }
807  }
808  return true;
809  }
810 
812  const SwNodeIndex& rOldNode,
813  const SwPosition& rNewPos,
814  const sal_Int32 nOffset)
815  {
816  const SwNode* const pOldNode = &rOldNode.GetNode();
817  SwPosition aNewPos(rNewPos);
818  aNewPos.nContent += nOffset;
819  bool isSortingNeeded = false;
820 
821  for (auto ppMark = m_vAllMarks.begin();
822  ppMark != m_vAllMarks.end();
823  ++ppMark)
824  {
825  ::sw::mark::MarkBase *const pMark = *ppMark;
826  // correction of non-existent non-MarkBase instances cannot be done
827  assert(pMark);
828  // is on position ??
829  bool bChangedPos = false;
830  if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
831  {
832  pMark->SetMarkPos(aNewPos);
833  bChangedPos = true;
834  isSortingNeeded = true;
835  }
836  bool bChangedOPos = false;
837  if (pMark->IsExpanded() &&
838  &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
839  {
840  // shift the OtherMark to aNewPos
841  pMark->SetOtherMarkPos(aNewPos);
842  bChangedOPos= true;
843  isSortingNeeded = true;
844  }
845  // illegal selection? collapse the mark and restore sorting later
846  isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
847  }
848 
849  // restore sorting if needed
850  if(isSortingNeeded)
851  sortMarks();
852 
853  SAL_INFO("sw.core", "correctMarksAbsolute");
854  lcl_DebugMarks(m_vAllMarks);
855  }
856 
857  void MarkManager::correctMarksRelative(const SwNodeIndex& rOldNode, const SwPosition& rNewPos, const sal_Int32 nOffset)
858  {
859  const SwNode* const pOldNode = &rOldNode.GetNode();
860  SwPosition aNewPos(rNewPos);
861  aNewPos.nContent += nOffset;
862  bool isSortingNeeded = false;
863 
864  for (auto ppMark = m_vAllMarks.begin();
865  ppMark != m_vAllMarks.end();
866  ++ppMark)
867  {
868  // is on position ??
869  bool bChangedPos = false, bChangedOPos = false;
870  ::sw::mark::MarkBase* const pMark = *ppMark;
871  // correction of non-existent non-MarkBase instances cannot be done
872  assert(pMark);
873  if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
874  {
875  SwPosition aNewPosRel(aNewPos);
876  if (dynamic_cast< ::sw::mark::CrossRefBookmark *>(pMark))
877  {
878  // ensure that cross ref bookmark always starts at 0
879  aNewPosRel.nContent = 0; // HACK for WW8 import
880  isSortingNeeded = true; // and sort them to be safe...
881  }
882  aNewPosRel.nContent += pMark->GetMarkPos().nContent.GetIndex();
883  pMark->SetMarkPos(aNewPosRel);
884  bChangedPos = true;
885  }
886  if(pMark->IsExpanded() &&
887  &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
888  {
889  SwPosition aNewPosRel(aNewPos);
890  aNewPosRel.nContent += pMark->GetOtherMarkPos().nContent.GetIndex();
891  pMark->SetOtherMarkPos(aNewPosRel);
892  bChangedOPos = true;
893  }
894  // illegal selection? collapse the mark and restore sorting later
895  isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
896  }
897 
898  // restore sorting if needed
899  if(isSortingNeeded)
900  sortMarks();
901 
902  SAL_INFO("sw.core", "correctMarksRelative");
903  lcl_DebugMarks(m_vAllMarks);
904  }
905 
907  const SwNodeIndex& rStt,
908  const SwNodeIndex& rEnd,
909  std::vector<SaveBookmark>* pSaveBkmk,
910  const SwIndex* pSttIdx,
911  const SwIndex* pEndIdx )
912  {
913  std::vector<const_iterator_t> vMarksToDelete;
914  bool bIsSortingNeeded = false;
915 
916  // boolean indicating, if at least one mark has been moved while collecting marks for deletion
917  bool bMarksMoved = false;
918  // have marks in the range been skipped instead of deleted
919  bool bMarksSkipDeletion = false;
920 
921  // copy all bookmarks in the move area to a vector storing all position data as offset
922  // reassignment is performed after the move
923  for (auto ppMark = m_vAllMarks.begin();
924  ppMark != m_vAllMarks.end();
925  ++ppMark)
926  {
927  // navigator marks should not be moved
928  // TODO: Check if this might make them invalid
930  continue;
931 
932  ::sw::mark::MarkBase *const pMark = *ppMark;
933 
934  if (!pMark)
935  continue;
936 
937  // on position ??
938  bool bIsPosInRange = lcl_GreaterThan(pMark->GetMarkPos(), rStt, pSttIdx)
939  && lcl_Lower(pMark->GetMarkPos(), rEnd, pEndIdx);
940  bool bIsOtherPosInRange = pMark->IsExpanded()
941  && lcl_GreaterThan(pMark->GetOtherMarkPos(), rStt, pSttIdx)
942  && lcl_Lower(pMark->GetOtherMarkPos(), rEnd, pEndIdx);
943  // special case: completely in range, touching the end?
944  if ( pEndIdx != nullptr
945  && ( ( bIsOtherPosInRange
946  && pMark->GetMarkPos().nNode == rEnd
947  && pMark->GetMarkPos().nContent == *pEndIdx )
948  || ( bIsPosInRange
949  && pMark->IsExpanded()
950  && pMark->GetOtherMarkPos().nNode == rEnd
951  && pMark->GetOtherMarkPos().nContent == *pEndIdx ) ) )
952  {
953  bIsPosInRange = true;
954  bIsOtherPosInRange = true;
955  }
956 
957  if ( bIsPosInRange
958  && ( bIsOtherPosInRange
959  || !pMark->IsExpanded() ) )
960  {
961  // completely in range
962 
963  bool bDeleteMark = true;
964  {
965  switch ( IDocumentMarkAccess::GetType( *pMark ) )
966  {
969  // no delete of cross-reference bookmarks, if range is inside one paragraph
970  bDeleteMark = rStt != rEnd;
971  break;
973  // no delete of UNO mark, if it is not expanded and only touches the start of the range
974  bDeleteMark = bIsOtherPosInRange
975  || pMark->IsExpanded()
976  || pSttIdx == nullptr
977  || !( pMark->GetMarkPos().nNode == rStt
978  && pMark->GetMarkPos().nContent == *pSttIdx );
979  break;
980  default:
981  bDeleteMark = true;
982  break;
983  }
984  }
985 
986  if ( bDeleteMark )
987  {
988  if ( pSaveBkmk )
989  {
990  pSaveBkmk->push_back( SaveBookmark( *pMark, rStt, pSttIdx ) );
991  }
992  vMarksToDelete.emplace_back(ppMark);
993  }
994  else
995  {
996  bMarksSkipDeletion = true;
997  }
998  }
999  else if ( bIsPosInRange != bIsOtherPosInRange )
1000  {
1001  // the bookmark is partially in the range
1002  // move position of that is in the range out of it
1003 
1004  std::unique_ptr< SwPosition > pNewPos;
1005  {
1006  if ( pEndIdx != nullptr )
1007  {
1008  pNewPos = std::make_unique< SwPosition >( rEnd, *pEndIdx );
1009  }
1010  else
1011  {
1012  pNewPos =
1013  lcl_FindExpelPosition( rStt, rEnd, bIsPosInRange ? pMark->GetOtherMarkPos() : pMark->GetMarkPos() );
1014  }
1015  }
1016 
1017  bool bMoveMark = true;
1018  {
1019  switch ( IDocumentMarkAccess::GetType( *pMark ) )
1020  {
1023  // no move of cross-reference bookmarks, if move occurs inside a certain node
1024  bMoveMark = pMark->GetMarkPos().nNode != pNewPos->nNode;
1025  break;
1027  // no move of annotation marks, if method is called to collect deleted marks
1028  bMoveMark = pSaveBkmk == nullptr;
1029  break;
1030  default:
1031  bMoveMark = true;
1032  break;
1033  }
1034  }
1035  if ( bMoveMark )
1036  {
1037  if ( bIsPosInRange )
1038  pMark->SetMarkPos(*pNewPos);
1039  else
1040  pMark->SetOtherMarkPos(*pNewPos);
1041  bMarksMoved = true;
1042 
1043  // illegal selection? collapse the mark and restore sorting later
1044  bIsSortingNeeded |= lcl_FixCorrectedMark( bIsPosInRange, bIsOtherPosInRange, pMark );
1045  }
1046  }
1047  }
1048 
1049  {
1050  // fdo#61016 delay the deletion of the fieldmark characters
1051  // to prevent that from deleting the marks on that position
1052  // which would invalidate the iterators in vMarksToDelete
1053  std::vector< std::unique_ptr<ILazyDeleter> > vDelay;
1054  vDelay.reserve(vMarksToDelete.size());
1055 
1056  // If needed, sort mark containers containing subsets of the marks
1057  // in order to assure sorting. The sorting is critical for the
1058  // deletion of a mark as it is searched in these container for
1059  // deletion.
1060  if ( !vMarksToDelete.empty() && bMarksMoved )
1061  {
1062  sortSubsetMarks();
1063  }
1064  // we just remembered the iterators to delete, so we do not need to search
1065  // for the shared_ptr<> (the entry in m_vAllMarks) again
1066  // reverse iteration, since erasing an entry invalidates iterators
1067  // behind it (the iterators in vMarksToDelete are sorted)
1068  for ( std::vector< const_iterator_t >::reverse_iterator pppMark = vMarksToDelete.rbegin();
1069  pppMark != vMarksToDelete.rend();
1070  ++pppMark )
1071  {
1072  vDelay.push_back(deleteMark(*pppMark));
1073  }
1074  } // scope to kill vDelay
1075 
1076  // also need to sort if both marks were moved and not-deleted because
1077  // the not-deleted marks could be in wrong order vs. the moved ones
1078  if (bIsSortingNeeded || (bMarksMoved && bMarksSkipDeletion))
1079  {
1080  sortMarks();
1081  }
1082 
1083  SAL_INFO("sw.core", "deleteMarks");
1084  lcl_DebugMarks(m_vAllMarks);
1085  }
1086 
1088  {
1089  std::unique_ptr<Fieldmark> m_pFieldmark;
1091  LazyFieldmarkDeleter(Fieldmark* pMark, SwDoc *const pDoc)
1092  : m_pFieldmark(pMark), m_pDoc(pDoc)
1093  {
1094  assert(m_pFieldmark);
1095  }
1096  virtual ~LazyFieldmarkDeleter() override
1097  {
1098  m_pFieldmark->ReleaseDoc(m_pDoc);
1099  }
1100  };
1101 
1102  std::unique_ptr<IDocumentMarkAccess::ILazyDeleter>
1104  {
1105  std::unique_ptr<ILazyDeleter> ret;
1106  if (ppMark.get() == m_vAllMarks.end())
1107  return ret;
1108  IMark* pMark = *ppMark;
1109 
1110  switch(IDocumentMarkAccess::GetType(*pMark))
1111  {
1115  {
1116  auto const ppBookmark = lcl_FindMark(m_vBookmarks, *ppMark.get());
1117  if ( ppBookmark != m_vBookmarks.end() )
1118  {
1119  m_vBookmarks.erase(ppBookmark);
1120  }
1121  else
1122  {
1123  assert(false &&
1124  "<MarkManager::deleteMark(..)> - Bookmark not found in Bookmark container.");
1125  }
1126  }
1127  break;
1128 
1133  {
1134  auto const ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark.get());
1135  if ( ppFieldmark != m_vFieldmarks.end() )
1136  {
1137  if(m_pLastActiveFieldmark == *ppFieldmark)
1139 
1140  m_vFieldmarks.erase(ppFieldmark);
1141  ret.reset(new LazyFieldmarkDeleter(dynamic_cast<Fieldmark*>(pMark), m_pDoc));
1142  }
1143  else
1144  {
1145  assert(false &&
1146  "<MarkManager::deleteMark(..)> - Fieldmark not found in Fieldmark container.");
1147  }
1148  }
1149  break;
1150 
1152  {
1153  auto const ppAnnotationMark = lcl_FindMark(m_vAnnotationMarks, *ppMark.get());
1154  assert(ppAnnotationMark != m_vAnnotationMarks.end() &&
1155  "<MarkManager::deleteMark(..)> - Annotation Mark not found in Annotation Mark container.");
1156  m_vAnnotationMarks.erase(ppAnnotationMark);
1157  }
1158  break;
1159 
1163  // no special marks container
1164  break;
1165  }
1166  DdeBookmark* const pDdeBookmark = dynamic_cast<DdeBookmark*>(pMark);
1167  if (pDdeBookmark)
1168  pDdeBookmark->DeregisterFromDoc(m_pDoc);
1169  //Effective STL Item 27, get a non-const iterator aI at the same
1170  //position as const iterator ppMark was
1171  auto aI = m_vAllMarks.begin();
1172  std::advance(aI, std::distance<container_t::const_iterator>(aI, ppMark.get()));
1173 
1174  m_vAllMarks.erase(aI);
1175  // If we don't have a lazy deleter
1176  if (!ret)
1177  // delete after we remove from the list, because the destructor can
1178  // recursively call into this method.
1179  delete pMark;
1180  return ret;
1181  }
1182 
1183  void MarkManager::deleteMark(const IMark* const pMark)
1184  {
1185  assert(pMark->GetMarkPos().GetDoc() == m_pDoc &&
1186  "<MarkManager::deleteMark(..)>"
1187  " - Mark is not in my doc.");
1188  // finds the last Mark that is starting before pMark
1189  // (pMarkLow < pMark)
1190  auto [it, endIt] = equal_range(
1191  m_vAllMarks.begin(),
1192  m_vAllMarks.end(),
1193  pMark->GetMarkStart(),
1194  CompareIMarkStartsBefore());
1195  for ( ; it != endIt; ++it)
1196  if (*it == pMark)
1197  {
1198  deleteMark(iterator(it));
1199  break;
1200  }
1201  }
1202 
1204  {
1206  m_vFieldmarks.clear();
1207  m_vBookmarks.clear();
1208  m_vAnnotationMarks.clear();
1209  for (auto & p : m_vAllMarks)
1210  delete p;
1211  m_vAllMarks.clear();
1212  }
1213 
1215  {
1216  auto const ret = lcl_FindMarkByName(rName, m_vAllMarks.begin(), m_vAllMarks.end());
1217  return IDocumentMarkAccess::iterator(ret);
1218  }
1219 
1221  {
1222  auto const ret = lcl_FindMarkByName(rName, m_vBookmarks.begin(), m_vBookmarks.end());
1223  return IDocumentMarkAccess::iterator(ret);
1224  }
1225 
1226  // find the first Mark that does not start before
1228  {
1229  return std::lower_bound(
1230  m_vAllMarks.begin(),
1231  m_vAllMarks.end(),
1232  rPos,
1233  CompareIMarkStartsBefore());
1234  }
1235 
1237  { return m_vAllMarks.begin(); }
1238 
1240  { return m_vAllMarks.end(); }
1241 
1243  { return m_vAllMarks.size(); }
1244 
1246  { return m_vBookmarks.begin(); }
1247 
1249  { return m_vBookmarks.end(); }
1250 
1252  { return m_vBookmarks.size(); }
1253 
1254  // finds the first that is starting after
1256  {
1257  return std::upper_bound(
1258  m_vBookmarks.begin(),
1259  m_vBookmarks.end(),
1260  rPos,
1261  CompareIMarkStartsAfter());
1262  }
1263 
1265  {
1266  auto const pFieldmark = find_if(
1267  m_vFieldmarks.begin(),
1268  m_vFieldmarks.end(),
1269  [&rPos] (const ::sw::mark::MarkBase *const pMark) { return pMark->IsCoveringPosition(rPos); } );
1270  if(pFieldmark == m_vFieldmarks.end())
1271  return nullptr;
1272  return dynamic_cast<IFieldmark*>(*pFieldmark);
1273  }
1274 
1276  {
1277  auto const pFieldmark = find_if(
1278  m_vFieldmarks.begin(),
1279  m_vFieldmarks.end(),
1280  [&rPos] (const ::sw::mark::IMark* pMark) { return pMark->IsCoveringPosition(rPos); } );
1281  if(pFieldmark == m_vFieldmarks.end())
1282  return;
1283 
1284  deleteMark(lcl_FindMark(m_vAllMarks, *pFieldmark));
1285  }
1286 
1288  {
1289  bool bActualChange = false;
1290  if(rNewType == ODF_FORMDROPDOWN)
1291  {
1292  if (!dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark))
1293  bActualChange = true;
1294  if (!dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark)) // only allowed converting between checkbox <-> dropdown
1295  return nullptr;
1296  }
1297  else if(rNewType == ODF_FORMCHECKBOX)
1298  {
1299  if (!dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark))
1300  bActualChange = true;
1301  if (!dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark)) // only allowed converting between checkbox <-> dropdown
1302  return nullptr;
1303  }
1304  else if(rNewType == ODF_FORMDATE)
1305  {
1306  if (!dynamic_cast<::sw::mark::DateFieldmark*>(pFieldmark))
1307  bActualChange = true;
1308  if (!dynamic_cast<::sw::mark::TextFieldmark*>(pFieldmark)) // only allowed converting between date field <-> text field
1309  return nullptr;
1310  }
1311 
1312  if (!bActualChange)
1313  return nullptr;
1314 
1315  // Store attributes needed to create the new fieldmark
1316  OUString sName = pFieldmark->GetName();
1317  SwPaM aPaM(pFieldmark->GetMarkPos());
1318 
1319  // Remove the old fieldmark and create a new one with the new type
1320  if(aPaM.GetPoint()->nContent > 0 && (rNewType == ODF_FORMDROPDOWN || rNewType == ODF_FORMCHECKBOX))
1321  {
1322  --aPaM.GetPoint()->nContent;
1323  SwPosition aNewPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent);
1324  deleteFieldmarkAt(aNewPos);
1325  return makeNoTextFieldBookmark(aPaM, sName, rNewType);
1326  }
1327  else if(rNewType == ODF_FORMDATE)
1328  {
1329  SwPosition aPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent);
1330  SwPaM aNewPaM(pFieldmark->GetMarkStart(), pFieldmark->GetMarkEnd());
1331  deleteFieldmarkAt(aPos);
1332  return makeFieldBookmark(aNewPaM, sName, rNewType);
1333  }
1334  return nullptr;
1335  }
1336 
1338  {
1339  SwView* pSwView = dynamic_cast<SwView *>(rCursorShell.GetSfxViewShell());
1340  if(!pSwView)
1341  return;
1342 
1343  SwEditWin& rEditWin = pSwView->GetEditWin();
1344  SwPosition aPos(*rCursorShell.GetCursor()->GetPoint());
1345  IFieldmark* pFieldBM = getFieldmarkFor(aPos);
1346  FieldmarkWithDropDownButton* pNewActiveFieldmark = nullptr;
1347  if ((!pFieldBM || (pFieldBM->GetFieldname() != ODF_FORMDROPDOWN && pFieldBM->GetFieldname() != ODF_FORMDATE))
1348  && aPos.nContent.GetIndex() > 0 )
1349  {
1350  --aPos.nContent;
1351  pFieldBM = getFieldmarkFor(aPos);
1352  }
1353 
1354  if ( pFieldBM && (pFieldBM->GetFieldname() == ODF_FORMDROPDOWN ||
1355  pFieldBM->GetFieldname() == ODF_FORMDATE))
1356  {
1357  if (m_pLastActiveFieldmark != pFieldBM)
1358  {
1359  auto pFormField = dynamic_cast<FieldmarkWithDropDownButton*>(pFieldBM);
1360  pFormField->ShowButton(&rEditWin);
1361  pNewActiveFieldmark = pFormField;
1362  }
1363  else
1364  {
1365  pNewActiveFieldmark = m_pLastActiveFieldmark;
1366  }
1367  }
1368 
1369  if(pNewActiveFieldmark != m_pLastActiveFieldmark)
1370  {
1372  m_pLastActiveFieldmark = pNewActiveFieldmark;
1373  }
1374  }
1375 
1377  {
1380 
1381  m_pLastActiveFieldmark = nullptr;
1382  }
1383 
1385  {
1386  IFieldmark *pMark = getFieldmarkFor(rPos);
1387  if (!pMark || pMark->GetFieldname() != ODF_FORMDROPDOWN)
1388  return nullptr;
1389  return pMark;
1390  }
1391 
1392  std::vector<IFieldmark*> MarkManager::getDropDownsFor(const SwPaM &rPaM) const
1393  {
1394  std::vector<IFieldmark*> aRet;
1395 
1396  for (auto aI = m_vFieldmarks.begin(),
1397  aEnd = m_vFieldmarks.end(); aI != aEnd; ++aI)
1398  {
1399  ::sw::mark::IMark* pI = *aI;
1400  const SwPosition &rStart = pI->GetMarkPos();
1401  if (!rPaM.ContainsPosition(rStart))
1402  continue;
1403 
1404  IFieldmark *pMark = dynamic_cast<IFieldmark*>(pI);
1405  if (!pMark || pMark->GetFieldname() != ODF_FORMDROPDOWN)
1406  continue;
1407 
1408  aRet.push_back(pMark);
1409  }
1410 
1411  return aRet;
1412  }
1413 
1415  { return dynamic_cast<IFieldmark*>(lcl_getMarkAfter(m_vFieldmarks, rPos)); }
1416 
1418  { return dynamic_cast<IFieldmark*>(lcl_getMarkBefore(m_vFieldmarks, rPos)); }
1419 
1421  {
1422  return m_vAnnotationMarks.begin();
1423  }
1424 
1426  {
1427  return m_vAnnotationMarks.end();
1428  }
1429 
1431  {
1432  return m_vAnnotationMarks.size();
1433  }
1434 
1436  {
1437  auto const ret = lcl_FindMarkByName( rName, m_vAnnotationMarks.begin(), m_vAnnotationMarks.end() );
1438  return IDocumentMarkAccess::iterator(ret);
1439  }
1440 
1442  {
1443  auto const pAnnotationMark = find_if(
1444  m_vAnnotationMarks.begin(),
1445  m_vAnnotationMarks.end(),
1446  [&rPos] (const ::sw::mark::MarkBase *const pMark) { return pMark->IsCoveringPosition(rPos); } );
1447  if (pAnnotationMark == m_vAnnotationMarks.end())
1448  return nullptr;
1449  return *pAnnotationMark;
1450  }
1451 
1452  // finds the first that is starting after
1454  {
1455  return std::upper_bound(
1456  m_vAnnotationMarks.begin(),
1457  m_vAnnotationMarks.end(),
1458  rPos,
1459  CompareIMarkStartsAfter());
1460  }
1461 
1462  OUString MarkManager::getUniqueMarkName(const OUString& rName) const
1463  {
1464  OSL_ENSURE(rName.getLength(),
1465  "<MarkManager::getUniqueMarkName(..)> - a name should be proposed");
1466  if( m_pDoc->IsInMailMerge())
1467  {
1468  OUString newName = rName + "MailMergeMark"
1469  + OStringToOUString( DateTimeToOString( DateTime( DateTime::SYSTEM )), RTL_TEXTENCODING_ASCII_US )
1470  + OUString::number( m_vAllMarks.size() + 1 );
1471  return newName;
1472  }
1473 
1474  if (lcl_FindMarkByName(rName, m_vAllMarks.begin(), m_vAllMarks.end()) == m_vAllMarks.end())
1475  {
1476  return rName;
1477  }
1478  OUStringBuffer sBuf;
1479  OUString sTmp;
1480 
1481  // try the name "<rName>XXX" (where XXX is a number starting from 1) unless there is
1482  // a unused name. Due to performance-reasons (especially in mailmerge-scenarios) there
1483  // is a map m_aMarkBasenameMapUniqueOffset which holds the next possible offset (XXX) for
1484  // rName (so there is no need to test for nCnt-values smaller than the offset).
1485  sal_Int32 nCnt = 1;
1486  MarkBasenameMapUniqueOffset_t::const_iterator aIter = m_aMarkBasenameMapUniqueOffset.find(rName);
1487  if(aIter != m_aMarkBasenameMapUniqueOffset.end()) nCnt = aIter->second;
1488  while(nCnt < SAL_MAX_INT32)
1489  {
1490  sTmp = sBuf.append(rName).append(nCnt).makeStringAndClear();
1491  nCnt++;
1492  if (lcl_FindMarkByName(sTmp, m_vAllMarks.begin(), m_vAllMarks.end()) == m_vAllMarks.end())
1493  {
1494  break;
1495  }
1496  }
1497  m_aMarkBasenameMapUniqueOffset[rName] = nCnt;
1498 
1499  return sTmp;
1500  }
1501 
1503  {
1504  const_cast< MarkManager* >(this)->sortMarks();
1505  }
1506 
1508  {
1509  sort(m_vBookmarks.begin(), m_vBookmarks.end(), &lcl_MarkOrderingByStart);
1510  sort(m_vFieldmarks.begin(), m_vFieldmarks.end(), &lcl_MarkOrderingByStart);
1511  sort(m_vAnnotationMarks.begin(), m_vAnnotationMarks.end(), &lcl_MarkOrderingByStart);
1512  }
1513 
1515  {
1516  sort(m_vAllMarks.begin(), m_vAllMarks.end(), &lcl_MarkOrderingByStart);
1517  sortSubsetMarks();
1518  }
1519 
1521 {
1522  struct
1523  {
1524  const char* pName;
1525  const container_t* pContainer;
1526  } aContainers[] =
1527  {
1528  // UNO marks are only part of all marks.
1529  {"allmarks", &m_vAllMarks},
1530  {"bookmarks", &m_vBookmarks},
1531  {"fieldmarks", &m_vFieldmarks},
1532  {"annotationmarks", &m_vAnnotationMarks}
1533  };
1534 
1535  xmlTextWriterStartElement(pWriter, BAD_CAST("MarkManager"));
1536  for (const auto & rContainer : aContainers)
1537  {
1538  if (!rContainer.pContainer->empty())
1539  {
1540  xmlTextWriterStartElement(pWriter, BAD_CAST(rContainer.pName));
1541  for (auto it = rContainer.pContainer->begin(); it != rContainer.pContainer->end(); ++it)
1542  (*it)->dumpAsXml(pWriter);
1543  xmlTextWriterEndElement(pWriter);
1544  }
1545  }
1546  xmlTextWriterEndElement(pWriter);
1547 }
1548 
1549 }} // namespace ::sw::mark
1550 
1551 namespace
1552 {
1553  bool lcl_Greater( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
1554  {
1555  return rPos.nNode > rNdIdx || ( pIdx && rPos.nNode == rNdIdx && rPos.nContent > pIdx->GetIndex() );
1556  }
1557 }
1558 
1559 // IDocumentMarkAccess for SwDoc
1561  { return static_cast< IDocumentMarkAccess* >(mpMarkManager.get()); }
1562 
1564  { return static_cast< IDocumentMarkAccess* >(mpMarkManager.get()); }
1565 
1566 SaveBookmark::SaveBookmark(
1567  const IMark& rBkmk,
1568  const SwNodeIndex & rMvPos,
1569  const SwIndex* pIdx)
1570  : m_aName(rBkmk.GetName())
1571  , m_aShortName()
1572  , m_aCode()
1573  , m_eOrigBkmType(IDocumentMarkAccess::GetType(rBkmk))
1574 {
1575  const IBookmark* const pBookmark = dynamic_cast< const IBookmark* >(&rBkmk);
1576  if(pBookmark)
1577  {
1578  m_aShortName = pBookmark->GetShortName();
1579  m_aCode = pBookmark->GetKeyCode();
1580 
1581  ::sfx2::Metadatable const*const pMetadatable(
1582  dynamic_cast< ::sfx2::Metadatable const* >(pBookmark));
1583  if (pMetadatable)
1584  {
1585  m_pMetadataUndo = pMetadatable->CreateUndo();
1586  }
1587  }
1588  m_nNode1 = rBkmk.GetMarkPos().nNode.GetIndex();
1590 
1591  m_nNode1 -= rMvPos.GetIndex();
1592  if(pIdx && !m_nNode1)
1593  m_nContent1 -= pIdx->GetIndex();
1594 
1595  if(rBkmk.IsExpanded())
1596  {
1597  m_nNode2 = rBkmk.GetOtherMarkPos().nNode.GetIndex();
1599 
1600  m_nNode2 -= rMvPos.GetIndex();
1601  if(pIdx && !m_nNode2)
1602  m_nContent2 -= pIdx->GetIndex();
1603  }
1604  else
1605  {
1606  m_nNode2 = ULONG_MAX;
1607  m_nContent2 = -1;
1608  }
1609 }
1610 
1612  SwDoc* pDoc,
1613  const SwNodeIndex& rNewPos,
1614  const SwIndex* pIdx)
1615 {
1616  SwPaM aPam(rNewPos.GetNode());
1617  if(pIdx)
1618  aPam.GetPoint()->nContent = *pIdx;
1619 
1620  if(ULONG_MAX != m_nNode2)
1621  {
1622  aPam.SetMark();
1623 
1624  aPam.GetMark()->nNode += m_nNode2;
1625  if(pIdx && !m_nNode2)
1626  aPam.GetMark()->nContent += m_nContent2;
1627  else
1628  aPam.GetMark()->nContent.Assign(aPam.GetContentNode(false), m_nContent2);
1629  }
1630 
1631  aPam.GetPoint()->nNode += m_nNode1;
1632 
1633  if(pIdx && !m_nNode1)
1634  aPam.GetPoint()->nContent += m_nContent1;
1635  else
1636  aPam.GetPoint()->nContent.Assign(aPam.GetContentNode(), m_nContent1);
1637 
1638  if(!aPam.HasMark()
1639  || CheckNodesRange(aPam.GetPoint()->nNode, aPam.GetMark()->nNode, true))
1640  {
1641  ::sw::mark::IBookmark* const pBookmark = dynamic_cast<::sw::mark::IBookmark*>(
1642  pDoc->getIDocumentMarkAccess()->makeMark(aPam, m_aName,
1644  if(pBookmark)
1645  {
1646  pBookmark->SetKeyCode(m_aCode);
1647  pBookmark->SetShortName(m_aShortName);
1648  if (m_pMetadataUndo)
1649  {
1650  ::sfx2::Metadatable * const pMeta(
1651  dynamic_cast< ::sfx2::Metadatable* >(pBookmark));
1652  assert(pMeta && "metadata undo, but not metadatable?");
1653  if (pMeta)
1654  {
1656  }
1657  }
1658  }
1659  }
1660 }
1661 
1662 // DelBookmarks
1663 
1665  const SwNodeIndex& rStt,
1666  const SwNodeIndex& rEnd,
1667  std::vector<SaveBookmark> * pSaveBkmk,
1668  const SwIndex* pSttIdx,
1669  const SwIndex* pEndIdx)
1670 {
1671  // illegal range ??
1672  if(rStt.GetIndex() > rEnd.GetIndex()
1673  || (rStt == rEnd && (!pSttIdx || !pEndIdx || pSttIdx->GetIndex() >= pEndIdx->GetIndex())))
1674  return;
1675  SwDoc* const pDoc = rStt.GetNode().GetDoc();
1676 
1677  pDoc->getIDocumentMarkAccess()->deleteMarks(rStt, rEnd, pSaveBkmk, pSttIdx, pEndIdx);
1678 
1679  // Copy all Redlines which are in the move area into an array
1680  // which holds all position information as offset.
1681  // Assignment happens after moving.
1683  for(SwRangeRedline* pRedl : rTable)
1684  {
1685  // Is at position?
1686  SwPosition *const pRStt = pRedl->Start();
1687  SwPosition *const pREnd = pRedl->End();
1688 
1689  if( lcl_Greater( *pRStt, rStt, pSttIdx ) && lcl_Lower( *pRStt, rEnd, pEndIdx ))
1690  {
1691  pRStt->nNode = rEnd;
1692  if( pEndIdx )
1693  pRStt->nContent = *pEndIdx;
1694  else
1695  {
1696  bool bStt = true;
1697  SwContentNode* pCNd = pRStt->nNode.GetNode().GetContentNode();
1698  if( !pCNd && nullptr == ( pCNd = pDoc->GetNodes().GoNext( &pRStt->nNode )) )
1699  {
1700  bStt = false;
1701  pRStt->nNode = rStt;
1702  if( nullptr == ( pCNd = SwNodes::GoPrevious( &pRStt->nNode )) )
1703  {
1704  pRStt->nNode = pREnd->nNode;
1705  pCNd = pRStt->nNode.GetNode().GetContentNode();
1706  }
1707  }
1708  pRStt->nContent.Assign( pCNd, bStt ? 0 : pCNd->Len() );
1709  }
1710  }
1711  if( lcl_Greater( *pREnd, rStt, pSttIdx ) && lcl_Lower( *pREnd, rEnd, pEndIdx ))
1712  {
1713  pREnd->nNode = rStt;
1714  if( pSttIdx )
1715  pREnd->nContent = *pSttIdx;
1716  else
1717  {
1718  bool bStt = false;
1719  SwContentNode* pCNd = pREnd->nNode.GetNode().GetContentNode();
1720  if( !pCNd && nullptr == ( pCNd = SwNodes::GoPrevious( &pREnd->nNode )) )
1721  {
1722  bStt = true;
1723  pREnd->nNode = rEnd;
1724  if( nullptr == ( pCNd = pDoc->GetNodes().GoNext( &pREnd->nNode )) )
1725  {
1726  pREnd->nNode = pRStt->nNode;
1727  pCNd = pREnd->nNode.GetNode().GetContentNode();
1728  }
1729  }
1730  pREnd->nContent.Assign( pCNd, bStt ? 0 : pCNd->Len() );
1731  }
1732  }
1733  }
1734 }
1735 
1736 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual sw::mark::IMark * getAnnotationMarkFor(const SwPosition &rPos) const override
Definition: docbm.cxx:1441
virtual sal_Int32 Len() const
Definition: node.cxx:1183
virtual void ShowButton(SwEditWin *pEditWin)=0
bool IsInMailMerge() const
Definition: doc.hxx:951
virtual const_iterator_t findFirstAnnotationStartsAfter(const SwPosition &rPos) const override
Finds the first mark that is starting after.
Definition: docbm.cxx:1453
virtual sal_Int32 getAllMarksCount() const override
returns the number of marks.
Definition: docbm.cxx:1242
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:1664
sw::mark::FieldmarkWithDropDownButton * m_pLastActiveFieldmark
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:185
virtual const_iterator_t findFirstBookmarkStartsAfter(const SwPosition &rPos) const override
Finds the first mark that is starting after.
Definition: docbm.cxx:1255
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:1462
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:1611
virtual const SwPosition & GetMarkPos() const =0
virtual ::sw::mark::IFieldmark * getFieldmarkAfter(const SwPosition &rPos) const override
Definition: docbm.cxx:1414
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:1236
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1560
Dialog to specify the properties of date form field.
Definition: accfrmobj.cxx:40
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:176
virtual const_iterator_t getAnnotationMarksBegin() const override
Definition: docbm.cxx:1420
IDocumentMarkAccess::MarkType const m_eOrigBkmType
Definition: mvsave.hxx:62
SfxViewShell * GetSfxViewShell() const
Definition: viewsh.hxx:444
virtual ~LazyFieldmarkDeleter() override
Definition: docbm.cxx:1096
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &rPos) const override
Definition: docbm.cxx:1264
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:690
virtual const_iterator_t findFirstMarkStartsBefore(const SwPosition &rPos) const override
Find the first Mark that does not start before.
Definition: docbm.cxx:1227
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:1248
virtual const OUString & GetName() const override
Definition: bookmrk.hxx:58
virtual void clearAllMarks() override
Clear (deletes) all marks.
Definition: docbm.cxx:1203
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:178
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:1520
sal_uLong m_nNode1
Definition: mvsave.hxx:63
bool CheckNodesRange(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, bool bChkSection)
Definition: pam.cxx:238
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:738
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:906
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:1430
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:1425
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:1089
OUString sName
virtual void assureSortedMarkContainers() const override
Definition: docbm.cxx:1502
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:1214
SwDoc * GetDoc()
Definition: node.hxx:702
virtual std::unique_ptr< ILazyDeleter > deleteMark(const const_iterator_t &ppMark) override
Deletes a mark.
Definition: docbm.cxx:1103
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:782
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:1239
virtual const_iterator_t findAnnotationMark(const OUString &rName) const override
Definition: docbm.cxx:1435
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:751
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:1251
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:811
virtual void NotifyCursorUpdate(const SwCursorShell &rCursorShell) override
Definition: docbm.cxx:1337
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:403
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:1220
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:857
virtual void SetMarkPos(const SwPosition &rNewPos)
Definition: bookmrk.cxx:179
iterator & operator+=(difference_type)
Definition: docbm.cxx:145
virtual ::sw::mark::IFieldmark * getFieldmarkBefore(const SwPosition &rPos) const override
Definition: docbm.cxx:1417
virtual ::sw::mark::IFieldmark * getDropDownFor(const SwPosition &rPos) const override
Definition: docbm.cxx:1384
virtual const SwPosition & GetMarkEnd() const =0
virtual void deleteFieldmarkAt(const SwPosition &rPos) override
Definition: docbm.cxx:1275
virtual std::vector< ::sw::mark::IFieldmark * > getDropDownsFor(const SwPaM &rPaM) const override
Definition: docbm.cxx:1392
#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:1287
#define SAL_WARN(area, stream)
virtual void ClearFieldActivation() override
Definition: docbm.cxx:1376
vcl::KeyCode m_aCode
Definition: mvsave.hxx:61
virtual void DeregisterFromDoc(SwDoc *const pDoc)
Definition: bookmrk.cxx:270
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:185
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:1245
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:759
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:1091
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