LCOV - code coverage report
Current view: top level - sw/source/core/doc - docbm.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 356 794 44.8 %
Date: 2012-08-25 Functions: 51 69 73.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 417 1498 27.8 %

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

Generated by: LCOV version 1.10