LCOV - code coverage report
Current view: top level - sw/source/core/doc - docbm.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 923 0.0 %
Date: 2014-04-14 Functions: 0 86 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <MarkManager.hxx>
      21             : #include <bookmrk.hxx>
      22             : #include <boost/bind.hpp>
      23             : #include <cntfrm.hxx>
      24             : #include <crossrefbookmark.hxx>
      25             : #include <annotationmark.hxx>
      26             : #include <dcontact.hxx>
      27             : #include <doc.hxx>
      28             : #include <docary.hxx>
      29             : #include <xmloff/odffields.hxx>
      30             : #include <editsh.hxx>
      31             : #include <fmtanchr.hxx>
      32             : #include <frmfmt.hxx>
      33             : #include <functional>
      34             : #include <hintids.hxx>
      35             : #include <mvsave.hxx>
      36             : #include <ndtxt.hxx>
      37             : #include <node.hxx>
      38             : #include <pam.hxx>
      39             : #include <redline.hxx>
      40             : #include <rolbck.hxx>
      41             : #include <rtl/ustrbuf.hxx>
      42             : #include <rtl/ustring.hxx>
      43             : #include <sal/types.h>
      44             : #include <sortedobjs.hxx>
      45             : #include <sfx2/linkmgr.hxx>
      46             : #include <swserv.hxx>
      47             : #include <swundo.hxx>
      48             : #include <unocrsr.hxx>
      49             : #include <viscrs.hxx>
      50             : #include <edimp.hxx>
      51             : #include <stdio.h>
      52             : 
      53             : using namespace ::boost;
      54             : using namespace ::sw::mark;
      55             : 
      56             : namespace
      57             : {
      58           0 :     static bool lcl_GreaterThan( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
      59             :     {
      60             :         return pIdx != NULL
      61           0 :                ? ( rPos.nNode > rNdIdx
      62           0 :                    || ( rPos.nNode == rNdIdx
      63           0 :                         && rPos.nContent >= pIdx->GetIndex() ) )
      64           0 :                : rPos.nNode >= rNdIdx;
      65             :     }
      66             : 
      67           0 :     static bool lcl_Lower( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
      68             :     {
      69           0 :         return rPos.nNode < rNdIdx
      70           0 :                || ( pIdx != NULL
      71           0 :                     && rPos.nNode == rNdIdx
      72           0 :                     && rPos.nContent < pIdx->GetIndex() );
      73             :     }
      74             : 
      75           0 :     static bool lcl_MarkOrderingByStart(const IDocumentMarkAccess::pMark_t& rpFirst,
      76             :         const IDocumentMarkAccess::pMark_t& rpSecond)
      77             :     {
      78           0 :         return rpFirst->GetMarkStart() < rpSecond->GetMarkStart();
      79             :     }
      80             : 
      81           0 :     static bool lcl_MarkOrderingByEnd(const IDocumentMarkAccess::pMark_t& rpFirst,
      82             :         const IDocumentMarkAccess::pMark_t& rpSecond)
      83             :     {
      84           0 :         return rpFirst->GetMarkEnd() < rpSecond->GetMarkEnd();
      85             :     }
      86             : 
      87           0 :     static void lcl_InsertMarkSorted(IDocumentMarkAccess::container_t& io_vMarks,
      88             :         const IDocumentMarkAccess::pMark_t& pMark)
      89             :     {
      90             :         io_vMarks.insert(
      91             :             lower_bound(
      92             :                 io_vMarks.begin(),
      93             :                 io_vMarks.end(),
      94             :                 pMark,
      95             :                 &lcl_MarkOrderingByStart),
      96           0 :             pMark);
      97           0 :     }
      98             : 
      99             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     100           0 :     static inline ::std::auto_ptr<SwPosition> lcl_PositionFromCntntNode(
     101             :         SwCntntNode * const pCntntNode,
     102             :         const bool bAtEnd=false)
     103             :     {
     104           0 :         ::std::auto_ptr<SwPosition> pResult(new SwPosition(*pCntntNode));
     105           0 :         pResult->nContent.Assign(pCntntNode, bAtEnd ? pCntntNode->Len() : 0);
     106           0 :         return pResult;
     107             :     }
     108             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     109             : 
     110             :     // return a position at the begin of rEnd, if it is a CntntNode
     111             :     // else set it to the begin of the Node after rEnd, if there is one
     112             :     // else set it to the end of the node before rStt
     113             :     // else set it to the CntntNode of the Pos outside the Range
     114             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     115           0 :     static inline ::std::auto_ptr<SwPosition> lcl_FindExpelPosition(
     116             :         const SwNodeIndex& rStt,
     117             :         const SwNodeIndex& rEnd,
     118             :         const SwPosition& rOtherPosition)
     119             :     {
     120           0 :         SwCntntNode * pNode = rEnd.GetNode().GetCntntNode();
     121           0 :         bool bPosAtEndOfNode = false;
     122           0 :         if ( pNode == NULL)
     123             :         {
     124           0 :             SwNodeIndex aEnd = SwNodeIndex(rEnd);
     125           0 :             pNode = rEnd.GetNodes().GoNext( &aEnd );
     126           0 :             bPosAtEndOfNode = false;
     127             :         }
     128           0 :         if ( pNode == NULL )
     129             :         {
     130           0 :             SwNodeIndex aStt = SwNodeIndex(rStt);
     131           0 :             pNode = rStt.GetNodes().GoPrevious(&aStt);
     132           0 :             bPosAtEndOfNode = true;
     133             :         }
     134           0 :         if ( pNode != NULL )
     135             :         {
     136           0 :             return lcl_PositionFromCntntNode( pNode, bPosAtEndOfNode );
     137             :         }
     138             : 
     139           0 :         return ::std::auto_ptr<SwPosition>(new SwPosition(rOtherPosition));
     140             :     }
     141             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     142             : 
     143           0 :     static IMark* lcl_getMarkAfter(const IDocumentMarkAccess::container_t& rMarks, const SwPosition& rPos)
     144             :     {
     145             :         IDocumentMarkAccess::const_iterator_t pMarkAfter = upper_bound(
     146             :             rMarks.begin(),
     147             :             rMarks.end(),
     148             :             rPos,
     149           0 :             sw::mark::CompareIMarkStartsAfter());
     150           0 :         if(pMarkAfter == rMarks.end()) return NULL;
     151           0 :         return pMarkAfter->get();
     152             :     };
     153             : 
     154           0 :     static IMark* lcl_getMarkBefore(const IDocumentMarkAccess::container_t& rMarks, const SwPosition& rPos)
     155             :     {
     156             :         // candidates from which to choose the mark before
     157           0 :         IDocumentMarkAccess::container_t vCandidates;
     158             :         // no need to consider marks starting after rPos
     159             :         IDocumentMarkAccess::const_iterator_t pCandidatesEnd = upper_bound(
     160             :             rMarks.begin(),
     161             :             rMarks.end(),
     162             :             rPos,
     163           0 :             sw::mark::CompareIMarkStartsAfter());
     164           0 :         vCandidates.reserve(pCandidatesEnd - rMarks.begin());
     165             :         // only marks ending before are candidates
     166             :         remove_copy_if(
     167             :             rMarks.begin(),
     168             :             pCandidatesEnd,
     169             :             back_inserter(vCandidates),
     170           0 :             boost::bind( ::std::logical_not<bool>(), boost::bind( &IMark::EndsBefore, _1, rPos ) ) );
     171             :         // no candidate left => we are in front of the first mark or there are none
     172           0 :         if(!vCandidates.size()) return NULL;
     173             :         // return the highest (last) candidate using mark end ordering
     174           0 :         return max_element(vCandidates.begin(), vCandidates.end(), &lcl_MarkOrderingByEnd)->get();
     175             :     }
     176             : 
     177           0 :     static bool lcl_FixCorrectedMark(
     178             :         const bool bChangedPos,
     179             :         const bool bChangedOPos,
     180             :         MarkBase* io_pMark )
     181             :     {
     182           0 :         if ( IDocumentMarkAccess::GetType(*io_pMark) == IDocumentMarkAccess::ANNOTATIONMARK )
     183             :         {
     184             :             // annotation marks are allowed to span a table cell range.
     185             :             // but trigger sorting to be save
     186           0 :             return true;
     187             :         }
     188             : 
     189           0 :         if ( ( bChangedPos || bChangedOPos )
     190           0 :              && io_pMark->IsExpanded()
     191           0 :              && io_pMark->GetOtherMarkPos().nNode.GetNode().FindTableBoxStartNode() !=
     192           0 :                     io_pMark->GetMarkPos().nNode.GetNode().FindTableBoxStartNode() )
     193             :         {
     194           0 :             if ( !bChangedOPos )
     195             :             {
     196           0 :                 io_pMark->SetMarkPos( io_pMark->GetOtherMarkPos() );
     197             :             }
     198           0 :             io_pMark->ClearOtherMarkPos();
     199           0 :             DdeBookmark * const pDdeBkmk = dynamic_cast< DdeBookmark*>(io_pMark);
     200           0 :             if ( pDdeBkmk != NULL
     201           0 :                  && pDdeBkmk->IsServer() )
     202             :             {
     203           0 :                 pDdeBkmk->SetRefObject(NULL);
     204             :             }
     205           0 :             return true;
     206             :         }
     207           0 :         return false;
     208             :     }
     209             : 
     210           0 :     static IDocumentMarkAccess::iterator_t lcl_FindMark(
     211             :         IDocumentMarkAccess::container_t& rMarks,
     212             :         const IDocumentMarkAccess::pMark_t& rpMarkToFind)
     213             :     {
     214             :         IDocumentMarkAccess::iterator_t ppCurrentMark = lower_bound(
     215             :             rMarks.begin(), rMarks.end(),
     216           0 :             rpMarkToFind, &lcl_MarkOrderingByStart);
     217             :         // since there are usually not too many marks on the same start
     218             :         // position, we are not doing a bisect search for the upper bound
     219             :         // but instead start to iterate from pMarkLow directly
     220           0 :         while(ppCurrentMark != rMarks.end() && **ppCurrentMark == *rpMarkToFind)
     221             :         {
     222           0 :             if(ppCurrentMark->get() == rpMarkToFind.get())
     223             :             {
     224             :                 //OSL_TRACE("found mark named '%s'",
     225             :                 //    OUStringToOString(ppCurrentMark->get()->GetName(), RTL_TEXTENCODING_UTF8).getStr());
     226           0 :                 return ppCurrentMark;
     227             :             }
     228           0 :             ++ppCurrentMark;
     229             :         }
     230             :         // reached a mark starting on a later start pos or the end of the
     231             :         // vector => not found
     232           0 :         return rMarks.end();
     233             :     };
     234             : 
     235           0 :     static IDocumentMarkAccess::iterator_t lcl_FindMarkAtPos(
     236             :         IDocumentMarkAccess::container_t& rMarks,
     237             :         const SwPosition& rPos,
     238             :         const IDocumentMarkAccess::MarkType eType)
     239             :     {
     240           0 :         for(IDocumentMarkAccess::iterator_t ppCurrentMark = lower_bound(
     241             :                 rMarks.begin(), rMarks.end(),
     242             :                 rPos,
     243           0 :                 sw::mark::CompareIMarkStartsBefore());
     244           0 :             ppCurrentMark != rMarks.end();
     245             :             ++ppCurrentMark)
     246             :         {
     247             :             // Once we reach a mark starting after the target pos
     248             :             // we do not need to continue
     249           0 :             if(ppCurrentMark->get()->StartsAfter(rPos))
     250           0 :                 break;
     251           0 :             if(IDocumentMarkAccess::GetType(**ppCurrentMark) == eType)
     252             :             {
     253             :                 //OSL_TRACE("found mark named '%s'",
     254             :                 //    OUStringToOString(ppCurrentMark->get()->GetName(), RTL_TEXTENCODING_UTF8).getStr());
     255           0 :                 return ppCurrentMark;
     256             :             }
     257             :         }
     258             :         // reached a mark starting on a later start pos or the end of the
     259             :         // vector => not found
     260           0 :         return rMarks.end();
     261             :     };
     262             : 
     263           0 :     static IDocumentMarkAccess::const_iterator_t lcl_FindMarkByName(
     264             :         const OUString& rName,
     265             :         IDocumentMarkAccess::const_iterator_t ppMarksBegin,
     266             :         IDocumentMarkAccess::const_iterator_t ppMarksEnd)
     267             :     {
     268             :         return find_if(
     269             :             ppMarksBegin,
     270             :             ppMarksEnd,
     271           0 :             boost::bind(&OUString::equals, boost::bind(&IMark::GetName, _1), rName));
     272             :     }
     273             : 
     274             : #if 0
     275             :     static void lcl_DebugMarks(IDocumentMarkAccess::container_t vMarks)
     276             :     {
     277             :         OSL_TRACE("%d Marks", vMarks.size());
     278             :         for(IDocumentMarkAccess::iterator_t ppMark = vMarks.begin();
     279             :             ppMark != vMarks.end();
     280             :             ppMark++)
     281             :         {
     282             :             IMark* pMark = ppMark->get();
     283             :             OString sName = OUStringToOString(pMark->GetName(), RTL_TEXTENCODING_UTF8);
     284             :             const SwPosition* const pStPos = &pMark->GetMarkStart();
     285             :             const SwPosition* const pEndPos = &pMark->GetMarkEnd();
     286             :             OSL_TRACE("%s %s %d,%d %d,%d",
     287             :                 typeid(*pMark).name(),
     288             :                 sName.getStr(),
     289             :                 pStPos->nNode.GetIndex(),
     290             :                 pStPos->nContent.GetIndex(),
     291             :                 pEndPos->nNode.GetIndex(),
     292             :                 pEndPos->nContent.GetIndex());
     293             :         }
     294             :     };
     295             : #endif
     296             : }
     297             : 
     298           0 : IDocumentMarkAccess::MarkType IDocumentMarkAccess::GetType(const IMark& rBkmk)
     299             : {
     300           0 :     const std::type_info* const pMarkTypeInfo = &typeid(rBkmk);
     301             :     // not using dynamic_cast<> here for performance
     302           0 :     if(*pMarkTypeInfo == typeid(UnoMark))
     303           0 :         return UNO_BOOKMARK;
     304           0 :     else if(*pMarkTypeInfo == typeid(DdeBookmark))
     305           0 :         return DDE_BOOKMARK;
     306           0 :     else if(*pMarkTypeInfo == typeid(Bookmark))
     307           0 :         return BOOKMARK;
     308           0 :     else if(*pMarkTypeInfo == typeid(CrossRefHeadingBookmark))
     309           0 :         return CROSSREF_HEADING_BOOKMARK;
     310           0 :     else if(*pMarkTypeInfo == typeid(CrossRefNumItemBookmark))
     311           0 :         return CROSSREF_NUMITEM_BOOKMARK;
     312           0 :     else if(*pMarkTypeInfo == typeid(AnnotationMark))
     313           0 :         return ANNOTATIONMARK;
     314           0 :     else if(*pMarkTypeInfo == typeid(TextFieldmark))
     315           0 :         return TEXT_FIELDMARK;
     316           0 :     else if(*pMarkTypeInfo == typeid(CheckboxFieldmark))
     317           0 :         return CHECKBOX_FIELDMARK;
     318           0 :     else if(*pMarkTypeInfo == typeid(NavigatorReminder))
     319           0 :         return NAVIGATOR_REMINDER;
     320             :     else
     321             :     {
     322             :         OSL_FAIL("IDocumentMarkAccess::GetType(..)"
     323             :             " - unknown MarkType. This needs to be fixed!");
     324           0 :         return UNO_BOOKMARK;
     325             :     }
     326             : }
     327             : 
     328           0 : OUString IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()
     329             : {
     330           0 :     return OUString("__RefHeading__");
     331             : }
     332             : 
     333           0 : bool IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( const SwPaM& rPaM )
     334             : {
     335           0 :     return rPaM.Start()->nNode.GetNode().IsTxtNode() &&
     336           0 :            rPaM.Start()->nContent.GetIndex() == 0 &&
     337           0 :            ( !rPaM.HasMark() ||
     338           0 :              ( rPaM.GetMark()->nNode == rPaM.GetPoint()->nNode &&
     339           0 :                rPaM.End()->nContent.GetIndex() == rPaM.End()->nNode.GetNode().GetTxtNode()->Len() ) );
     340             : }
     341             : 
     342             : namespace sw { namespace mark
     343             : {
     344           0 :     MarkManager::MarkManager(SwDoc& rDoc)
     345             :         : m_vAllMarks()
     346             :         , m_vBookmarks()
     347             :         , m_vFieldmarks()
     348             :         , m_vAnnotationMarks()
     349             :         , m_vCommonMarks()
     350           0 :         , m_pDoc(&rDoc)
     351           0 :     { }
     352             : 
     353           0 :     ::sw::mark::IMark* MarkManager::makeMark(const SwPaM& rPaM,
     354             :         const OUString& rName,
     355             :         const IDocumentMarkAccess::MarkType eType)
     356             :     {
     357             : #if 0
     358             :         {
     359             :             OString sName = OUStringToOString(rName, RTL_TEXTENCODING_UTF8);
     360             :             const SwPosition* const pPos1 = rPaM.GetPoint();
     361             :             const SwPosition* pPos2 = pPos1;
     362             :             if(rPaM.HasMark())
     363             :                 pPos2 = rPaM.GetMark();
     364             :             OSL_TRACE("%s %d,%d %d,%d",
     365             :                 sName.getStr(),
     366             :                 pPos1->nNode.GetIndex(),
     367             :                 pPos1->nContent.GetIndex(),
     368             :                 pPos2->nNode.GetIndex(),
     369             :                 pPos2->nContent.GetIndex());
     370             :         }
     371             : #endif
     372             :         // see for example _SaveCntntIdx, Shells
     373             :         OSL_PRECOND(m_vAllMarks.size() < USHRT_MAX,
     374             :             "MarkManager::makeMark(..)"
     375             :             " - more than USHRT_MAX marks are not supported correctly");
     376             :         // There should only be one CrossRefBookmark per Textnode per Type
     377             :         OSL_PRECOND(
     378             :             (eType != CROSSREF_NUMITEM_BOOKMARK && eType != CROSSREF_HEADING_BOOKMARK)
     379             :             || (lcl_FindMarkAtPos(m_vBookmarks, *rPaM.GetPoint(), eType) == m_vBookmarks.end()),
     380             :             "MarkManager::makeMark(..)"
     381             :             " - creating duplicate CrossRefBookmark");
     382             : 
     383             :         // create mark
     384           0 :         pMark_t pMark;
     385           0 :         switch(eType)
     386             :         {
     387             :             case IDocumentMarkAccess::TEXT_FIELDMARK:
     388           0 :                 pMark = boost::shared_ptr<IMark>(new TextFieldmark(rPaM));
     389           0 :                 break;
     390             :             case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
     391           0 :                 pMark = boost::shared_ptr<IMark>(new CheckboxFieldmark(rPaM));
     392           0 :                 break;
     393             :             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
     394           0 :                 pMark = boost::shared_ptr<IMark>(new NavigatorReminder(rPaM));
     395           0 :                 break;
     396             :             case IDocumentMarkAccess::BOOKMARK:
     397           0 :                 pMark = boost::shared_ptr<IMark>(new Bookmark(rPaM, KeyCode(), rName, OUString()));
     398           0 :                 break;
     399             :             case IDocumentMarkAccess::DDE_BOOKMARK:
     400           0 :                 pMark = boost::shared_ptr<IMark>(new DdeBookmark(rPaM));
     401           0 :                 break;
     402             :             case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
     403           0 :                 pMark = boost::shared_ptr<IMark>(new CrossRefHeadingBookmark(rPaM, KeyCode(), rName, OUString()));
     404           0 :                 break;
     405             :             case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
     406           0 :                 pMark = boost::shared_ptr<IMark>(new CrossRefNumItemBookmark(rPaM, KeyCode(), rName, OUString()));
     407           0 :                 break;
     408             :             case IDocumentMarkAccess::UNO_BOOKMARK:
     409           0 :                 pMark = boost::shared_ptr<IMark>(new UnoMark(rPaM));
     410           0 :                 break;
     411             :             case IDocumentMarkAccess::ANNOTATIONMARK:
     412           0 :                 pMark = boost::shared_ptr<IMark>(new AnnotationMark( rPaM, rName ));
     413           0 :                 break;
     414             :         }
     415             :         OSL_ENSURE(pMark.get(),
     416             :             "MarkManager::makeMark(..)"
     417             :             " - Mark was not created.");
     418           0 :         MarkBase* pMarkBase = dynamic_cast<MarkBase*>(pMark.get());
     419             : 
     420           0 :         if(pMark->GetMarkPos() != pMark->GetMarkStart())
     421           0 :             pMarkBase->Swap();
     422             : 
     423             :         // for performance reasons, we trust UnoMarks to have a (generated) unique name
     424           0 :         if ( eType != IDocumentMarkAccess::UNO_BOOKMARK )
     425           0 :             pMarkBase->SetName( getUniqueMarkName( pMarkBase->GetName() ) );
     426             : 
     427             :         // register mark
     428           0 :         m_aMarkNamesSet.insert(pMarkBase->GetName());
     429           0 :         lcl_InsertMarkSorted(m_vAllMarks, pMark);
     430           0 :         switch(eType)
     431             :         {
     432             :             case IDocumentMarkAccess::BOOKMARK:
     433             :             case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
     434             :             case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
     435           0 :                 lcl_InsertMarkSorted(m_vCommonMarks, pMark);
     436           0 :                 lcl_InsertMarkSorted(m_vBookmarks, pMark);
     437           0 :                 break;
     438             :             case IDocumentMarkAccess::TEXT_FIELDMARK:
     439             :             case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
     440           0 :                 lcl_InsertMarkSorted(m_vCommonMarks, pMark);
     441           0 :                 lcl_InsertMarkSorted(m_vFieldmarks, pMark);
     442           0 :                 break;
     443             :             case IDocumentMarkAccess::ANNOTATIONMARK:
     444           0 :                 lcl_InsertMarkSorted( m_vAnnotationMarks, pMark );
     445           0 :                 break;
     446             :             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
     447             :             case IDocumentMarkAccess::DDE_BOOKMARK:
     448             :             case IDocumentMarkAccess::UNO_BOOKMARK:
     449           0 :                 lcl_InsertMarkSorted(m_vCommonMarks, pMark);
     450             :                 // no special array for these
     451           0 :                 break;
     452             :         }
     453           0 :         pMarkBase->InitDoc(m_pDoc);
     454             : #if 0
     455             :         OSL_TRACE("--- makeType ---");
     456             :         OSL_TRACE("Marks");
     457             :         lcl_DebugMarks(m_vAllMarks);
     458             :         OSL_TRACE("Bookmarks");
     459             :         lcl_DebugMarks(m_vBookmarks);
     460             :         OSL_TRACE("Fieldmarks");
     461             :         lcl_DebugMarks(m_vFieldmarks);
     462             : #endif
     463             : 
     464           0 :         return pMark.get();
     465             :     }
     466             : 
     467           0 :     ::sw::mark::IFieldmark* MarkManager::makeFieldBookmark(
     468             :         const SwPaM& rPaM,
     469             :         const OUString& rName,
     470             :         const OUString& rType )
     471             :     {
     472             :         sw::mark::IMark* pMark = makeMark( rPaM, rName,
     473           0 :                 IDocumentMarkAccess::TEXT_FIELDMARK );
     474           0 :         sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
     475           0 :         pFieldMark->SetFieldname( rType );
     476             : 
     477           0 :         return pFieldMark;
     478             :     }
     479             : 
     480           0 :     ::sw::mark::IFieldmark* MarkManager::makeNoTextFieldBookmark(
     481             :         const SwPaM& rPaM,
     482             :         const OUString& rName,
     483             :         const OUString& rType)
     484             :     {
     485             :         sw::mark::IMark* pMark = makeMark( rPaM, rName,
     486           0 :                 IDocumentMarkAccess::CHECKBOX_FIELDMARK );
     487           0 :         sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
     488           0 :         pFieldMark->SetFieldname( rType );
     489             : 
     490           0 :         return pFieldMark;
     491             :     }
     492             : 
     493           0 :     ::sw::mark::IMark* MarkManager::getMarkForTxtNode(
     494             :         const SwTxtNode& rTxtNode,
     495             :         const IDocumentMarkAccess::MarkType eType )
     496             :     {
     497           0 :         SwPosition aPos(rTxtNode);
     498           0 :         aPos.nContent.Assign(&(const_cast<SwTxtNode&>(rTxtNode)), 0);
     499           0 :         const iterator_t ppExistingMark = lcl_FindMarkAtPos(m_vBookmarks, aPos, eType);
     500           0 :         if(ppExistingMark != m_vBookmarks.end())
     501           0 :             return ppExistingMark->get();
     502           0 :         const SwPaM aPaM(aPos);
     503           0 :         return makeMark(aPaM, OUString(), eType);
     504             :     }
     505             : 
     506           0 :     sw::mark::IMark* MarkManager::makeAnnotationMark(
     507             :         const SwPaM& rPaM,
     508             :         const ::rtl::OUString& rName )
     509             :     {
     510           0 :         return makeMark( rPaM, rName, IDocumentMarkAccess::ANNOTATIONMARK );
     511             :     }
     512             : 
     513           0 :     void MarkManager::repositionMark(
     514             :         ::sw::mark::IMark* const io_pMark,
     515             :         const SwPaM& rPaM)
     516             :     {
     517             :         OSL_PRECOND(io_pMark->GetMarkPos().GetDoc() == m_pDoc,
     518             :             "<MarkManager::repositionMark(..)>"
     519             :             " - Mark is not in my doc.");
     520           0 :         MarkBase* const pMarkBase = dynamic_cast< MarkBase* >(io_pMark);
     521           0 :         pMarkBase->SetMarkPos(*(rPaM.GetPoint()));
     522           0 :         if(rPaM.HasMark())
     523           0 :             pMarkBase->SetOtherMarkPos(*(rPaM.GetMark()));
     524             :         else
     525           0 :             pMarkBase->ClearOtherMarkPos();
     526             : 
     527           0 :         if(pMarkBase->GetMarkPos() != pMarkBase->GetMarkStart())
     528           0 :             pMarkBase->Swap();
     529             : 
     530           0 :         sortMarks();
     531           0 :     }
     532             : 
     533           0 :     bool MarkManager::renameMark(
     534             :         ::sw::mark::IMark* io_pMark,
     535             :         const OUString& rNewName )
     536             :     {
     537             :         OSL_PRECOND(io_pMark->GetMarkPos().GetDoc() == m_pDoc,
     538             :             "<MarkManager::renameMark(..)>"
     539             :             " - Mark is not in my doc.");
     540           0 :         if ( io_pMark->GetName() == rNewName )
     541           0 :             return true;
     542           0 :         if ( findMark(rNewName) != m_vAllMarks.end() )
     543           0 :             return false;
     544           0 :         m_aMarkNamesSet.erase(dynamic_cast< ::sw::mark::MarkBase* >(io_pMark)->GetName());
     545           0 :         m_aMarkNamesSet.insert(rNewName);
     546           0 :         dynamic_cast< ::sw::mark::MarkBase* >(io_pMark)->SetName(rNewName);
     547           0 :         return true;
     548             :     }
     549             : 
     550           0 :     void MarkManager::correctMarksAbsolute(
     551             :         const SwNodeIndex& rOldNode,
     552             :         const SwPosition& rNewPos,
     553             :         const sal_Int32 nOffset)
     554             :     {
     555           0 :         const SwNode* const pOldNode = &rOldNode.GetNode();
     556           0 :         SwPosition aNewPos(rNewPos);
     557           0 :         aNewPos.nContent += nOffset;
     558           0 :         bool isSortingNeeded = false;
     559             : 
     560           0 :         for(iterator_t ppMark = m_vAllMarks.begin();
     561           0 :             ppMark != m_vAllMarks.end();
     562             :             ++ppMark)
     563             :         {
     564           0 :             ::sw::mark::MarkBase* pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
     565             :             // is on position ??
     566           0 :             bool bChangedPos = false;
     567           0 :             if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
     568             :             {
     569           0 :                 pMark->SetMarkPos(aNewPos);
     570           0 :                 bChangedPos = true;
     571             :             }
     572           0 :             bool bChangedOPos = false;
     573           0 :             if (pMark->IsExpanded() &&
     574           0 :                 &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
     575             :             {
     576           0 :                 pMark->SetMarkPos(aNewPos);
     577           0 :                 bChangedOPos= true;
     578             :             }
     579             :             // illegal selection? collapse the mark and restore sorting later
     580           0 :             isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
     581             :         }
     582             : 
     583             :         // restore sorting if needed
     584           0 :         if(isSortingNeeded)
     585           0 :             sortMarks();
     586             : #if 0
     587             :         OSL_TRACE("correctMarksAbsolute");
     588             :         lcl_DebugMarks(m_vAllMarks);
     589             : #endif
     590           0 :     }
     591             : 
     592           0 :     void MarkManager::correctMarksRelative(const SwNodeIndex& rOldNode, const SwPosition& rNewPos, const sal_Int32 nOffset)
     593             :     {
     594           0 :         const SwNode* const pOldNode = &rOldNode.GetNode();
     595           0 :         SwPosition aNewPos(rNewPos);
     596           0 :         aNewPos.nContent += nOffset;
     597           0 :         bool isSortingNeeded = false;
     598             : 
     599           0 :         for(iterator_t ppMark = m_vAllMarks.begin();
     600           0 :             ppMark != m_vAllMarks.end();
     601             :             ++ppMark)
     602             :         {
     603             :             // is on position ??
     604           0 :             bool bChangedPos = false, bChangedOPos = false;
     605           0 :             ::sw::mark::MarkBase* const pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
     606           0 :             if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
     607             :             {
     608           0 :                 SwPosition aNewPosRel(aNewPos);
     609           0 :                 aNewPosRel.nContent += pMark->GetMarkPos().nContent.GetIndex();
     610           0 :                 pMark->SetMarkPos(aNewPosRel);
     611           0 :                 bChangedPos = true;
     612             :             }
     613           0 :             if(pMark->IsExpanded() &&
     614           0 :                 &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
     615             :             {
     616           0 :                 SwPosition aNewPosRel(aNewPos);
     617           0 :                 aNewPosRel.nContent += pMark->GetOtherMarkPos().nContent.GetIndex();
     618           0 :                 pMark->SetOtherMarkPos(aNewPosRel);
     619           0 :                 bChangedOPos = true;
     620             :             }
     621             :             // illegal selection? collapse the mark and restore sorting later
     622           0 :             isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
     623             :         }
     624             : 
     625             :         // restore sorting if needed
     626           0 :         if(isSortingNeeded)
     627           0 :             sortMarks();
     628             : #if 0
     629             :         OSL_TRACE("correctMarksRelative");
     630             :         lcl_DebugMarks(m_vAllMarks);
     631             : #endif
     632           0 :     }
     633             : 
     634           0 :     void MarkManager::deleteMarks(
     635             :             const SwNodeIndex& rStt,
     636             :             const SwNodeIndex& rEnd,
     637             :             ::std::vector<SaveBookmark>* pSaveBkmk,
     638             :             const SwIndex* pSttIdx,
     639             :             const SwIndex* pEndIdx )
     640             :     {
     641           0 :         ::std::vector<const_iterator_t> vMarksToDelete;
     642           0 :         bool bIsSortingNeeded = false;
     643             : 
     644             :         // boolean indicating, if at least one mark has been moved while colleting marks for deletion
     645           0 :         bool bMarksMoved = false;
     646             : 
     647             :         // copy all bookmarks in the move area to a vector storing all position data as offset
     648             :         // reassignment is performed after the move
     649           0 :         for(iterator_t ppMark = m_vAllMarks.begin();
     650           0 :             ppMark != m_vAllMarks.end();
     651             :             ++ppMark)
     652             :         {
     653             :             // navigator marks should not be moved
     654             :             // TODO: Check if this might make them invalid
     655           0 :             if(IDocumentMarkAccess::GetType(**ppMark) == NAVIGATOR_REMINDER)
     656           0 :                 continue;
     657             : 
     658           0 :             ::sw::mark::MarkBase* pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
     659             :             // on position ??
     660           0 :             bool bIsPosInRange = lcl_GreaterThan(pMark->GetMarkPos(), rStt, pSttIdx)
     661           0 :                                  && lcl_Lower(pMark->GetMarkPos(), rEnd, pEndIdx);
     662           0 :             bool bIsOtherPosInRange = pMark->IsExpanded()
     663           0 :                                       && lcl_GreaterThan(pMark->GetOtherMarkPos(), rStt, pSttIdx)
     664           0 :                                       && lcl_Lower(pMark->GetOtherMarkPos(), rEnd, pEndIdx);
     665             :             // special case: completely in range, touching the end?
     666           0 :             if ( pEndIdx != NULL
     667           0 :                  && ( ( bIsOtherPosInRange
     668           0 :                         && pMark->GetMarkPos().nNode == rEnd
     669           0 :                         && pMark->GetMarkPos().nContent == *pEndIdx )
     670           0 :                       || ( bIsPosInRange
     671           0 :                            && pMark->IsExpanded()
     672           0 :                            && pMark->GetOtherMarkPos().nNode == rEnd
     673           0 :                            && pMark->GetOtherMarkPos().nContent == *pEndIdx ) ) )
     674             :             {
     675           0 :                 bIsPosInRange = true, bIsOtherPosInRange = true;
     676             :             }
     677             : 
     678           0 :             if ( bIsPosInRange
     679           0 :                  && ( bIsOtherPosInRange
     680           0 :                       || !pMark->IsExpanded() ) )
     681             :             {
     682             :                 // completely in range
     683             : 
     684           0 :                 bool bDeleteMark = true;
     685             :                 {
     686           0 :                     switch ( IDocumentMarkAccess::GetType( *pMark ) )
     687             :                     {
     688             :                     case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
     689             :                     case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
     690             :                         // no delete of cross-reference bookmarks, if range is inside one paragraph
     691           0 :                         bDeleteMark = rStt != rEnd;
     692           0 :                         break;
     693             :                     case IDocumentMarkAccess::UNO_BOOKMARK:
     694             :                         // no delete of UNO mark, if it is not expanded and only touches the start of the range
     695             :                         bDeleteMark = bIsOtherPosInRange
     696           0 :                                       || pMark->IsExpanded()
     697           0 :                                       || pSttIdx == NULL
     698           0 :                                       || !( pMark->GetMarkPos().nNode == rStt
     699           0 :                                             && pMark->GetMarkPos().nContent == *pSttIdx );
     700           0 :                         break;
     701             :                     default:
     702           0 :                         bDeleteMark = true;
     703           0 :                         break;
     704             :                     }
     705             :                 }
     706             : 
     707           0 :                 if ( bDeleteMark )
     708             :                 {
     709           0 :                     if ( pSaveBkmk )
     710             :                     {
     711           0 :                         pSaveBkmk->push_back( SaveBookmark( true, true, *pMark, rStt, pSttIdx ) );
     712             :                     }
     713           0 :                     vMarksToDelete.push_back(ppMark);
     714             :                 }
     715             :             }
     716           0 :             else if ( bIsPosInRange != bIsOtherPosInRange )
     717             :             {
     718             :                 // the bookmark is partitially in the range
     719             :                 // move position of that is in the range out of it
     720             : 
     721             :                 SAL_WNODEPRECATED_DECLARATIONS_PUSH
     722           0 :                 ::std::auto_ptr< SwPosition > pNewPos;
     723             :                 {
     724           0 :                     if ( pEndIdx != NULL )
     725             :                     {
     726           0 :                         pNewPos = ::std::auto_ptr< SwPosition >( new SwPosition( rEnd, *pEndIdx ) );
     727             :                     }
     728             :                     else
     729             :                     {
     730           0 :                         pNewPos =
     731           0 :                             lcl_FindExpelPosition( rStt, rEnd, bIsPosInRange ? pMark->GetOtherMarkPos() : pMark->GetMarkPos() );
     732             :                     }
     733             :                 }
     734             : 
     735           0 :                 bool bMoveMark = true;
     736             :                 {
     737           0 :                     switch ( IDocumentMarkAccess::GetType( *pMark ) )
     738             :                     {
     739             :                     case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
     740             :                     case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
     741             :                         // no move of cross-reference bookmarks, if move occurs inside a certain node
     742           0 :                         bMoveMark = pMark->GetMarkPos().nNode != pNewPos->nNode;
     743           0 :                         break;
     744             :                     case IDocumentMarkAccess::ANNOTATIONMARK:
     745             :                         // no move of annotation marks, if method is called to collect deleted marks
     746           0 :                         bMoveMark = pSaveBkmk == NULL;
     747           0 :                         break;
     748             :                     default:
     749           0 :                         bMoveMark = true;
     750           0 :                         break;
     751             :                     }
     752             :                 }
     753             :                 SAL_WNODEPRECATED_DECLARATIONS_POP
     754           0 :                 if ( bMoveMark )
     755             :                 {
     756           0 :                     if ( bIsPosInRange )
     757           0 :                         pMark->SetMarkPos(*pNewPos);
     758             :                     else
     759           0 :                         pMark->SetOtherMarkPos(*pNewPos);
     760           0 :                     bMarksMoved = true;
     761             : 
     762             :                     // illegal selection? collapse the mark and restore sorting later
     763           0 :                     bIsSortingNeeded |= lcl_FixCorrectedMark( bIsPosInRange, bIsOtherPosInRange, pMark );
     764           0 :                 }
     765             :             }
     766             :         }
     767             : 
     768             :         {
     769             :             // fdo#61016 delay the deletion of the fieldmark characters
     770             :             // to prevent that from deleting the marks on that position
     771             :             // which would invalidate the iterators in vMarksToDelete
     772           0 :             std::vector< ::boost::shared_ptr<ILazyDeleter> > vDelay;
     773           0 :             vDelay.reserve(vMarksToDelete.size());
     774             : 
     775             :             // If needed, sort mark containers containing subsets of the marks
     776             :             // in order to assure sorting.  The sorting is critical for the
     777             :             // deletion of a mark as it is searched in these container for
     778             :             // deletion.
     779           0 :             if ( vMarksToDelete.size() > 0 && bMarksMoved )
     780             :             {
     781           0 :                 sortSubsetMarks();
     782             :             }
     783             :             // we just remembered the iterators to delete, so we do not need to search
     784             :             // for the shared_ptr<> (the entry in m_vAllMarks) again
     785             :             // reverse iteration, since erasing an entry invalidates iterators
     786             :             // behind it (the iterators in vMarksToDelete are sorted)
     787           0 :             for ( ::std::vector< const_iterator_t >::reverse_iterator pppMark = vMarksToDelete.rbegin();
     788           0 :                   pppMark != vMarksToDelete.rend();
     789             :                   ++pppMark )
     790             :             {
     791           0 :                 vDelay.push_back(deleteMark(*pppMark));
     792           0 :             }
     793             :         } // scope to kill vDelay
     794             : 
     795           0 :         if ( bIsSortingNeeded )
     796             :         {
     797           0 :             sortMarks();
     798           0 :         }
     799             : 
     800             : #if 0
     801             :         OSL_TRACE("deleteMarks");
     802             :         lcl_DebugMarks(m_vAllMarks);
     803             : #endif
     804           0 :     }
     805             : 
     806             :     struct LazyFieldmarkDeleter : public IDocumentMarkAccess::ILazyDeleter
     807             :     {
     808             :         ::boost::shared_ptr<IMark> const m_pFieldmark;
     809             :         SwDoc *const m_pDoc;
     810           0 :         LazyFieldmarkDeleter(
     811             :                 ::boost::shared_ptr<IMark> const& pMark, SwDoc *const pDoc)
     812           0 :             : m_pFieldmark(pMark), m_pDoc(pDoc)
     813           0 :         { }
     814           0 :         virtual ~LazyFieldmarkDeleter()
     815           0 :         {
     816           0 :             dynamic_cast<Fieldmark *>(m_pFieldmark.get())->ReleaseDoc(m_pDoc);
     817           0 :         }
     818             :     };
     819             : 
     820             :     ::boost::shared_ptr<IDocumentMarkAccess::ILazyDeleter>
     821           0 :         MarkManager::deleteMark(const const_iterator_t ppMark)
     822             :     {
     823           0 :         ::boost::shared_ptr<ILazyDeleter> ret;
     824           0 :         if (ppMark == m_vAllMarks.end()) return ret;
     825             : 
     826           0 :         switch(IDocumentMarkAccess::GetType(**ppMark))
     827             :         {
     828             :             case IDocumentMarkAccess::BOOKMARK:
     829             :             case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
     830             :             case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
     831             :                 {
     832           0 :                     IDocumentMarkAccess::iterator_t ppBookmark = lcl_FindMark(m_vBookmarks, *ppMark);
     833           0 :                     if ( ppBookmark != m_vBookmarks.end() )
     834             :                     {
     835           0 :                         m_vBookmarks.erase(ppBookmark);
     836             :                     }
     837             :                     else
     838             :                     {
     839             :                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Bookmark not found in Bookmark container.");
     840             :                     }
     841             : 
     842           0 :                     ppBookmark = lcl_FindMark(m_vCommonMarks, *ppMark);
     843           0 :                     if ( ppBookmark != m_vCommonMarks.end() )
     844             :                     {
     845           0 :                         m_vCommonMarks.erase(ppBookmark);
     846             :                     }
     847             :                     else
     848             :                     {
     849             :                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Bookmark not found in common mark container.");
     850             :                     }
     851             :                 }
     852           0 :                 break;
     853             : 
     854             :             case IDocumentMarkAccess::TEXT_FIELDMARK:
     855             :             case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
     856             :                 {
     857           0 :                     IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark);
     858           0 :                     if ( ppFieldmark != m_vFieldmarks.end() )
     859             :                     {
     860           0 :                         m_vFieldmarks.erase(ppFieldmark);
     861           0 :                         ret.reset(new LazyFieldmarkDeleter(*ppMark, m_pDoc));
     862             :                     }
     863             :                     else
     864             :                     {
     865             :                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Fieldmark not found in Fieldmark container.");
     866             :                     }
     867             : 
     868           0 :                     ppFieldmark = lcl_FindMark(m_vCommonMarks, *ppMark);
     869           0 :                     if ( ppFieldmark != m_vCommonMarks.end() )
     870             :                     {
     871           0 :                         m_vCommonMarks.erase(ppFieldmark);
     872             :                     }
     873             :                     else
     874             :                     {
     875             :                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Fieldmark not found in common mark container.");
     876             :                     }
     877             :                 }
     878           0 :                 break;
     879             : 
     880             :             case IDocumentMarkAccess::ANNOTATIONMARK:
     881             :                 {
     882           0 :                     IDocumentMarkAccess::iterator_t ppAnnotationMark = lcl_FindMark(m_vAnnotationMarks, *ppMark);
     883           0 :                     if ( ppAnnotationMark != m_vAnnotationMarks.end() )
     884             :                     {
     885           0 :                         m_vAnnotationMarks.erase(ppAnnotationMark);
     886             :                     }
     887             :                     else
     888             :                     {
     889             :                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Annotation Mark not found in Annotation Mark container.");
     890             :                     }
     891             :                 }
     892           0 :                 break;
     893             : 
     894             :             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
     895             :             case IDocumentMarkAccess::DDE_BOOKMARK:
     896             :             case IDocumentMarkAccess::UNO_BOOKMARK:
     897             :                 {
     898           0 :                     IDocumentMarkAccess::iterator_t ppOtherMark = lcl_FindMark(m_vCommonMarks, *ppMark);
     899           0 :                     if ( ppOtherMark != m_vCommonMarks.end() )
     900             :                     {
     901           0 :                         m_vCommonMarks.erase(ppOtherMark);
     902             :                     }
     903             :                     else
     904             :                     {
     905             :                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Navigator Reminder, DDE Mark or Uno Makr not found in common mark container.");
     906             :                     }
     907             :                 }
     908           0 :                 break;
     909             :         }
     910           0 :         DdeBookmark* const pDdeBookmark = dynamic_cast<DdeBookmark*>(ppMark->get());
     911           0 :         if(pDdeBookmark)
     912           0 :             pDdeBookmark->DeregisterFromDoc(m_pDoc);
     913             :         //Effective STL Item 27, get a non-const iterator aI at the same
     914             :         //position as const iterator ppMark was
     915           0 :         iterator_t aI = m_vAllMarks.begin();
     916           0 :         std::advance(aI, std::distance<const_iterator_t>(aI, ppMark));
     917             : 
     918             :         //fdo#37974
     919             :         //a) a mark destructor may callback into this method.
     920             :         //b) vector::erase first calls the destructor of the object, then
     921             :         //removes it from the vector.
     922             :         //So if the only reference to the object is the one
     923             :         //in the vector then we may reenter this method when the mark
     924             :         //is destructed but before it is removed, i.e. findMark still
     925             :         //finds the object whose destructor is being run. Take a temp
     926             :         //extra reference on the shared_ptr, remove the entry from the
     927             :         //vector, and on xHoldPastErase release findMark won't find
     928             :         //it anymore.
     929           0 :         pMark_t xHoldPastErase = *aI;
     930           0 :         m_aMarkNamesSet.erase(ppMark->get()->GetName());
     931           0 :         m_vAllMarks.erase(aI);
     932           0 :         return ret;
     933             :     }
     934             : 
     935           0 :     void MarkManager::deleteMark(const IMark* const pMark)
     936             :     {
     937             :         OSL_PRECOND(pMark->GetMarkPos().GetDoc() == m_pDoc,
     938             :             "<MarkManager::deleteMark(..)>"
     939             :             " - Mark is not in my doc.");
     940             :         // finds the last Mark that is starting before pMark
     941             :         // (pMarkLow < pMark)
     942             :         iterator_t pMarkLow =
     943             :             lower_bound(
     944             :                 m_vAllMarks.begin(),
     945             :                 m_vAllMarks.end(),
     946           0 :                 pMark->GetMarkStart(),
     947           0 :                 sw::mark::CompareIMarkStartsBefore());
     948           0 :         iterator_t pMarkHigh = m_vAllMarks.end();
     949             :         iterator_t pMarkFound =
     950             :             find_if(
     951             :                 pMarkLow,
     952             :                 pMarkHigh,
     953           0 :                 boost::bind( ::std::equal_to<const IMark*>(), boost::bind(&boost::shared_ptr<IMark>::get, _1), pMark ) );
     954           0 :         if(pMarkFound != pMarkHigh)
     955           0 :             deleteMark(pMarkFound);
     956           0 :     }
     957             : 
     958           0 :     void MarkManager::clearAllMarks()
     959             :     {
     960           0 :         m_vFieldmarks.clear();
     961           0 :         m_vBookmarks.clear();
     962           0 :         m_aMarkNamesSet.clear();
     963             : 
     964           0 :         m_vCommonMarks.clear();
     965             : 
     966           0 :         m_vAnnotationMarks.clear();
     967             : 
     968             : #if OSL_DEBUG_LEVEL > 0
     969             :         for(iterator_t pBkmk = m_vAllMarks.begin();
     970             :             pBkmk != m_vAllMarks.end();
     971             :             ++pBkmk)
     972             :             OSL_ENSURE( pBkmk->unique(),
     973             :                         "<MarkManager::clearAllMarks(..)> - a Bookmark is still in use.");
     974             : #endif
     975           0 :         m_vAllMarks.clear();
     976           0 :     }
     977             : 
     978           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::findMark(const OUString& rName) const
     979             :     {
     980           0 :         return lcl_FindMarkByName(rName, m_vAllMarks.begin(), m_vAllMarks.end());
     981             :     }
     982             : 
     983           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::findBookmark(const OUString& rName) const
     984             :     {
     985           0 :         return lcl_FindMarkByName(rName, m_vBookmarks.begin(), m_vBookmarks.end());
     986             :     }
     987             : 
     988           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::getAllMarksBegin() const
     989           0 :         { return m_vAllMarks.begin(); }
     990             : 
     991           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::getAllMarksEnd() const
     992           0 :         { return m_vAllMarks.end(); }
     993             : 
     994           0 :     sal_Int32 MarkManager::getAllMarksCount() const
     995           0 :         { return m_vAllMarks.size(); }
     996             : 
     997           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::getBookmarksBegin() const
     998           0 :         { return m_vBookmarks.begin(); }
     999             : 
    1000           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::getBookmarksEnd() const
    1001           0 :         { return m_vBookmarks.end(); }
    1002             : 
    1003           0 :     sal_Int32 MarkManager::getBookmarksCount() const
    1004           0 :         { return m_vBookmarks.size(); }
    1005             : 
    1006           0 :     IFieldmark* MarkManager::getFieldmarkFor(const SwPosition& rPos) const
    1007             :     {
    1008             :         const_iterator_t pFieldmark = find_if(
    1009             :             m_vFieldmarks.begin(),
    1010             :             m_vFieldmarks.end( ),
    1011           0 :             boost::bind(&IMark::IsCoveringPosition, _1, rPos));
    1012           0 :         if(pFieldmark == m_vFieldmarks.end()) return NULL;
    1013           0 :         return dynamic_cast<IFieldmark*>(pFieldmark->get());
    1014             :     }
    1015             : 
    1016           0 :     IFieldmark* MarkManager::getDropDownFor(const SwPosition& rPos) const
    1017             :     {
    1018           0 :         IFieldmark *pMark = getFieldmarkFor(rPos);
    1019           0 :         if (!pMark || pMark->GetFieldname() != ODF_FORMDROPDOWN)
    1020           0 :             return NULL;
    1021           0 :         return pMark;
    1022             :     }
    1023             : 
    1024           0 :     std::vector<IFieldmark*> MarkManager::getDropDownsFor(const SwPaM &rPaM) const
    1025             :     {
    1026           0 :         std::vector<IFieldmark*> aRet;
    1027             : 
    1028           0 :         for (IDocumentMarkAccess::const_iterator_t aI = m_vFieldmarks.begin(),
    1029           0 :             aEnd = m_vFieldmarks.end(); aI != aEnd; ++aI)
    1030             :         {
    1031           0 :             boost::shared_ptr<IMark> xI = *aI;
    1032           0 :             const SwPosition &rStart = xI->GetMarkPos();
    1033           0 :             if (!rPaM.ContainsPosition(rStart))
    1034           0 :                 continue;
    1035             : 
    1036           0 :             IFieldmark *pMark = dynamic_cast<IFieldmark*>(xI.get());
    1037           0 :             if (!pMark || pMark->GetFieldname() != ODF_FORMDROPDOWN)
    1038           0 :                 continue;
    1039             : 
    1040           0 :             aRet.push_back(pMark);
    1041           0 :         }
    1042             : 
    1043           0 :         return aRet;
    1044             :     }
    1045             : 
    1046           0 :     IFieldmark* MarkManager::getFieldmarkAfter(const SwPosition& rPos) const
    1047           0 :         { return dynamic_cast<IFieldmark*>(lcl_getMarkAfter(m_vFieldmarks, rPos)); }
    1048             : 
    1049           0 :     IFieldmark* MarkManager::getFieldmarkBefore(const SwPosition& rPos) const
    1050           0 :         { return dynamic_cast<IFieldmark*>(lcl_getMarkBefore(m_vFieldmarks, rPos)); }
    1051             : 
    1052           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::getCommonMarksBegin() const
    1053             :     {
    1054           0 :         return m_vCommonMarks.begin();
    1055             :     }
    1056             : 
    1057           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::getCommonMarksEnd() const
    1058             :     {
    1059           0 :         return m_vCommonMarks.end();
    1060             :     }
    1061             : 
    1062           0 :     sal_Int32 MarkManager::getCommonMarksCount() const
    1063             :     {
    1064           0 :         return m_vCommonMarks.size();
    1065             :     }
    1066             : 
    1067           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::getAnnotationMarksBegin() const
    1068             :     {
    1069           0 :         return m_vAnnotationMarks.begin();
    1070             :     }
    1071             : 
    1072           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::getAnnotationMarksEnd() const
    1073             :     {
    1074           0 :         return m_vAnnotationMarks.end();
    1075             :     }
    1076             : 
    1077           0 :     sal_Int32 MarkManager::getAnnotationMarksCount() const
    1078             :     {
    1079           0 :         return m_vAnnotationMarks.size();
    1080             :     }
    1081             : 
    1082           0 :     IDocumentMarkAccess::const_iterator_t MarkManager::findAnnotationMark( const ::rtl::OUString& rName ) const
    1083             :     {
    1084           0 :         return lcl_FindMarkByName( rName, m_vAnnotationMarks.begin(), m_vAnnotationMarks.end() );
    1085             :     }
    1086             : 
    1087           0 :     OUString MarkManager::getUniqueMarkName(const OUString& rName) const
    1088             :     {
    1089             :         OSL_ENSURE(rName.getLength(),
    1090             :             "<MarkManager::getUniqueMarkName(..)> - a name should be proposed");
    1091           0 :         if ( findMark(rName) == getAllMarksEnd() )
    1092             :         {
    1093           0 :             return rName;
    1094             :         }
    1095           0 :         OUStringBuffer sBuf;
    1096           0 :         OUString sTmp;
    1097             : 
    1098             :         // try the name "<rName>XXX" (where XXX is a number starting from 1) unless there is
    1099             :         // a unused name. Due to performance-reasons (especially in mailmerge-Szenarios) there
    1100             :         // is a map m_aMarkBasenameMapUniqueOffset which holds the next possible offset (XXX) for
    1101             :         // rName (so there is no need to test for nCnt-values smaller than the offset).
    1102           0 :         sal_Int32 nCnt = 1;
    1103           0 :         MarkBasenameMapUniqueOffset_t::const_iterator aIter = m_aMarkBasenameMapUniqueOffset.find(rName);
    1104           0 :         if(aIter != m_aMarkBasenameMapUniqueOffset.end()) nCnt = aIter->second;
    1105           0 :         while(nCnt < SAL_MAX_INT32)
    1106             :         {
    1107           0 :             sTmp = sBuf.append(rName).append(nCnt).makeStringAndClear();
    1108           0 :             nCnt++;
    1109           0 :             if ( findMark(sTmp) == getAllMarksEnd() )
    1110             :             {
    1111           0 :                 break;
    1112             :             }
    1113             :         }
    1114           0 :         m_aMarkBasenameMapUniqueOffset[rName] = nCnt;
    1115             : 
    1116           0 :         return sTmp;
    1117             :     }
    1118             : 
    1119           0 :     void MarkManager::assureSortedMarkContainers() const
    1120             :     {
    1121           0 :         const_cast< MarkManager* >(this)->sortMarks();
    1122           0 :     }
    1123             : 
    1124           0 :     void MarkManager::sortSubsetMarks()
    1125             :     {
    1126           0 :         sort(m_vCommonMarks.begin(), m_vCommonMarks.end(), &lcl_MarkOrderingByStart);
    1127           0 :         sort(m_vBookmarks.begin(), m_vBookmarks.end(), &lcl_MarkOrderingByStart);
    1128           0 :         sort(m_vFieldmarks.begin(), m_vFieldmarks.end(), &lcl_MarkOrderingByStart);
    1129           0 :         sort(m_vAnnotationMarks.begin(), m_vAnnotationMarks.end(), &lcl_MarkOrderingByStart);
    1130           0 :     }
    1131             : 
    1132           0 :     void MarkManager::sortMarks()
    1133             :     {
    1134           0 :         sort(m_vAllMarks.begin(), m_vAllMarks.end(), &lcl_MarkOrderingByStart);
    1135           0 :         sortSubsetMarks();
    1136           0 :     }
    1137             : 
    1138           0 :     bool MarkManager::hasMark(const OUString& rName) const
    1139             :     {
    1140           0 :         return (m_aMarkNamesSet.find(rName) != m_aMarkNamesSet.end());
    1141             :     }
    1142             : 
    1143             : }} // namespace ::sw::mark
    1144             : 
    1145             : #define PCURSH ((SwCrsrShell*)_pStartShell)
    1146             : #define FOREACHSHELL_START( pEShell ) \
    1147             :     {\
    1148             :         SwViewShell *_pStartShell = pEShell; \
    1149             :         do { \
    1150             :             if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) \
    1151             :             {
    1152             : 
    1153             : #define FOREACHSHELL_END( pEShell ) \
    1154             :             } \
    1155             :         } while((_pStartShell=(SwViewShell*)_pStartShell->GetNext())!= pEShell ); \
    1156             :     }
    1157             : 
    1158             : namespace
    1159             : {
    1160             :     // Array structure: 2 longs,
    1161             :     //  1st long contains the type and position in the DocArray,
    1162             :     //  2nd long contains the ContentPosition
    1163             : 
    1164             :     //  CntntType --
    1165             :     //          0x8000 = Bookmark Pos1
    1166             :     //          0x8001 = Bookmark Pos2
    1167             :     //          0x2000 = Paragraph anchored frame
    1168             :     //          0x2001 = frame anchored at character, which should be moved
    1169             :     //          0x1000 = Redline Mark
    1170             :     //          0x1001 = Redline Point
    1171             :     //          0x0800 = Crsr from the CrsrShell Mark
    1172             :     //          0x0801 = Crsr from the CrsrShell Point
    1173             :     //          0x0400 = UnoCrsr Mark
    1174             :     //          0x0401 = UnoCrsr Point
    1175             : 
    1176             :     class _SwSaveTypeCountContent
    1177             :     {
    1178             :         union {
    1179             :             struct { sal_uInt16 nType, nCount; } TC;
    1180             :             sal_uLong nTypeCount;
    1181             :             } TYPECOUNT;
    1182             :         sal_Int32 nContent;
    1183             : 
    1184             :     public:
    1185           0 :         _SwSaveTypeCountContent() { TYPECOUNT.nTypeCount = 0; nContent = 0; }
    1186           0 :         _SwSaveTypeCountContent( const std::vector<sal_uLong> &rArr, sal_uInt16& rPos )
    1187             :             {
    1188           0 :                 TYPECOUNT.nTypeCount = rArr[ rPos++ ];
    1189           0 :                 nContent = static_cast<sal_Int32>(rArr[ rPos++ ]);
    1190           0 :             }
    1191           0 :         void Add( std::vector<sal_uLong> &rArr )
    1192             :         {
    1193           0 :             rArr.push_back( TYPECOUNT.nTypeCount );
    1194           0 :             rArr.push_back( nContent );
    1195           0 :         }
    1196             : 
    1197           0 :         void SetType( sal_uInt16 n )        { TYPECOUNT.TC.nType = n; }
    1198           0 :         sal_uInt16 GetType() const          { return TYPECOUNT.TC.nType; }
    1199           0 :         void IncType()                  { ++TYPECOUNT.TC.nType; }
    1200           0 :         void DecType()                  { --TYPECOUNT.TC.nType; }
    1201             : 
    1202           0 :         void SetCount( sal_uInt16 n )       { TYPECOUNT.TC.nCount = n; }
    1203           0 :         sal_uInt16 GetCount() const         { return TYPECOUNT.TC.nCount; }
    1204           0 :         sal_uInt16 IncCount()               { return ++TYPECOUNT.TC.nCount; }
    1205           0 :         sal_uInt16 DecCount()               { return --TYPECOUNT.TC.nCount; }
    1206             : 
    1207           0 :         void SetTypeAndCount( sal_uInt16 nT, sal_uInt16 nC )
    1208           0 :             { TYPECOUNT.TC.nCount = nC; TYPECOUNT.TC.nType = nT; }
    1209             : 
    1210           0 :         void SetContent( sal_Int32 n )     { nContent = n; }
    1211           0 :         sal_Int32 GetContent() const       { return nContent; }
    1212             :     };
    1213             : 
    1214             :     // #i59534: If a paragraph will be splitted we have to restore some redline positions
    1215             :     // This help function checks a position compared with a node and an content index
    1216             : 
    1217             :     static const int BEFORE_NODE = 0;          // Position before the given node index
    1218             :     static const int BEFORE_SAME_NODE = 1;     // Same node index but content index before given content index
    1219             :     static const int SAME_POSITION = 2;        // Same node index and samecontent index
    1220             :     static const int BEHIND_SAME_NODE = 3;     // Same node index but content index behind given content index
    1221             :     static const int BEHIND_NODE = 4;          // Position behind the given node index
    1222             : 
    1223           0 :     static int lcl_RelativePosition( const SwPosition& rPos, sal_uLong nNode, sal_Int32 nCntnt )
    1224             :     {
    1225           0 :         sal_uLong nIndex = rPos.nNode.GetIndex();
    1226           0 :         int nReturn = BEFORE_NODE;
    1227           0 :         if( nIndex == nNode )
    1228             :         {
    1229           0 :             const sal_Int32 nCntIdx = rPos.nContent.GetIndex();
    1230           0 :             if( nCntIdx < nCntnt )
    1231           0 :                 nReturn = BEFORE_SAME_NODE;
    1232           0 :             else if( nCntIdx == nCntnt )
    1233           0 :                 nReturn = SAME_POSITION;
    1234             :             else
    1235           0 :                 nReturn = BEHIND_SAME_NODE;
    1236             :         }
    1237           0 :         else if( nIndex > nNode )
    1238           0 :             nReturn = BEHIND_NODE;
    1239           0 :         return nReturn;
    1240             :     }
    1241             : 
    1242           0 :     static inline bool lcl_Greater( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
    1243             :     {
    1244           0 :         return rPos.nNode > rNdIdx || ( pIdx && rPos.nNode == rNdIdx && rPos.nContent > pIdx->GetIndex() );
    1245             :     }
    1246             : 
    1247           0 :     static void lcl_ChkPaM( std::vector<sal_uLong> &rSaveArr, sal_uLong nNode, sal_Int32 nCntnt,
    1248             :                     const SwPaM& rPam, _SwSaveTypeCountContent& rSave,
    1249             :                     bool bChkSelDirection )
    1250             :     {
    1251             :         // Respect direction of selection
    1252             :         bool bBound1IsStart = !bChkSelDirection ? true :
    1253           0 :                             ( *rPam.GetPoint() < *rPam.GetMark()
    1254           0 :                                 ? rPam.GetPoint() == &rPam.GetBound()
    1255           0 :                                 : rPam.GetMark() == &rPam.GetBound());
    1256             : 
    1257           0 :         const SwPosition* pPos = &rPam.GetBound( true );
    1258           0 :         if( pPos->nNode.GetIndex() == nNode &&
    1259           0 :             ( bBound1IsStart ? pPos->nContent.GetIndex() < nCntnt
    1260           0 :                                 : pPos->nContent.GetIndex() <= nCntnt ))
    1261             :         {
    1262           0 :             rSave.SetContent( pPos->nContent.GetIndex() );
    1263           0 :             rSave.Add( rSaveArr );
    1264             :         }
    1265             : 
    1266           0 :         pPos = &rPam.GetBound( false );
    1267           0 :         if( pPos->nNode.GetIndex() == nNode &&
    1268           0 :             ( (bBound1IsStart && bChkSelDirection)
    1269           0 :                         ? pPos->nContent.GetIndex() <= nCntnt
    1270           0 :                         : pPos->nContent.GetIndex() < nCntnt ))
    1271             :         {
    1272           0 :             rSave.SetContent( pPos->nContent.GetIndex() );
    1273           0 :             rSave.IncType();
    1274           0 :             rSave.Add( rSaveArr );
    1275           0 :             rSave.DecType();
    1276             :         }
    1277           0 :     }
    1278             : }
    1279             : 
    1280             : // IDocumentMarkAccess for SwDoc
    1281           0 : IDocumentMarkAccess* SwDoc::getIDocumentMarkAccess()
    1282           0 :     { return static_cast< IDocumentMarkAccess* >(mpMarkManager.get()); }
    1283             : 
    1284           0 : const IDocumentMarkAccess* SwDoc::getIDocumentMarkAccess() const
    1285           0 :     { return static_cast< IDocumentMarkAccess* >(mpMarkManager.get()); }
    1286             : 
    1287             : // SaveBookmark methods
    1288             : 
    1289           0 : SaveBookmark::SaveBookmark(
    1290             :     bool bSavePos,
    1291             :     bool bSaveOtherPos,
    1292             :     const IMark& rBkmk,
    1293             :     const SwNodeIndex & rMvPos,
    1294             :     const SwIndex* pIdx)
    1295           0 :     : m_aName(rBkmk.GetName())
    1296             :     , m_aShortName()
    1297             :     , m_aCode()
    1298             :     , m_bSavePos(bSavePos)
    1299             :     , m_bSaveOtherPos(bSaveOtherPos)
    1300           0 :     , m_eOrigBkmType(IDocumentMarkAccess::GetType(rBkmk))
    1301             : {
    1302           0 :     const IBookmark* const pBookmark = dynamic_cast< const IBookmark* >(&rBkmk);
    1303           0 :     if(pBookmark)
    1304             :     {
    1305           0 :         m_aShortName = pBookmark->GetShortName();
    1306           0 :         m_aCode = pBookmark->GetKeyCode();
    1307             : 
    1308             :         ::sfx2::Metadatable const*const pMetadatable(
    1309           0 :                 dynamic_cast< ::sfx2::Metadatable const* >(pBookmark));
    1310           0 :         if (pMetadatable)
    1311             :         {
    1312           0 :             m_pMetadataUndo = pMetadatable->CreateUndo();
    1313             :         }
    1314             :     }
    1315           0 :     m_nNode1 = rBkmk.GetMarkPos().nNode.GetIndex();
    1316           0 :     m_nCntnt1 = rBkmk.GetMarkPos().nContent.GetIndex();
    1317             : 
    1318           0 :     if(m_bSavePos)
    1319             :     {
    1320           0 :         m_nNode1 -= rMvPos.GetIndex();
    1321           0 :         if(pIdx && !m_nNode1)
    1322           0 :             m_nCntnt1 -= pIdx->GetIndex();
    1323             :     }
    1324             : 
    1325           0 :     if(rBkmk.IsExpanded())
    1326             :     {
    1327           0 :         m_nNode2 = rBkmk.GetOtherMarkPos().nNode.GetIndex();
    1328           0 :         m_nCntnt2 = rBkmk.GetOtherMarkPos().nContent.GetIndex();
    1329             : 
    1330           0 :         if(m_bSaveOtherPos)
    1331             :         {
    1332           0 :             m_nNode2 -= rMvPos.GetIndex();
    1333           0 :             if(pIdx && !m_nNode2)
    1334           0 :                 m_nCntnt2 -= pIdx->GetIndex();
    1335             :         }
    1336             :     }
    1337             :     else
    1338             :     {
    1339           0 :         m_nNode2 = ULONG_MAX;
    1340           0 :         m_nCntnt2 = -1;
    1341             :     }
    1342           0 : }
    1343             : 
    1344           0 : void SaveBookmark::SetInDoc(
    1345             :     SwDoc* pDoc,
    1346             :     const SwNodeIndex& rNewPos,
    1347             :     const SwIndex* pIdx)
    1348             : {
    1349           0 :     SwPaM aPam(rNewPos.GetNode());
    1350           0 :     if(pIdx)
    1351           0 :         aPam.GetPoint()->nContent = *pIdx;
    1352             : 
    1353           0 :     if(ULONG_MAX != m_nNode2)
    1354             :     {
    1355           0 :         aPam.SetMark();
    1356             : 
    1357           0 :         if(m_bSaveOtherPos)
    1358             :         {
    1359           0 :             aPam.GetMark()->nNode += m_nNode2;
    1360           0 :             if(pIdx && !m_nNode2)
    1361           0 :                 aPam.GetMark()->nContent += m_nCntnt2;
    1362             :             else
    1363           0 :                 aPam.GetMark()->nContent.Assign(aPam.GetCntntNode(false), m_nCntnt2);
    1364             :         }
    1365             :         else
    1366             :         {
    1367           0 :             aPam.GetMark()->nNode = m_nNode2;
    1368           0 :             aPam.GetMark()->nContent.Assign(aPam.GetCntntNode(false), m_nCntnt2);
    1369             :         }
    1370             :     }
    1371             : 
    1372           0 :     if(m_bSavePos)
    1373             :     {
    1374           0 :         aPam.GetPoint()->nNode += m_nNode1;
    1375             : 
    1376           0 :         if(pIdx && !m_nNode1)
    1377           0 :             aPam.GetPoint()->nContent += m_nCntnt1;
    1378             :         else
    1379           0 :             aPam.GetPoint()->nContent.Assign(aPam.GetCntntNode(), m_nCntnt1);
    1380             :     }
    1381             :     else
    1382             :     {
    1383           0 :         aPam.GetPoint()->nNode = m_nNode1;
    1384           0 :         aPam.GetPoint()->nContent.Assign(aPam.GetCntntNode(), m_nCntnt1);
    1385             :     }
    1386             : 
    1387           0 :     if(!aPam.HasMark()
    1388           0 :         || CheckNodesRange(aPam.GetPoint()->nNode, aPam.GetMark()->nNode, true))
    1389             :     {
    1390           0 :         ::sw::mark::IBookmark* const pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pDoc->getIDocumentMarkAccess()->makeMark(aPam, m_aName, m_eOrigBkmType));
    1391           0 :         if(pBookmark)
    1392             :         {
    1393           0 :             pBookmark->SetKeyCode(m_aCode);
    1394           0 :             pBookmark->SetShortName(m_aShortName);
    1395           0 :             if (m_pMetadataUndo)
    1396             :             {
    1397             :                 ::sfx2::Metadatable * const pMeta(
    1398           0 :                     dynamic_cast< ::sfx2::Metadatable* >(pBookmark));
    1399             :                 OSL_ENSURE(pMeta, "metadata undo, but not metadatable?");
    1400           0 :                 if (pMeta)
    1401             :                 {
    1402           0 :                     pMeta->RestoreMetadata(m_pMetadataUndo);
    1403             :                 }
    1404             :             }
    1405             :         }
    1406           0 :     }
    1407           0 : }
    1408             : 
    1409             : // _DelBookmarks, _{Save,Restore}CntntIdx
    1410             : 
    1411           0 : void _DelBookmarks(
    1412             :     const SwNodeIndex& rStt,
    1413             :     const SwNodeIndex& rEnd,
    1414             :     ::std::vector<SaveBookmark> * pSaveBkmk,
    1415             :     const SwIndex* pSttIdx,
    1416             :     const SwIndex* pEndIdx)
    1417             : {
    1418             :     // illegal range ??
    1419           0 :     if(rStt.GetIndex() > rEnd.GetIndex()
    1420           0 :         || (rStt == rEnd && (!pSttIdx || pSttIdx->GetIndex() >= pEndIdx->GetIndex())))
    1421           0 :         return;
    1422           0 :     SwDoc* const pDoc = rStt.GetNode().GetDoc();
    1423             : 
    1424           0 :     pDoc->getIDocumentMarkAccess()->deleteMarks(rStt, rEnd, pSaveBkmk, pSttIdx, pEndIdx);
    1425             : 
    1426             :     // Copy all Redlines which are in the move area into an array
    1427             :     // which holds all position information as offset.
    1428             :     // Assignement happens after moving.
    1429           0 :     SwRedlineTbl& rTbl = (SwRedlineTbl&)pDoc->GetRedlineTbl();
    1430           0 :     for(sal_uInt16 nCnt = 0; nCnt < rTbl.size(); ++nCnt )
    1431             :     {
    1432             :         // Is at position?
    1433           0 :         SwRangeRedline* pRedl = rTbl[ nCnt ];
    1434             : 
    1435           0 :         SwPosition *pRStt = &pRedl->GetBound(true),
    1436           0 :                    *pREnd = &pRedl->GetBound(false);
    1437           0 :         if( *pRStt > *pREnd )
    1438             :         {
    1439           0 :             SwPosition *pTmp = pRStt; pRStt = pREnd, pREnd = pTmp;
    1440             :         }
    1441             : 
    1442           0 :         if( lcl_Greater( *pRStt, rStt, pSttIdx ) && lcl_Lower( *pRStt, rEnd, pEndIdx ))
    1443             :         {
    1444           0 :             pRStt->nNode = rEnd;
    1445           0 :             if( pEndIdx )
    1446           0 :                 pRStt->nContent = *pEndIdx;
    1447             :             else
    1448             :             {
    1449           0 :                 bool bStt = true;
    1450           0 :                 SwCntntNode* pCNd = pRStt->nNode.GetNode().GetCntntNode();
    1451           0 :                 if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoNext( &pRStt->nNode )) )
    1452             :                 {
    1453           0 :                     bStt = false;
    1454           0 :                     pRStt->nNode = rStt;
    1455           0 :                     if( 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &pRStt->nNode )) )
    1456             :                     {
    1457           0 :                         pRStt->nNode = pREnd->nNode;
    1458           0 :                         pCNd = pRStt->nNode.GetNode().GetCntntNode();
    1459             :                     }
    1460             :                 }
    1461           0 :                 pRStt->nContent.Assign( pCNd, bStt ? 0 : pCNd->Len() );
    1462             :             }
    1463             :         }
    1464           0 :         if( lcl_Greater( *pREnd, rStt, pSttIdx ) && lcl_Lower( *pREnd, rEnd, pEndIdx ))
    1465             :         {
    1466           0 :             pREnd->nNode = rStt;
    1467           0 :             if( pSttIdx )
    1468           0 :                 pREnd->nContent = *pSttIdx;
    1469             :             else
    1470             :             {
    1471           0 :                 bool bStt = false;
    1472           0 :                 SwCntntNode* pCNd = pREnd->nNode.GetNode().GetCntntNode();
    1473           0 :                 if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &pREnd->nNode )) )
    1474             :                 {
    1475           0 :                     bStt = true;
    1476           0 :                     pREnd->nNode = rEnd;
    1477           0 :                     if( 0 == ( pCNd = pDoc->GetNodes().GoNext( &pREnd->nNode )) )
    1478             :                     {
    1479           0 :                         pREnd->nNode = pRStt->nNode;
    1480           0 :                         pCNd = pREnd->nNode.GetNode().GetCntntNode();
    1481             :                     }
    1482             :                 }
    1483           0 :                 pREnd->nContent.Assign( pCNd, bStt ? 0 : pCNd->Len() );
    1484             :             }
    1485             :         }
    1486             :     }
    1487             : }
    1488             : 
    1489           0 : void _SaveCntntIdx(SwDoc* pDoc,
    1490             :     sal_uLong nNode,
    1491             :     sal_Int32 nCntnt,
    1492             :     std::vector<sal_uLong> &rSaveArr,
    1493             :     sal_uInt8 nSaveFly)
    1494             : {
    1495             :     // 1. Bookmarks
    1496           0 :     _SwSaveTypeCountContent aSave;
    1497           0 :     aSave.SetTypeAndCount( 0x8000, 0 );
    1498             : 
    1499           0 :     IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    1500           0 :     const sal_Int32 nMarksCount = pMarkAccess->getAllMarksCount();
    1501           0 :     for ( ; aSave.GetCount() < nMarksCount; aSave.IncCount() )
    1502             :     {
    1503           0 :         bool bMarkPosEqual = false;
    1504           0 :         const ::sw::mark::IMark* pBkmk = (pMarkAccess->getAllMarksBegin() + aSave.GetCount())->get();
    1505           0 :         if(pBkmk->GetMarkPos().nNode.GetIndex() == nNode
    1506           0 :             && pBkmk->GetMarkPos().nContent.GetIndex() <= nCntnt)
    1507             :         {
    1508           0 :             if(pBkmk->GetMarkPos().nContent.GetIndex() < nCntnt)
    1509             :             {
    1510           0 :                 aSave.SetContent(pBkmk->GetMarkPos().nContent.GetIndex());
    1511           0 :                 aSave.Add(rSaveArr);
    1512             :             }
    1513             :             else // if a bookmark position is equal nCntnt, the other position
    1514           0 :                 bMarkPosEqual = true; // has to decide if it is added to the array
    1515             :         }
    1516             : 
    1517           0 :         if(pBkmk->IsExpanded()
    1518           0 :             && pBkmk->GetOtherMarkPos().nNode.GetIndex() == nNode
    1519           0 :             && pBkmk->GetOtherMarkPos().nContent.GetIndex() <= nCntnt)
    1520             :         {
    1521           0 :             if(bMarkPosEqual)
    1522             :             { // the other position is before, the (main) position is equal
    1523           0 :                 aSave.SetContent(pBkmk->GetMarkPos().nContent.GetIndex());
    1524           0 :                 aSave.Add(rSaveArr);
    1525             :             }
    1526           0 :             aSave.SetContent(pBkmk->GetOtherMarkPos().nContent.GetIndex());
    1527           0 :             aSave.IncType();
    1528           0 :             aSave.Add(rSaveArr);
    1529           0 :             aSave.DecType();
    1530             :         }
    1531             :     }
    1532             : 
    1533             :     // 2. Redlines
    1534           0 :     aSave.SetTypeAndCount( 0x1000, 0 );
    1535           0 :     const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
    1536           0 :     for( ; aSave.GetCount() < rRedlTbl.size(); aSave.IncCount() )
    1537             :     {
    1538           0 :         const SwRangeRedline* pRdl = rRedlTbl[ aSave.GetCount() ];
    1539           0 :         int nPointPos = lcl_RelativePosition( *pRdl->GetPoint(), nNode, nCntnt );
    1540           0 :         int nMarkPos = pRdl->HasMark() ? lcl_RelativePosition( *pRdl->GetMark(), nNode, nCntnt ) :
    1541           0 :                                           nPointPos;
    1542             :         // #i59534: We have to store the positions inside the same node before the insert position
    1543             :         // and the one at the insert position if the corresponding Point/Mark position is before
    1544             :         // the insert position.
    1545           0 :         if( nPointPos == BEFORE_SAME_NODE ||
    1546           0 :             ( nPointPos == SAME_POSITION && nMarkPos < SAME_POSITION ) )
    1547             :         {
    1548           0 :             aSave.SetContent( pRdl->GetPoint()->nContent.GetIndex() );
    1549           0 :             aSave.IncType();
    1550           0 :             aSave.Add( rSaveArr );
    1551           0 :             aSave.DecType();
    1552             :         }
    1553           0 :         if( pRdl->HasMark() && ( nMarkPos == BEFORE_SAME_NODE ||
    1554           0 :             ( nMarkPos == SAME_POSITION && nPointPos < SAME_POSITION ) ) )
    1555             :         {
    1556           0 :             aSave.SetContent( pRdl->GetMark()->nContent.GetIndex() );
    1557           0 :             aSave.Add( rSaveArr );
    1558             :         }
    1559             :     }
    1560             : 
    1561             :     // 4. Paragraph anchored objects
    1562             :     {
    1563           0 :         SwCntntNode *pNode = pDoc->GetNodes()[nNode]->GetCntntNode();
    1564           0 :         if( pNode )
    1565             :         {
    1566             : 
    1567           0 :             SwFrm* pFrm = pNode->getLayoutFrm( pDoc->GetCurrentLayout() );
    1568             : #if OSL_DEBUG_LEVEL > 1
    1569             :             static bool bViaDoc = false;
    1570             :             if( bViaDoc )
    1571             :                 pFrm = NULL;
    1572             : #endif
    1573           0 :             if( pFrm ) // Do we have a layout? Then it's a bit cheaper ...
    1574             :             {
    1575           0 :                 if( pFrm->GetDrawObjs() )
    1576             :                 {
    1577           0 :                     const SwSortedObjs& rDObj = *pFrm->GetDrawObjs();
    1578           0 :                     for( sal_uInt32 n = rDObj.Count(); n; )
    1579             :                     {
    1580           0 :                         SwAnchoredObject* pObj = rDObj[ --n ];
    1581           0 :                         const SwFrmFmt& rFmt = pObj->GetFrmFmt();
    1582           0 :                         const SwFmtAnchor& rAnchor = rFmt.GetAnchor();
    1583           0 :                         SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
    1584           0 :                         if ( pAPos &&
    1585           0 :                              ( ( nSaveFly &&
    1586           0 :                                  FLY_AT_PARA == rAnchor.GetAnchorId() ) ||
    1587           0 :                                ( FLY_AT_CHAR == rAnchor.GetAnchorId() ) ) )
    1588             :                         {
    1589           0 :                             aSave.SetType( 0x2000 );
    1590           0 :                             aSave.SetContent( pAPos->nContent.GetIndex() );
    1591             : 
    1592             :                             OSL_ENSURE( nNode == pAPos->nNode.GetIndex(),
    1593             :                                     "_SaveCntntIdx: Wrong Node-Index" );
    1594           0 :                             if ( FLY_AT_CHAR == rAnchor.GetAnchorId() )
    1595             :                             {
    1596           0 :                                 if( nCntnt <= aSave.GetContent() )
    1597             :                                 {
    1598           0 :                                     if( SAVEFLY_SPLIT == nSaveFly )
    1599           0 :                                         aSave.IncType(); // = 0x2001;
    1600             :                                     else
    1601           0 :                                         continue;
    1602             :                                 }
    1603             :                             }
    1604           0 :                             aSave.SetCount( pDoc->GetSpzFrmFmts()->size() );
    1605           0 :                             while( aSave.GetCount() &&
    1606           0 :                                     &rFmt != (*pDoc->GetSpzFrmFmts())[
    1607           0 :                                     aSave.DecCount() ] )
    1608             :                                 ; // nothing
    1609             :                             OSL_ENSURE( &rFmt == (*pDoc->GetSpzFrmFmts())[
    1610             :                                                     aSave.GetCount() ],
    1611             :                                     "_SaveCntntIdx: Lost FrameFormat" );
    1612           0 :                             aSave.Add( rSaveArr );
    1613             :                         }
    1614             :                     }
    1615             :                 }
    1616             :             }
    1617             :             else // No layout, so it's a bit more expensive ...
    1618             :             {
    1619           0 :                 for( aSave.SetCount( pDoc->GetSpzFrmFmts()->size() );
    1620           0 :                         aSave.GetCount() ; )
    1621             :                 {
    1622           0 :                     SwFrmFmt* pFrmFmt = (*pDoc->GetSpzFrmFmts())[
    1623           0 :                                                 aSave.DecCount() ];
    1624           0 :                     if ( RES_FLYFRMFMT != pFrmFmt->Which() &&
    1625           0 :                             RES_DRAWFRMFMT != pFrmFmt->Which() )
    1626           0 :                         continue;
    1627             : 
    1628           0 :                     const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
    1629           0 :                     SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
    1630           0 :                     if ( pAPos && ( nNode == pAPos->nNode.GetIndex() ) &&
    1631           0 :                          ( FLY_AT_PARA == rAnchor.GetAnchorId() ||
    1632           0 :                            FLY_AT_CHAR == rAnchor.GetAnchorId() ) )
    1633             :                     {
    1634           0 :                         aSave.SetType( 0x2000 );
    1635           0 :                         aSave.SetContent( pAPos->nContent.GetIndex() );
    1636           0 :                         if ( FLY_AT_CHAR == rAnchor.GetAnchorId() )
    1637             :                         {
    1638           0 :                             if( nCntnt <= aSave.GetContent() )
    1639             :                             {
    1640           0 :                                 if( SAVEFLY_SPLIT == nSaveFly )
    1641           0 :                                     aSave.IncType(); // = 0x2001;
    1642             :                                 else
    1643           0 :                                     continue;
    1644             :                             }
    1645             :                         }
    1646           0 :                         aSave.Add( rSaveArr );
    1647             :                     }
    1648             :                 }
    1649             :             }
    1650             :         }
    1651             :     }
    1652             :     // 5. CrsrShell
    1653             :     {
    1654           0 :         SwCrsrShell* pShell = pDoc->GetEditShell();
    1655           0 :         if( pShell )
    1656             :         {
    1657           0 :             aSave.SetTypeAndCount( 0x800, 0 );
    1658           0 :             FOREACHSHELL_START( pShell )
    1659           0 :                 SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
    1660           0 :                 if( _pStkCrsr )
    1661           0 :                     do {
    1662             :                         lcl_ChkPaM( rSaveArr, nNode, nCntnt, *_pStkCrsr,
    1663           0 :                                     aSave, false );
    1664           0 :                         aSave.IncCount();
    1665           0 :                     } while ( (_pStkCrsr != 0 ) &&
    1666           0 :                         ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
    1667             : 
    1668           0 :                 FOREACHPAM_START( PCURSH->_GetCrsr() )
    1669             :                     lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR,
    1670           0 :                                 aSave, false );
    1671           0 :                     aSave.IncCount();
    1672           0 :                 FOREACHPAM_END()
    1673             : 
    1674           0 :             FOREACHSHELL_END( pShell )
    1675             :         }
    1676             :     }
    1677             :     // 6. UnoCrsr
    1678             :     {
    1679           0 :         aSave.SetTypeAndCount( 0x400, 0 );
    1680           0 :         const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl();
    1681           0 :         for (SwUnoCrsrTbl::const_iterator it = rTbl.begin();
    1682           0 :                 it != rTbl.end(); ++it)
    1683             :         {
    1684           0 :             FOREACHPAM_START( *it )
    1685           0 :                 lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, false );
    1686           0 :                 aSave.IncCount();
    1687           0 :             FOREACHPAM_END()
    1688             : 
    1689             :             SwUnoTableCrsr* pUnoTblCrsr =
    1690           0 :                 dynamic_cast<SwUnoTableCrsr*>(*it);
    1691           0 :             if( pUnoTblCrsr )
    1692             :             {
    1693           0 :                 FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
    1694           0 :                     lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, false );
    1695           0 :                     aSave.IncCount();
    1696           0 :                 FOREACHPAM_END()
    1697             :             }
    1698             :         }
    1699             :     }
    1700           0 : }
    1701             : 
    1702           0 : void _RestoreCntntIdx(SwDoc* pDoc,
    1703             :     std::vector<sal_uLong> &rSaveArr,
    1704             :     sal_uLong nNode,
    1705             :     sal_Int32 nOffset,
    1706             :     bool bAuto)
    1707             : {
    1708           0 :     SwCntntNode* pCNd = pDoc->GetNodes()[ nNode ]->GetCntntNode();
    1709           0 :     const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
    1710           0 :     SwFrmFmts* pSpz = pDoc->GetSpzFrmFmts();
    1711           0 :     IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    1712           0 :     sal_uInt16 n = 0;
    1713           0 :     while( n < rSaveArr.size() )
    1714             :     {
    1715           0 :         _SwSaveTypeCountContent aSave( rSaveArr, n );
    1716           0 :         SwPosition* pPos = 0;
    1717           0 :         switch( aSave.GetType() )
    1718             :         {
    1719             :             case 0x8000:
    1720             :             {
    1721           0 :                 MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aSave.GetCount()].get());
    1722           0 :                 SwPosition aNewPos(pMark->GetMarkPos());
    1723           0 :                 aNewPos.nNode = *pCNd;
    1724           0 :                 aNewPos.nContent.Assign(pCNd, aSave.GetContent() + nOffset);
    1725           0 :                 pMark->SetMarkPos(aNewPos);
    1726             :             }
    1727           0 :             break;
    1728             :             case 0x8001:
    1729             :             {
    1730           0 :                 MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aSave.GetCount()].get());
    1731           0 :                 SwPosition aNewPos(pMark->GetOtherMarkPos());
    1732           0 :                 aNewPos.nNode = *pCNd;
    1733           0 :                 aNewPos.nContent.Assign(pCNd, aSave.GetContent() + nOffset);
    1734           0 :                 pMark->SetOtherMarkPos(aNewPos);
    1735             :             }
    1736           0 :             break;
    1737             :             case 0x1001:
    1738           0 :                 pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetPoint();
    1739           0 :                 break;
    1740             :             case 0x1000:
    1741           0 :                 pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetMark();
    1742           0 :                 break;
    1743             :             case 0x2000:
    1744             :                 {
    1745           0 :                     SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
    1746           0 :                     const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor();
    1747           0 :                     if( rFlyAnchor.GetCntntAnchor() )
    1748             :                     {
    1749           0 :                         SwFmtAnchor aNew( rFlyAnchor );
    1750           0 :                         SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() );
    1751           0 :                         aNewPos.nNode = *pCNd;
    1752           0 :                         if ( FLY_AT_CHAR == rFlyAnchor.GetAnchorId() )
    1753             :                         {
    1754             :                             aNewPos.nContent.Assign( pCNd,
    1755           0 :                                                      aSave.GetContent() + nOffset );
    1756             :                         }
    1757             :                         else
    1758             :                         {
    1759           0 :                             aNewPos.nContent.Assign( 0, 0 );
    1760             :                         }
    1761           0 :                         aNew.SetAnchor( &aNewPos );
    1762           0 :                         pFrmFmt->SetFmtAttr( aNew );
    1763             :                     }
    1764             :                 }
    1765           0 :                 break;
    1766             :             case 0x2001:
    1767           0 :                 if( bAuto )
    1768             :                 {
    1769           0 :                     SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
    1770           0 :                     SfxPoolItem *pAnchor = (SfxPoolItem*)&pFrmFmt->GetAnchor();
    1771           0 :                     pFrmFmt->NotifyClients( pAnchor, pAnchor );
    1772             :                 }
    1773           0 :                 break;
    1774             : 
    1775             :             case 0x0800:
    1776             :             case 0x0801:
    1777             :                 {
    1778           0 :                     SwCrsrShell* pShell = pDoc->GetEditShell();
    1779           0 :                     if( pShell )
    1780             :                     {
    1781           0 :                         sal_uInt16 nCnt = 0;
    1782           0 :                         FOREACHSHELL_START( pShell )
    1783           0 :                             SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
    1784           0 :                             if( _pStkCrsr )
    1785           0 :                                 do {
    1786           0 :                                     if( aSave.GetCount() == nCnt )
    1787             :                                     {
    1788             :                                         pPos = &_pStkCrsr->GetBound( 0x0800 ==
    1789           0 :                                                             aSave.GetType() );
    1790           0 :                                         break;
    1791             :                                     }
    1792           0 :                                     ++nCnt;
    1793           0 :                                 } while ( (_pStkCrsr != 0 ) &&
    1794           0 :                                     ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
    1795             : 
    1796           0 :                             if( pPos )
    1797           0 :                                 break;
    1798             : 
    1799           0 :                             FOREACHPAM_START( PCURSH->_GetCrsr() )
    1800           0 :                                 if( aSave.GetCount() == nCnt )
    1801             :                                 {
    1802             :                                     pPos = &PCURCRSR->GetBound( 0x0800 ==
    1803           0 :                                                         aSave.GetType() );
    1804           0 :                                     break;
    1805             :                                 }
    1806           0 :                                 ++nCnt;
    1807           0 :                             FOREACHPAM_END()
    1808           0 :                             if( pPos )
    1809           0 :                                 break;
    1810             : 
    1811           0 :                         FOREACHSHELL_END( pShell )
    1812             :                     }
    1813             :             }
    1814           0 :             break;
    1815             : 
    1816             :         case 0x0400:
    1817             :         case 0x0401:
    1818             :             {
    1819           0 :                 sal_uInt16 nCnt = 0;
    1820           0 :                 const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl();
    1821           0 :                 for (SwUnoCrsrTbl::const_iterator it = rTbl.begin();
    1822           0 :                         it != rTbl.end(); ++it)
    1823             :                 {
    1824           0 :                     FOREACHPAM_START( *it )
    1825           0 :                         if( aSave.GetCount() == nCnt )
    1826             :                         {
    1827             :                             pPos = &PCURCRSR->GetBound( 0x0400 ==
    1828           0 :                                                     aSave.GetType() );
    1829           0 :                             break;
    1830             :                         }
    1831           0 :                         ++nCnt;
    1832           0 :                     FOREACHPAM_END()
    1833           0 :                     if( pPos )
    1834           0 :                         break;
    1835             : 
    1836             :                     SwUnoTableCrsr* pUnoTblCrsr =
    1837           0 :                         dynamic_cast<SwUnoTableCrsr*>(*it);
    1838           0 :                     if ( pUnoTblCrsr )
    1839             :                     {
    1840           0 :                         FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
    1841           0 :                             if( aSave.GetCount() == nCnt )
    1842             :                             {
    1843             :                                 pPos = &PCURCRSR->GetBound( 0x0400 ==
    1844           0 :                                                     aSave.GetType() );
    1845           0 :                                 break;
    1846             :                             }
    1847           0 :                             ++nCnt;
    1848           0 :                         FOREACHPAM_END()
    1849             :                     }
    1850           0 :                     if ( pPos )
    1851           0 :                         break;
    1852             :                 }
    1853             :             }
    1854           0 :             break;
    1855             :         }
    1856             : 
    1857           0 :         if( pPos )
    1858             :         {
    1859           0 :             pPos->nNode = *pCNd;
    1860           0 :             pPos->nContent.Assign( pCNd, aSave.GetContent() + nOffset );
    1861             :         }
    1862             :     }
    1863           0 : }
    1864             : 
    1865           0 : void _RestoreCntntIdx(std::vector<sal_uLong> &rSaveArr,
    1866             :     const SwNode& rNd,
    1867             :     sal_Int32 nLen,
    1868             :     sal_Int32 nChkLen)
    1869             : {
    1870           0 :     const SwDoc* pDoc = rNd.GetDoc();
    1871           0 :     const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
    1872           0 :     const SwFrmFmts* pSpz = pDoc->GetSpzFrmFmts();
    1873           0 :     const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    1874           0 :     SwCntntNode* pCNd = (SwCntntNode*)rNd.GetCntntNode();
    1875             : 
    1876           0 :     sal_uInt16 n = 0;
    1877           0 :     while( n < rSaveArr.size() )
    1878             :     {
    1879           0 :         _SwSaveTypeCountContent aSave( rSaveArr, n );
    1880           0 :         if( aSave.GetContent() >= nChkLen )
    1881           0 :             rSaveArr[ n-1 ] -= nChkLen;
    1882             :         else
    1883             :         {
    1884           0 :             SwPosition* pPos = 0;
    1885           0 :             switch( aSave.GetType() )
    1886             :             {
    1887             :             case 0x8000:
    1888             :             {
    1889           0 :                 MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aSave.GetCount()].get());
    1890           0 :                 SwPosition aNewPos(pMark->GetMarkPos());
    1891           0 :                 aNewPos.nNode = rNd;
    1892           0 :                 aNewPos.nContent.Assign(pCNd, std::min(aSave.GetContent(), nLen));
    1893           0 :                 pMark->SetMarkPos(aNewPos);
    1894             :             }
    1895           0 :             break;
    1896             :             case 0x8001:
    1897             :             {
    1898           0 :                 MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aSave.GetCount()].get());
    1899           0 :                 SwPosition aNewPos(pMark->GetOtherMarkPos());
    1900           0 :                 aNewPos.nNode = rNd;
    1901           0 :                 aNewPos.nContent.Assign(pCNd, std::min(aSave.GetContent(), nLen));
    1902           0 :                 pMark->SetOtherMarkPos(aNewPos);
    1903             :             }
    1904           0 :             break;
    1905             :             case 0x1001:
    1906           0 :                 pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetPoint();
    1907           0 :                 break;
    1908             :             case 0x1000:
    1909           0 :                 pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetMark();
    1910           0 :                 break;
    1911             :             case 0x2000:
    1912             :             case 0x2001:
    1913             :                 {
    1914           0 :                     SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
    1915           0 :                     const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor();
    1916           0 :                     if( rFlyAnchor.GetCntntAnchor() )
    1917             :                     {
    1918           0 :                         SwFmtAnchor aNew( rFlyAnchor );
    1919           0 :                         SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() );
    1920           0 :                         aNewPos.nNode = rNd;
    1921           0 :                         if ( FLY_AT_CHAR == rFlyAnchor.GetAnchorId() )
    1922             :                         {
    1923             :                             aNewPos.nContent.Assign( pCNd, std::min(
    1924           0 :                                                      aSave.GetContent(), nLen ) );
    1925             :                         }
    1926             :                         else
    1927             :                         {
    1928           0 :                             aNewPos.nContent.Assign( 0, 0 );
    1929             :                         }
    1930           0 :                         aNew.SetAnchor( &aNewPos );
    1931           0 :                         pFrmFmt->SetFmtAttr( aNew );
    1932             :                     }
    1933             :                 }
    1934           0 :                 break;
    1935             : 
    1936             :             case 0x0800:
    1937             :             case 0x0801:
    1938             :                 {
    1939           0 :                     SwCrsrShell* pShell = pDoc->GetEditShell();
    1940           0 :                     if( pShell )
    1941             :                     {
    1942           0 :                         sal_uInt16 nCnt = 0;
    1943           0 :                         FOREACHSHELL_START( pShell )
    1944           0 :                             SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
    1945           0 :                             if( _pStkCrsr )
    1946           0 :                                 do {
    1947           0 :                                     if( aSave.GetCount() == nCnt )
    1948             :                                     {
    1949             :                                         pPos = &_pStkCrsr->GetBound( 0x0800 ==
    1950           0 :                                                     aSave.GetType() );
    1951           0 :                                         break;
    1952             :                                     }
    1953           0 :                                     ++nCnt;
    1954           0 :                                 } while ( (_pStkCrsr != 0 ) &&
    1955           0 :                                     ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
    1956             : 
    1957           0 :                             if( pPos )
    1958           0 :                                 break;
    1959             : 
    1960           0 :                             FOREACHPAM_START( PCURSH->_GetCrsr() )
    1961           0 :                                 if( aSave.GetCount() == nCnt )
    1962             :                                 {
    1963             :                                     pPos = &PCURCRSR->GetBound( 0x0800 ==
    1964           0 :                                                 aSave.GetType() );
    1965           0 :                                     break;
    1966             :                                 }
    1967           0 :                                 ++nCnt;
    1968           0 :                             FOREACHPAM_END()
    1969           0 :                             if( pPos )
    1970           0 :                                 break;
    1971             : 
    1972           0 :                         FOREACHSHELL_END( pShell )
    1973             :                     }
    1974             :                 }
    1975           0 :                 break;
    1976             : 
    1977             :             case 0x0400:
    1978             :             case 0x0401:
    1979             :                 {
    1980           0 :                     sal_uInt16 nCnt = 0;
    1981           0 :                     const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl();
    1982           0 :                     for (SwUnoCrsrTbl::const_iterator it = rTbl.begin();
    1983           0 :                             it != rTbl.end(); ++it)
    1984             :                     {
    1985           0 :                         FOREACHPAM_START( *it )
    1986           0 :                             if( aSave.GetCount() == nCnt )
    1987             :                             {
    1988             :                                 pPos = &PCURCRSR->GetBound( 0x0400 ==
    1989           0 :                                                     aSave.GetType() );
    1990           0 :                                 break;
    1991             :                             }
    1992           0 :                             ++nCnt;
    1993           0 :                         FOREACHPAM_END()
    1994           0 :                         if( pPos )
    1995           0 :                             break;
    1996             : 
    1997             :                         SwUnoTableCrsr* pUnoTblCrsr =
    1998           0 :                             dynamic_cast<SwUnoTableCrsr*>(*it);
    1999           0 :                         if ( pUnoTblCrsr )
    2000             :                         {
    2001           0 :                             FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
    2002           0 :                                 if( aSave.GetCount() == nCnt )
    2003             :                                 {
    2004             :                                     pPos = &PCURCRSR->GetBound( 0x0400 ==
    2005           0 :                                                     aSave.GetType() );
    2006           0 :                                     break;
    2007             :                                 }
    2008           0 :                                 ++nCnt;
    2009           0 :                             FOREACHPAM_END()
    2010             :                         }
    2011           0 :                         if ( pPos )
    2012           0 :                             break;
    2013             :                     }
    2014             :                 }
    2015           0 :                 break;
    2016             :             }
    2017             : 
    2018           0 :             if( pPos )
    2019             :             {
    2020           0 :                 pPos->nNode = rNd;
    2021           0 :                 pPos->nContent.Assign( pCNd, std::min( aSave.GetContent(), nLen ) );
    2022             :             }
    2023           0 :             n -= 2;
    2024           0 :             rSaveArr.erase( rSaveArr.begin() + n, rSaveArr.begin() + n + 2);
    2025             :         }
    2026             :     }
    2027           0 : }
    2028             : 
    2029             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10