xref: /AOO41X/main/sw/source/core/doc/docbm.cxx (revision 12ad4c42153346fda96f0ac6386beaeb2adda508)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <MarkManager.hxx>
29cdf0e10cSrcweir #include <bookmrk.hxx>
30cdf0e10cSrcweir #include <boost/bind.hpp>
31cdf0e10cSrcweir #include <cntfrm.hxx>
32cdf0e10cSrcweir #include <crossrefbookmark.hxx>
33dec99bbdSOliver-Rainer Wittmann #include <annotationmark.hxx>
34cdf0e10cSrcweir #include <dcontact.hxx>
35cdf0e10cSrcweir #include <doc.hxx>
36cdf0e10cSrcweir #include <docary.hxx>
37cdf0e10cSrcweir #include <xmloff/odffields.hxx>
38cdf0e10cSrcweir #include <editsh.hxx>
39cdf0e10cSrcweir #include <errhdl.hxx>
40cdf0e10cSrcweir #include <fmtanchr.hxx>
41cdf0e10cSrcweir #include <frmfmt.hxx>
42cdf0e10cSrcweir #include <functional>
43cdf0e10cSrcweir #include <hintids.hxx>
44cdf0e10cSrcweir #include <mvsave.hxx>
45cdf0e10cSrcweir #include <ndtxt.hxx>
46cdf0e10cSrcweir #include <node.hxx>
47cdf0e10cSrcweir #include <pam.hxx>
48cdf0e10cSrcweir #include <redline.hxx>
49cdf0e10cSrcweir #include <rolbck.hxx>
50cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
51cdf0e10cSrcweir #include <rtl/ustring.hxx>
52cdf0e10cSrcweir #include <sal/types.h>
53cdf0e10cSrcweir #include <sortedobjs.hxx>
54cdf0e10cSrcweir #include <sfx2/linkmgr.hxx>
55cdf0e10cSrcweir #include <swserv.hxx>
56cdf0e10cSrcweir #include <swundo.hxx>
57cdf0e10cSrcweir #include <tools/pstm.hxx>
58cdf0e10cSrcweir #include <unocrsr.hxx>
59cdf0e10cSrcweir #include <viscrs.hxx>
60cdf0e10cSrcweir #include <stdio.h>
61cdf0e10cSrcweir 
62cdf0e10cSrcweir 
63cdf0e10cSrcweir using namespace ::sw::mark;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir namespace
66cdf0e10cSrcweir {
lcl_GreaterThan(const SwPosition & rPos,const SwNodeIndex & rNdIdx,const SwIndex * pIdx)67cdf0e10cSrcweir     static bool lcl_GreaterThan( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
68cdf0e10cSrcweir     {
69de5fde26SOliver-Rainer Wittmann         return pIdx != NULL
70de5fde26SOliver-Rainer Wittmann                ? ( rPos.nNode > rNdIdx
71de5fde26SOliver-Rainer Wittmann                    || ( rPos.nNode == rNdIdx
72de5fde26SOliver-Rainer Wittmann                         && rPos.nContent >= pIdx->GetIndex() ) )
73de5fde26SOliver-Rainer Wittmann                : rPos.nNode >= rNdIdx;
74cdf0e10cSrcweir     }
75cdf0e10cSrcweir 
lcl_Lower(const SwPosition & rPos,const SwNodeIndex & rNdIdx,const SwIndex * pIdx)76cdf0e10cSrcweir     static bool lcl_Lower( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
77cdf0e10cSrcweir     {
78de5fde26SOliver-Rainer Wittmann         return rPos.nNode < rNdIdx
79de5fde26SOliver-Rainer Wittmann                || ( pIdx != NULL
80de5fde26SOliver-Rainer Wittmann                     && rPos.nNode == rNdIdx
81de5fde26SOliver-Rainer Wittmann                     && rPos.nContent < pIdx->GetIndex() );
82cdf0e10cSrcweir     }
83cdf0e10cSrcweir 
lcl_MarkOrderingByStart(const IDocumentMarkAccess::pMark_t & rpFirst,const IDocumentMarkAccess::pMark_t & rpSecond)84cdf0e10cSrcweir     static bool lcl_MarkOrderingByStart(const IDocumentMarkAccess::pMark_t& rpFirst,
85cdf0e10cSrcweir         const IDocumentMarkAccess::pMark_t& rpSecond)
86cdf0e10cSrcweir     {
87cdf0e10cSrcweir         return rpFirst->GetMarkStart() < rpSecond->GetMarkStart();
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir 
lcl_MarkOrderingByEnd(const IDocumentMarkAccess::pMark_t & rpFirst,const IDocumentMarkAccess::pMark_t & rpSecond)90cdf0e10cSrcweir     static bool lcl_MarkOrderingByEnd(const IDocumentMarkAccess::pMark_t& rpFirst,
91cdf0e10cSrcweir         const IDocumentMarkAccess::pMark_t& rpSecond)
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         return rpFirst->GetMarkEnd() < rpSecond->GetMarkEnd();
94cdf0e10cSrcweir     }
95cdf0e10cSrcweir 
lcl_InsertMarkSorted(IDocumentMarkAccess::container_t & io_vMarks,const IDocumentMarkAccess::pMark_t & pMark)96cdf0e10cSrcweir     static void lcl_InsertMarkSorted(IDocumentMarkAccess::container_t& io_vMarks,
97cdf0e10cSrcweir         const IDocumentMarkAccess::pMark_t& pMark)
98cdf0e10cSrcweir     {
99cdf0e10cSrcweir         io_vMarks.insert(
100cdf0e10cSrcweir             lower_bound(
101cdf0e10cSrcweir                 io_vMarks.begin(),
102cdf0e10cSrcweir                 io_vMarks.end(),
103cdf0e10cSrcweir                 pMark,
104cdf0e10cSrcweir                 &lcl_MarkOrderingByStart),
105cdf0e10cSrcweir             pMark);
106cdf0e10cSrcweir     }
107cdf0e10cSrcweir 
lcl_PositionFromCntntNode(SwCntntNode * const pCntntNode,const bool bAtEnd=false)108fb3f75f2SOliver-Rainer Wittmann     static inline ::std::auto_ptr<SwPosition> lcl_PositionFromCntntNode(
109fb3f75f2SOliver-Rainer Wittmann         SwCntntNode * const pCntntNode,
110fb3f75f2SOliver-Rainer Wittmann         const bool bAtEnd=false)
111cdf0e10cSrcweir     {
112de5fde26SOliver-Rainer Wittmann         ::std::auto_ptr<SwPosition> pResult(new SwPosition(*pCntntNode));
113cdf0e10cSrcweir         pResult->nContent.Assign(pCntntNode, bAtEnd ? pCntntNode->Len() : 0);
114cdf0e10cSrcweir         return pResult;
115cdf0e10cSrcweir     }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir     // return a position at the begin of rEnd, if it is a CntntNode
118cdf0e10cSrcweir     // else set it to the begin of the Node after rEnd, if there is one
119cdf0e10cSrcweir     // else set it to the end of the node before rStt
120cdf0e10cSrcweir     // else set it to the CntntNode of the Pos outside the Range
lcl_FindExpelPosition(const SwNodeIndex & rStt,const SwNodeIndex & rEnd,const SwPosition & rOtherPosition)121fb3f75f2SOliver-Rainer Wittmann     static inline ::std::auto_ptr<SwPosition> lcl_FindExpelPosition(
122fb3f75f2SOliver-Rainer Wittmann         const SwNodeIndex& rStt,
123cdf0e10cSrcweir         const SwNodeIndex& rEnd,
124cdf0e10cSrcweir         const SwPosition& rOtherPosition)
125cdf0e10cSrcweir     {
126cdf0e10cSrcweir         SwCntntNode * pNode = rEnd.GetNode().GetCntntNode();
127fb3f75f2SOliver-Rainer Wittmann         bool bPosAtEndOfNode = false;
128fb3f75f2SOliver-Rainer Wittmann         if ( pNode == NULL)
129fb3f75f2SOliver-Rainer Wittmann         {
130cdf0e10cSrcweir             SwNodeIndex aEnd = SwNodeIndex(rEnd);
131fb3f75f2SOliver-Rainer Wittmann             pNode = rEnd.GetNodes().GoNext( &aEnd );
132fb3f75f2SOliver-Rainer Wittmann             bPosAtEndOfNode = false;
133fb3f75f2SOliver-Rainer Wittmann         }
134fb3f75f2SOliver-Rainer Wittmann         if ( pNode == NULL )
135fb3f75f2SOliver-Rainer Wittmann         {
136fb3f75f2SOliver-Rainer Wittmann             SwNodeIndex aStt = SwNodeIndex(rStt);
137fb3f75f2SOliver-Rainer Wittmann             pNode = rStt.GetNodes().GoPrevious(&aStt);
138fb3f75f2SOliver-Rainer Wittmann             bPosAtEndOfNode = true;
139fb3f75f2SOliver-Rainer Wittmann         }
140fb3f75f2SOliver-Rainer Wittmann         if ( pNode != NULL )
141fb3f75f2SOliver-Rainer Wittmann         {
142fb3f75f2SOliver-Rainer Wittmann             return lcl_PositionFromCntntNode( pNode, bPosAtEndOfNode );
143fb3f75f2SOliver-Rainer Wittmann         }
144fb3f75f2SOliver-Rainer Wittmann 
145de5fde26SOliver-Rainer Wittmann         return ::std::auto_ptr<SwPosition>(new SwPosition(rOtherPosition));
146cdf0e10cSrcweir     };
147cdf0e10cSrcweir 
lcl_getMarkAfter(const IDocumentMarkAccess::container_t & rMarks,const SwPosition & rPos)148cdf0e10cSrcweir     static IMark* lcl_getMarkAfter(const IDocumentMarkAccess::container_t& rMarks, const SwPosition& rPos)
149cdf0e10cSrcweir     {
150cdf0e10cSrcweir         IDocumentMarkAccess::const_iterator_t pMarkAfter = upper_bound(
151cdf0e10cSrcweir             rMarks.begin(),
152cdf0e10cSrcweir             rMarks.end(),
153cdf0e10cSrcweir             rPos,
154cdf0e10cSrcweir             bind(&IMark::StartsAfter, _2, _1)); // finds the first that is starting after
155cdf0e10cSrcweir         if(pMarkAfter == rMarks.end()) return NULL;
156cdf0e10cSrcweir         return pMarkAfter->get();
157cdf0e10cSrcweir     };
158cdf0e10cSrcweir 
lcl_getMarkBefore(const IDocumentMarkAccess::container_t & rMarks,const SwPosition & rPos)159cdf0e10cSrcweir     static IMark* lcl_getMarkBefore(const IDocumentMarkAccess::container_t& rMarks, const SwPosition& rPos)
160cdf0e10cSrcweir     {
161cdf0e10cSrcweir         // candidates from which to choose the mark before
162cdf0e10cSrcweir         IDocumentMarkAccess::container_t vCandidates;
163cdf0e10cSrcweir         // no need to consider marks starting after rPos
164cdf0e10cSrcweir         IDocumentMarkAccess::const_iterator_t pCandidatesEnd = upper_bound(
165cdf0e10cSrcweir             rMarks.begin(),
166cdf0e10cSrcweir             rMarks.end(),
167cdf0e10cSrcweir             rPos,
168cdf0e10cSrcweir             bind(&IMark::StartsAfter, _2, _1));
169cdf0e10cSrcweir         vCandidates.reserve(pCandidatesEnd - rMarks.begin());
170cdf0e10cSrcweir         // only marks ending before are candidates
171cdf0e10cSrcweir         remove_copy_if(
172cdf0e10cSrcweir             rMarks.begin(),
173cdf0e10cSrcweir             pCandidatesEnd,
174cdf0e10cSrcweir             back_inserter(vCandidates),
175de5fde26SOliver-Rainer Wittmann             boost::bind( ::std::logical_not<bool>(), bind( &IMark::EndsBefore, _1, rPos ) ) );
176cdf0e10cSrcweir         // no candidate left => we are in front of the first mark or there are none
177cdf0e10cSrcweir         if(!vCandidates.size()) return NULL;
178cdf0e10cSrcweir         // return the highest (last) candidate using mark end ordering
179cdf0e10cSrcweir         return max_element(vCandidates.begin(), vCandidates.end(), &lcl_MarkOrderingByEnd)->get();
180cdf0e10cSrcweir     }
181cdf0e10cSrcweir 
lcl_FixCorrectedMark(const bool bChangedPos,const bool bChangedOPos,MarkBase * io_pMark)182332f371aSOliver-Rainer Wittmann     static bool lcl_FixCorrectedMark(
183332f371aSOliver-Rainer Wittmann         const bool bChangedPos,
184332f371aSOliver-Rainer Wittmann         const bool bChangedOPos,
185332f371aSOliver-Rainer Wittmann         MarkBase* io_pMark )
186cdf0e10cSrcweir     {
187332f371aSOliver-Rainer Wittmann         if ( IDocumentMarkAccess::GetType(*io_pMark) == IDocumentMarkAccess::ANNOTATIONMARK )
188332f371aSOliver-Rainer Wittmann         {
189332f371aSOliver-Rainer Wittmann             // annotation marks are allowed to span a table cell range.
190332f371aSOliver-Rainer Wittmann             // but trigger sorting to be save
191332f371aSOliver-Rainer Wittmann             return true;
192332f371aSOliver-Rainer Wittmann         }
193332f371aSOliver-Rainer Wittmann 
194332f371aSOliver-Rainer Wittmann         if ( ( bChangedPos || bChangedOPos )
195332f371aSOliver-Rainer Wittmann              && io_pMark->IsExpanded()
196332f371aSOliver-Rainer Wittmann              && io_pMark->GetOtherMarkPos().nNode.GetNode().FindTableBoxStartNode() !=
197cdf0e10cSrcweir                     io_pMark->GetMarkPos().nNode.GetNode().FindTableBoxStartNode() )
198cdf0e10cSrcweir         {
199cdf0e10cSrcweir             if ( !bChangedOPos )
200332f371aSOliver-Rainer Wittmann             {
201cdf0e10cSrcweir                 io_pMark->SetMarkPos( io_pMark->GetOtherMarkPos() );
202332f371aSOliver-Rainer Wittmann             }
203cdf0e10cSrcweir             io_pMark->ClearOtherMarkPos();
204cdf0e10cSrcweir             DdeBookmark * const pDdeBkmk = dynamic_cast< DdeBookmark*>(io_pMark);
205332f371aSOliver-Rainer Wittmann             if ( pDdeBkmk != NULL
206332f371aSOliver-Rainer Wittmann                  && pDdeBkmk->IsServer() )
207332f371aSOliver-Rainer Wittmann             {
208cdf0e10cSrcweir                 pDdeBkmk->SetRefObject(NULL);
209332f371aSOliver-Rainer Wittmann             }
210cdf0e10cSrcweir             return true;
211cdf0e10cSrcweir         }
212cdf0e10cSrcweir         return false;
213cdf0e10cSrcweir     }
214cdf0e10cSrcweir 
lcl_FindMark(IDocumentMarkAccess::container_t & rMarks,const IDocumentMarkAccess::pMark_t & rpMarkToFind)215cdf0e10cSrcweir     static IDocumentMarkAccess::iterator_t lcl_FindMark(
216cdf0e10cSrcweir         IDocumentMarkAccess::container_t& rMarks,
217cdf0e10cSrcweir         const IDocumentMarkAccess::pMark_t& rpMarkToFind)
218cdf0e10cSrcweir     {
219cdf0e10cSrcweir         IDocumentMarkAccess::iterator_t ppCurrentMark = lower_bound(
220cdf0e10cSrcweir             rMarks.begin(), rMarks.end(),
221cdf0e10cSrcweir             rpMarkToFind, &lcl_MarkOrderingByStart);
222cdf0e10cSrcweir         // since there are usually not too many marks on the same start
223cdf0e10cSrcweir         // position, we are not doing a bisect search for the upper bound
224cdf0e10cSrcweir         // but instead start to iterate from pMarkLow directly
225cdf0e10cSrcweir         while(ppCurrentMark != rMarks.end() && **ppCurrentMark == *rpMarkToFind)
226cdf0e10cSrcweir         {
227cdf0e10cSrcweir             if(ppCurrentMark->get() == rpMarkToFind.get())
228cdf0e10cSrcweir             {
229cdf0e10cSrcweir                 //OSL_TRACE("found mark named '%s'",
230cdf0e10cSrcweir                 //    ::rtl::OUStringToOString(ppCurrentMark->get()->GetName(), RTL_TEXTENCODING_UTF8).getStr());
231cdf0e10cSrcweir                 return ppCurrentMark;
232cdf0e10cSrcweir             }
233cdf0e10cSrcweir             ++ppCurrentMark;
234cdf0e10cSrcweir         }
235cdf0e10cSrcweir         // reached a mark starting on a later start pos or the end of the
236cdf0e10cSrcweir         // vector => not found
237cdf0e10cSrcweir         return rMarks.end();
238cdf0e10cSrcweir     };
239cdf0e10cSrcweir 
lcl_FindMarkAtPos(IDocumentMarkAccess::container_t & rMarks,const SwPosition & rPos,const IDocumentMarkAccess::MarkType eType)240cdf0e10cSrcweir     static IDocumentMarkAccess::iterator_t lcl_FindMarkAtPos(
241cdf0e10cSrcweir         IDocumentMarkAccess::container_t& rMarks,
242cdf0e10cSrcweir         const SwPosition& rPos,
243cdf0e10cSrcweir         const IDocumentMarkAccess::MarkType eType)
244cdf0e10cSrcweir     {
245cdf0e10cSrcweir         for(IDocumentMarkAccess::iterator_t ppCurrentMark = lower_bound(
246cdf0e10cSrcweir                 rMarks.begin(), rMarks.end(),
247cdf0e10cSrcweir                 rPos,
248cdf0e10cSrcweir                 bind(&IMark::StartsBefore, _1, _2));
249cdf0e10cSrcweir             ppCurrentMark != rMarks.end();
250cdf0e10cSrcweir             ++ppCurrentMark)
251cdf0e10cSrcweir         {
252cdf0e10cSrcweir             // Once we reach a mark starting after the target pos
253cdf0e10cSrcweir             // we do not need to continue
254cdf0e10cSrcweir             if(ppCurrentMark->get()->StartsAfter(rPos))
255cdf0e10cSrcweir                 break;
256cdf0e10cSrcweir             if(IDocumentMarkAccess::GetType(**ppCurrentMark) == eType)
257cdf0e10cSrcweir             {
258cdf0e10cSrcweir                 //OSL_TRACE("found mark named '%s'",
259cdf0e10cSrcweir                 //    ::rtl::OUStringToOString(ppCurrentMark->get()->GetName(), RTL_TEXTENCODING_UTF8).getStr());
260cdf0e10cSrcweir                 return ppCurrentMark;
261cdf0e10cSrcweir             }
262cdf0e10cSrcweir         }
263cdf0e10cSrcweir         // reached a mark starting on a later start pos or the end of the
264cdf0e10cSrcweir         // vector => not found
265cdf0e10cSrcweir         return rMarks.end();
266cdf0e10cSrcweir     };
267cdf0e10cSrcweir 
lcl_FindMarkByName(const::rtl::OUString & rName,IDocumentMarkAccess::const_iterator_t ppMarksBegin,IDocumentMarkAccess::const_iterator_t ppMarksEnd)268cdf0e10cSrcweir     static IDocumentMarkAccess::const_iterator_t lcl_FindMarkByName(
269cdf0e10cSrcweir         const ::rtl::OUString& rName,
270cdf0e10cSrcweir         IDocumentMarkAccess::const_iterator_t ppMarksBegin,
271cdf0e10cSrcweir         IDocumentMarkAccess::const_iterator_t ppMarksEnd)
272cdf0e10cSrcweir     {
273cdf0e10cSrcweir         return find_if(
274cdf0e10cSrcweir             ppMarksBegin,
275cdf0e10cSrcweir             ppMarksEnd,
276cdf0e10cSrcweir             bind(&::rtl::OUString::equals, bind(&IMark::GetName, _1), rName));
277cdf0e10cSrcweir     }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir #if 0
280cdf0e10cSrcweir     static void lcl_DebugMarks(IDocumentMarkAccess::container_t vMarks)
281cdf0e10cSrcweir     {
282cdf0e10cSrcweir         OSL_TRACE("%d Marks", vMarks.size());
283cdf0e10cSrcweir         for(IDocumentMarkAccess::iterator_t ppMark = vMarks.begin();
284cdf0e10cSrcweir             ppMark != vMarks.end();
285cdf0e10cSrcweir             ppMark++)
286cdf0e10cSrcweir         {
287cdf0e10cSrcweir             IMark* pMark = ppMark->get();
288cdf0e10cSrcweir             ::rtl::OString sName = ::rtl::OUStringToOString(pMark->GetName(), RTL_TEXTENCODING_UTF8);
289cdf0e10cSrcweir             const SwPosition* const pStPos = &pMark->GetMarkStart();
290cdf0e10cSrcweir             const SwPosition* const pEndPos = &pMark->GetMarkEnd();
291cdf0e10cSrcweir             OSL_TRACE("%s %s %d,%d %d,%d",
292cdf0e10cSrcweir                 typeid(*pMark).name(),
293cdf0e10cSrcweir                 sName.getStr(),
294cdf0e10cSrcweir                 pStPos->nNode.GetIndex(),
295cdf0e10cSrcweir                 pStPos->nContent.GetIndex(),
296cdf0e10cSrcweir                 pEndPos->nNode.GetIndex(),
297cdf0e10cSrcweir                 pEndPos->nContent.GetIndex());
298cdf0e10cSrcweir         }
299cdf0e10cSrcweir     };
300cdf0e10cSrcweir #endif
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
GetType(const IMark & rBkmk)303cdf0e10cSrcweir IDocumentMarkAccess::MarkType IDocumentMarkAccess::GetType(const IMark& rBkmk)
304cdf0e10cSrcweir {
305cdf0e10cSrcweir     const std::type_info* const pMarkTypeInfo = &typeid(rBkmk);
306cdf0e10cSrcweir     // not using dynamic_cast<> here for performance
307cdf0e10cSrcweir     if(*pMarkTypeInfo == typeid(UnoMark))
308cdf0e10cSrcweir         return UNO_BOOKMARK;
309cdf0e10cSrcweir     else if(*pMarkTypeInfo == typeid(DdeBookmark))
310cdf0e10cSrcweir         return DDE_BOOKMARK;
311cdf0e10cSrcweir     else if(*pMarkTypeInfo == typeid(Bookmark))
312cdf0e10cSrcweir         return BOOKMARK;
313cdf0e10cSrcweir     else if(*pMarkTypeInfo == typeid(CrossRefHeadingBookmark))
314cdf0e10cSrcweir         return CROSSREF_HEADING_BOOKMARK;
315cdf0e10cSrcweir     else if(*pMarkTypeInfo == typeid(CrossRefNumItemBookmark))
316cdf0e10cSrcweir         return CROSSREF_NUMITEM_BOOKMARK;
317dec99bbdSOliver-Rainer Wittmann     else if(*pMarkTypeInfo == typeid(AnnotationMark))
318dec99bbdSOliver-Rainer Wittmann         return ANNOTATIONMARK;
319cdf0e10cSrcweir     else if(*pMarkTypeInfo == typeid(TextFieldmark))
320cdf0e10cSrcweir         return TEXT_FIELDMARK;
321cdf0e10cSrcweir     else if(*pMarkTypeInfo == typeid(CheckboxFieldmark))
322cdf0e10cSrcweir         return CHECKBOX_FIELDMARK;
323cdf0e10cSrcweir     else if(*pMarkTypeInfo == typeid(NavigatorReminder))
324cdf0e10cSrcweir         return NAVIGATOR_REMINDER;
325cdf0e10cSrcweir     else
326cdf0e10cSrcweir     {
327cdf0e10cSrcweir         OSL_ENSURE(false,
328cdf0e10cSrcweir             "IDocumentMarkAccess::GetType(..)"
329cdf0e10cSrcweir             " - unknown MarkType. This needs to be fixed!");
330cdf0e10cSrcweir         return UNO_BOOKMARK;
331cdf0e10cSrcweir     }
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
GetCrossRefHeadingBookmarkNamePrefix()3343078b051SOliver-Rainer Wittmann const ::rtl::OUString& IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()
3353078b051SOliver-Rainer Wittmann {
3363078b051SOliver-Rainer Wittmann     static const ::rtl::OUString CrossRefHeadingBookmarkNamePrefix = ::rtl::OUString::createFromAscii("__RefHeading__");
3373078b051SOliver-Rainer Wittmann 
3383078b051SOliver-Rainer Wittmann     return CrossRefHeadingBookmarkNamePrefix;
3393078b051SOliver-Rainer Wittmann }
3403078b051SOliver-Rainer Wittmann 
IsLegalPaMForCrossRefHeadingBookmark(const SwPaM & rPaM)341a180b29cSHerbert Dürr bool SAL_DLLPUBLIC_EXPORT IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( const SwPaM& rPaM )
3423078b051SOliver-Rainer Wittmann {
3433078b051SOliver-Rainer Wittmann     bool bRet( false );
3443078b051SOliver-Rainer Wittmann 
3453078b051SOliver-Rainer Wittmann     bRet = rPaM.Start()->nNode.GetNode().IsTxtNode() &&
3463078b051SOliver-Rainer Wittmann            rPaM.Start()->nContent.GetIndex() == 0 &&
3473078b051SOliver-Rainer Wittmann            ( !rPaM.HasMark() ||
3483078b051SOliver-Rainer Wittmann              ( rPaM.GetMark()->nNode == rPaM.GetPoint()->nNode &&
3493078b051SOliver-Rainer Wittmann                rPaM.End()->nContent.GetIndex() == rPaM.End()->nNode.GetNode().GetTxtNode()->Len() ) );
3503078b051SOliver-Rainer Wittmann 
3513078b051SOliver-Rainer Wittmann     return bRet;
3523078b051SOliver-Rainer Wittmann }
3533078b051SOliver-Rainer Wittmann 
354cdf0e10cSrcweir namespace sw { namespace mark
355cdf0e10cSrcweir {
MarkManager(SwDoc & rDoc)356cdf0e10cSrcweir     MarkManager::MarkManager(SwDoc& rDoc)
357dec99bbdSOliver-Rainer Wittmann         : m_vAllMarks()
358dec99bbdSOliver-Rainer Wittmann         , m_vBookmarks()
359dec99bbdSOliver-Rainer Wittmann         , m_vFieldmarks()
360dec99bbdSOliver-Rainer Wittmann         , m_vAnnotationMarks()
361dec99bbdSOliver-Rainer Wittmann         , m_pDoc(&rDoc)
362cdf0e10cSrcweir     { }
363dec99bbdSOliver-Rainer Wittmann 
364dec99bbdSOliver-Rainer Wittmann 
makeMark(const SwPaM & rPaM,const::rtl::OUString & rName,const IDocumentMarkAccess::MarkType eType)365cdf0e10cSrcweir     ::sw::mark::IMark* MarkManager::makeMark(const SwPaM& rPaM,
366cdf0e10cSrcweir         const ::rtl::OUString& rName,
367cdf0e10cSrcweir         const IDocumentMarkAccess::MarkType eType)
368cdf0e10cSrcweir     {
369cdf0e10cSrcweir #if 0
370cdf0e10cSrcweir         {
371cdf0e10cSrcweir             ::rtl::OString sName = ::rtl::OUStringToOString(rName, RTL_TEXTENCODING_UTF8);
372cdf0e10cSrcweir             const SwPosition* const pPos1 = rPaM.GetPoint();
373cdf0e10cSrcweir             const SwPosition* pPos2 = pPos1;
374cdf0e10cSrcweir             if(rPaM.HasMark())
375cdf0e10cSrcweir                 pPos2 = rPaM.GetMark();
376cdf0e10cSrcweir             OSL_TRACE("%s %d,%d %d,%d",
377cdf0e10cSrcweir                 sName.getStr(),
378cdf0e10cSrcweir                 pPos1->nNode.GetIndex(),
379cdf0e10cSrcweir                 pPos1->nContent.GetIndex(),
380cdf0e10cSrcweir                 pPos2->nNode.GetIndex(),
381cdf0e10cSrcweir                 pPos2->nContent.GetIndex());
382cdf0e10cSrcweir         }
383cdf0e10cSrcweir #endif
384cdf0e10cSrcweir         // see for example _SaveCntntIdx, Shells
385dec99bbdSOliver-Rainer Wittmann         OSL_PRECOND(m_vAllMarks.size() < USHRT_MAX,
386cdf0e10cSrcweir             "MarkManager::makeMark(..)"
387cdf0e10cSrcweir             " - more than USHRT_MAX marks are not supported correctly");
388cdf0e10cSrcweir         // There should only be one CrossRefBookmark per Textnode per Type
389cdf0e10cSrcweir         OSL_PRECOND(
390cdf0e10cSrcweir             (eType != CROSSREF_NUMITEM_BOOKMARK && eType != CROSSREF_HEADING_BOOKMARK)
391cdf0e10cSrcweir             || (lcl_FindMarkAtPos(m_vBookmarks, *rPaM.GetPoint(), eType) == m_vBookmarks.end()),
392cdf0e10cSrcweir             "MarkManager::makeMark(..)"
393cdf0e10cSrcweir             " - creating duplicate CrossRefBookmark");
394cdf0e10cSrcweir 
395cdf0e10cSrcweir         // create mark
396ed393576SHerbert Dürr         MarkBase* pMarkBase = NULL;
397cdf0e10cSrcweir         switch(eType)
398cdf0e10cSrcweir         {
399cdf0e10cSrcweir             case IDocumentMarkAccess::TEXT_FIELDMARK:
400ed393576SHerbert Dürr                 pMarkBase = new TextFieldmark(rPaM);
401cdf0e10cSrcweir                 break;
402cdf0e10cSrcweir             case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
403ed393576SHerbert Dürr                 pMarkBase = new CheckboxFieldmark(rPaM);
404cdf0e10cSrcweir                 break;
405cdf0e10cSrcweir             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
406ed393576SHerbert Dürr                 pMarkBase = new NavigatorReminder(rPaM);
407cdf0e10cSrcweir                 break;
408cdf0e10cSrcweir             case IDocumentMarkAccess::BOOKMARK:
409ed393576SHerbert Dürr                 pMarkBase = new Bookmark(rPaM, KeyCode(), rName, ::rtl::OUString());
410cdf0e10cSrcweir                 break;
411cdf0e10cSrcweir             case IDocumentMarkAccess::DDE_BOOKMARK:
412ed393576SHerbert Dürr                 pMarkBase = new DdeBookmark(rPaM);
413cdf0e10cSrcweir                 break;
414cdf0e10cSrcweir             case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
415ed393576SHerbert Dürr                 pMarkBase = new CrossRefHeadingBookmark(rPaM, KeyCode(), rName, ::rtl::OUString());
416cdf0e10cSrcweir                 break;
417cdf0e10cSrcweir             case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
418ed393576SHerbert Dürr                 pMarkBase = new CrossRefNumItemBookmark(rPaM, KeyCode(), rName, ::rtl::OUString());
419cdf0e10cSrcweir                 break;
420cdf0e10cSrcweir             case IDocumentMarkAccess::UNO_BOOKMARK:
421ed393576SHerbert Dürr                 pMarkBase = new UnoMark(rPaM);
422cdf0e10cSrcweir                 break;
423dec99bbdSOliver-Rainer Wittmann             case IDocumentMarkAccess::ANNOTATIONMARK:
424dec99bbdSOliver-Rainer Wittmann                 pMarkBase = new AnnotationMark( rPaM, rName );
425dec99bbdSOliver-Rainer Wittmann                 break;
426cdf0e10cSrcweir         }
427ed393576SHerbert Dürr         OSL_ENSURE( pMarkBase!=NULL,
428cdf0e10cSrcweir             "MarkManager::makeMark(..)"
429cdf0e10cSrcweir             " - Mark was not created.");
430cdf0e10cSrcweir 
431ed393576SHerbert Dürr         pMark_t pMark = boost::shared_ptr<IMark>( pMarkBase);
432cdf0e10cSrcweir         if(pMark->GetMarkPos() != pMark->GetMarkStart())
433cdf0e10cSrcweir             pMarkBase->Swap();
434cdf0e10cSrcweir 
435cdf0e10cSrcweir         // for performance reasons, we trust UnoMarks to have a (generated) unique name
436cdf0e10cSrcweir         if ( eType != IDocumentMarkAccess::UNO_BOOKMARK )
437cdf0e10cSrcweir             pMarkBase->SetName( getUniqueMarkName( pMarkBase->GetName() ) );
438cdf0e10cSrcweir 
439cdf0e10cSrcweir         // register mark
440dec99bbdSOliver-Rainer Wittmann         lcl_InsertMarkSorted( m_vAllMarks, pMark );
441cdf0e10cSrcweir         switch(eType)
442cdf0e10cSrcweir         {
443cdf0e10cSrcweir             case IDocumentMarkAccess::BOOKMARK:
444cdf0e10cSrcweir             case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
445cdf0e10cSrcweir             case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
446cdf0e10cSrcweir                 // if(dynamic_cast<IBookmark*>)
447cdf0e10cSrcweir                 lcl_InsertMarkSorted(m_vBookmarks, pMark);
448cdf0e10cSrcweir                 break;
449cdf0e10cSrcweir             case IDocumentMarkAccess::TEXT_FIELDMARK:
450cdf0e10cSrcweir             case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
451cdf0e10cSrcweir                 // if(dynamic_cast<IFieldmark*>
452cdf0e10cSrcweir                 lcl_InsertMarkSorted(m_vFieldmarks, pMark);
453cdf0e10cSrcweir                 break;
454dec99bbdSOliver-Rainer Wittmann             case IDocumentMarkAccess::ANNOTATIONMARK:
455dec99bbdSOliver-Rainer Wittmann                 lcl_InsertMarkSorted( m_vAnnotationMarks, pMark );
456dec99bbdSOliver-Rainer Wittmann                 break;
457cdf0e10cSrcweir             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
458cdf0e10cSrcweir             case IDocumentMarkAccess::DDE_BOOKMARK:
459cdf0e10cSrcweir             case IDocumentMarkAccess::UNO_BOOKMARK:
460cdf0e10cSrcweir                 // no special array for these
461cdf0e10cSrcweir                 break;
462cdf0e10cSrcweir         }
463cdf0e10cSrcweir         pMarkBase->InitDoc(m_pDoc);
464cdf0e10cSrcweir #if 0
465cdf0e10cSrcweir         OSL_TRACE("--- makeType ---");
466cdf0e10cSrcweir         OSL_TRACE("Marks");
467dec99bbdSOliver-Rainer Wittmann         lcl_DebugMarks(m_vAllMarks);
468cdf0e10cSrcweir         OSL_TRACE("Bookmarks");
469cdf0e10cSrcweir         lcl_DebugMarks(m_vBookmarks);
470cdf0e10cSrcweir         OSL_TRACE("Fieldmarks");
471cdf0e10cSrcweir         lcl_DebugMarks(m_vFieldmarks);
472cdf0e10cSrcweir #endif
473cdf0e10cSrcweir         return pMark.get();
474cdf0e10cSrcweir     }
475cdf0e10cSrcweir 
476dec99bbdSOliver-Rainer Wittmann 
makeFieldBookmark(const SwPaM & rPaM,const rtl::OUString & rName,const rtl::OUString & rType)477dec99bbdSOliver-Rainer Wittmann     ::sw::mark::IFieldmark* MarkManager::makeFieldBookmark(
478dec99bbdSOliver-Rainer Wittmann         const SwPaM& rPaM,
479cdf0e10cSrcweir         const rtl::OUString& rName,
480cdf0e10cSrcweir         const rtl::OUString& rType )
481cdf0e10cSrcweir     {
4823b32dd21SOliver-Rainer Wittmann         sw::mark::IMark* pMark =
4833b32dd21SOliver-Rainer Wittmann             makeMark( rPaM, rName, IDocumentMarkAccess::TEXT_FIELDMARK );
484cdf0e10cSrcweir         sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
485cdf0e10cSrcweir         pFieldMark->SetFieldname( rType );
486cdf0e10cSrcweir 
487cdf0e10cSrcweir         return pFieldMark;
488cdf0e10cSrcweir     }
489cdf0e10cSrcweir 
490dec99bbdSOliver-Rainer Wittmann 
makeNoTextFieldBookmark(const SwPaM & rPaM,const rtl::OUString & rName,const rtl::OUString & rType)491dec99bbdSOliver-Rainer Wittmann     ::sw::mark::IFieldmark* MarkManager::makeNoTextFieldBookmark(
492dec99bbdSOliver-Rainer Wittmann         const SwPaM& rPaM,
493cdf0e10cSrcweir         const rtl::OUString& rName,
494cdf0e10cSrcweir         const rtl::OUString& rType)
495cdf0e10cSrcweir     {
496cdf0e10cSrcweir         sw::mark::IMark* pMark = makeMark( rPaM, rName,
497cdf0e10cSrcweir                 IDocumentMarkAccess::CHECKBOX_FIELDMARK );
498cdf0e10cSrcweir         sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
499cdf0e10cSrcweir         pFieldMark->SetFieldname( rType );
500cdf0e10cSrcweir 
501cdf0e10cSrcweir         return pFieldMark;
502cdf0e10cSrcweir     }
503cdf0e10cSrcweir 
504dec99bbdSOliver-Rainer Wittmann 
getMarkForTxtNode(const SwTxtNode & rTxtNode,const IDocumentMarkAccess::MarkType eType)505dec99bbdSOliver-Rainer Wittmann     ::sw::mark::IMark* MarkManager::getMarkForTxtNode(
506dec99bbdSOliver-Rainer Wittmann         const SwTxtNode& rTxtNode,
507cdf0e10cSrcweir         const IDocumentMarkAccess::MarkType eType )
508cdf0e10cSrcweir     {
509cdf0e10cSrcweir         SwPosition aPos(rTxtNode);
510cdf0e10cSrcweir         aPos.nContent.Assign(&(const_cast<SwTxtNode&>(rTxtNode)), 0);
511cdf0e10cSrcweir         const iterator_t ppExistingMark = lcl_FindMarkAtPos(m_vBookmarks, aPos, eType);
512cdf0e10cSrcweir         if(ppExistingMark != m_vBookmarks.end())
513cdf0e10cSrcweir             return ppExistingMark->get();
514cdf0e10cSrcweir         const SwPaM aPaM(aPos);
515cdf0e10cSrcweir         return makeMark(aPaM, ::rtl::OUString(), eType);
516cdf0e10cSrcweir     }
517cdf0e10cSrcweir 
518dec99bbdSOliver-Rainer Wittmann 
makeAnnotationMark(const SwPaM & rPaM,const::rtl::OUString & rName)519dec99bbdSOliver-Rainer Wittmann     sw::mark::IMark* MarkManager::makeAnnotationMark(
520dec99bbdSOliver-Rainer Wittmann         const SwPaM& rPaM,
521dec99bbdSOliver-Rainer Wittmann         const ::rtl::OUString& rName )
522dec99bbdSOliver-Rainer Wittmann     {
523dec99bbdSOliver-Rainer Wittmann         return makeMark( rPaM, rName, IDocumentMarkAccess::ANNOTATIONMARK );
524dec99bbdSOliver-Rainer Wittmann     }
525dec99bbdSOliver-Rainer Wittmann 
repositionMark(::sw::mark::IMark * const io_pMark,const SwPaM & rPaM)526dec99bbdSOliver-Rainer Wittmann     void MarkManager::repositionMark(
527dec99bbdSOliver-Rainer Wittmann         ::sw::mark::IMark* const io_pMark,
528cdf0e10cSrcweir         const SwPaM& rPaM)
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir         OSL_PRECOND(io_pMark->GetMarkPos().GetDoc() == m_pDoc,
531cdf0e10cSrcweir             "<MarkManager::repositionMark(..)>"
532cdf0e10cSrcweir             " - Mark is not in my doc.");
533cdf0e10cSrcweir         MarkBase* const pMarkBase = dynamic_cast< MarkBase* >(io_pMark);
534cdf0e10cSrcweir         pMarkBase->SetMarkPos(*(rPaM.GetPoint()));
535cdf0e10cSrcweir         if(rPaM.HasMark())
536cdf0e10cSrcweir             pMarkBase->SetOtherMarkPos(*(rPaM.GetMark()));
537cdf0e10cSrcweir         else
538cdf0e10cSrcweir             pMarkBase->ClearOtherMarkPos();
539cdf0e10cSrcweir 
540cdf0e10cSrcweir         if(pMarkBase->GetMarkPos() != pMarkBase->GetMarkStart())
541cdf0e10cSrcweir             pMarkBase->Swap();
542cdf0e10cSrcweir 
543cdf0e10cSrcweir         sortMarks();
544cdf0e10cSrcweir     }
545cdf0e10cSrcweir 
546dec99bbdSOliver-Rainer Wittmann 
renameMark(::sw::mark::IMark * io_pMark,const::rtl::OUString & rNewName)547dec99bbdSOliver-Rainer Wittmann     bool MarkManager::renameMark(
548dec99bbdSOliver-Rainer Wittmann         ::sw::mark::IMark* io_pMark,
549dec99bbdSOliver-Rainer Wittmann         const ::rtl::OUString& rNewName )
550cdf0e10cSrcweir     {
551cdf0e10cSrcweir         OSL_PRECOND(io_pMark->GetMarkPos().GetDoc() == m_pDoc,
552cdf0e10cSrcweir             "<MarkManager::repositionMark(..)>"
553cdf0e10cSrcweir             " - Mark is not in my doc.");
554cdf0e10cSrcweir         if ( io_pMark->GetName() == rNewName )
555cdf0e10cSrcweir             return true;
556dec99bbdSOliver-Rainer Wittmann         if ( findMark(rNewName) != m_vAllMarks.end() )
557cdf0e10cSrcweir             return false;
558cdf0e10cSrcweir         dynamic_cast< ::sw::mark::MarkBase* >(io_pMark)->SetName(rNewName);
559cdf0e10cSrcweir         return true;
560cdf0e10cSrcweir     }
561cdf0e10cSrcweir 
562dec99bbdSOliver-Rainer Wittmann 
correctMarksAbsolute(const SwNodeIndex & rOldNode,const SwPosition & rNewPos,const xub_StrLen nOffset)563dec99bbdSOliver-Rainer Wittmann     void MarkManager::correctMarksAbsolute(
564dec99bbdSOliver-Rainer Wittmann         const SwNodeIndex& rOldNode,
565dec99bbdSOliver-Rainer Wittmann         const SwPosition& rNewPos,
566dec99bbdSOliver-Rainer Wittmann         const xub_StrLen nOffset)
567cdf0e10cSrcweir     {
568cdf0e10cSrcweir         const SwNode* const pOldNode = &rOldNode.GetNode();
569cdf0e10cSrcweir         SwPosition aNewPos(rNewPos);
570cdf0e10cSrcweir         aNewPos.nContent += nOffset;
571cdf0e10cSrcweir         bool isSortingNeeded = false;
572dec99bbdSOliver-Rainer Wittmann 
573dec99bbdSOliver-Rainer Wittmann         for(iterator_t ppMark = m_vAllMarks.begin();
574dec99bbdSOliver-Rainer Wittmann             ppMark != m_vAllMarks.end();
575cdf0e10cSrcweir             ppMark++)
576cdf0e10cSrcweir         {
577cdf0e10cSrcweir             ::sw::mark::MarkBase* pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
578dec99bbdSOliver-Rainer Wittmann             // is on position ??
579dec99bbdSOliver-Rainer Wittmann             bool bChangedPos = false;
580cdf0e10cSrcweir             if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
581cdf0e10cSrcweir             {
582cdf0e10cSrcweir                 pMark->SetMarkPos(aNewPos);
583cdf0e10cSrcweir                 bChangedPos = true;
584cdf0e10cSrcweir             }
585dec99bbdSOliver-Rainer Wittmann             bool bChangedOPos = false;
586cdf0e10cSrcweir             if (pMark->IsExpanded() &&
587cdf0e10cSrcweir                 &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
588cdf0e10cSrcweir             {
589cdf0e10cSrcweir                 pMark->SetMarkPos(aNewPos);
590cdf0e10cSrcweir                 bChangedOPos= true;
591cdf0e10cSrcweir             }
592cdf0e10cSrcweir             // illegal selection? collapse the mark and restore sorting later
593cdf0e10cSrcweir             isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
594cdf0e10cSrcweir         }
595dec99bbdSOliver-Rainer Wittmann 
596cdf0e10cSrcweir         // restore sorting if needed
597cdf0e10cSrcweir         if(isSortingNeeded)
598cdf0e10cSrcweir             sortMarks();
599cdf0e10cSrcweir #if 0
600cdf0e10cSrcweir         OSL_TRACE("correctMarksAbsolute");
601dec99bbdSOliver-Rainer Wittmann         lcl_DebugMarks(m_vAllMarks);
602cdf0e10cSrcweir #endif
603cdf0e10cSrcweir     }
604cdf0e10cSrcweir 
605dec99bbdSOliver-Rainer Wittmann 
correctMarksRelative(const SwNodeIndex & rOldNode,const SwPosition & rNewPos,const xub_StrLen nOffset)606cdf0e10cSrcweir     void MarkManager::correctMarksRelative(const SwNodeIndex& rOldNode, const SwPosition& rNewPos, const xub_StrLen nOffset)
607cdf0e10cSrcweir     {
608cdf0e10cSrcweir         const SwNode* const pOldNode = &rOldNode.GetNode();
609cdf0e10cSrcweir         SwPosition aNewPos(rNewPos);
610cdf0e10cSrcweir         aNewPos.nContent += nOffset;
611cdf0e10cSrcweir         bool isSortingNeeded = false;
612dec99bbdSOliver-Rainer Wittmann 
613dec99bbdSOliver-Rainer Wittmann         for(iterator_t ppMark = m_vAllMarks.begin();
614dec99bbdSOliver-Rainer Wittmann             ppMark != m_vAllMarks.end();
615cdf0e10cSrcweir             ppMark++)
616cdf0e10cSrcweir         {
617cdf0e10cSrcweir             // is on position ??
618cdf0e10cSrcweir             bool bChangedPos = false, bChangedOPos = false;
619cdf0e10cSrcweir             ::sw::mark::MarkBase* const pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
620cdf0e10cSrcweir             if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
621cdf0e10cSrcweir             {
622cdf0e10cSrcweir                 SwPosition aNewPosRel(aNewPos);
623cdf0e10cSrcweir                 aNewPosRel.nContent += pMark->GetMarkPos().nContent.GetIndex();
624cdf0e10cSrcweir                 pMark->SetMarkPos(aNewPosRel);
625cdf0e10cSrcweir                 bChangedPos = true;
626cdf0e10cSrcweir             }
627cdf0e10cSrcweir             if(pMark->IsExpanded() &&
628cdf0e10cSrcweir                 &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
629cdf0e10cSrcweir             {
630cdf0e10cSrcweir                 SwPosition aNewPosRel(aNewPos);
631cdf0e10cSrcweir                 aNewPosRel.nContent += pMark->GetOtherMarkPos().nContent.GetIndex();
632cdf0e10cSrcweir                 pMark->SetOtherMarkPos(aNewPosRel);
633cdf0e10cSrcweir                 bChangedOPos = true;
634cdf0e10cSrcweir             }
635cdf0e10cSrcweir             // illegal selection? collapse the mark and restore sorting later
636cdf0e10cSrcweir             isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
637cdf0e10cSrcweir         }
638dec99bbdSOliver-Rainer Wittmann 
639cdf0e10cSrcweir         // restore sorting if needed
640cdf0e10cSrcweir         if(isSortingNeeded)
641cdf0e10cSrcweir             sortMarks();
642cdf0e10cSrcweir #if 0
643cdf0e10cSrcweir         OSL_TRACE("correctMarksRelative");
644dec99bbdSOliver-Rainer Wittmann         lcl_DebugMarks(m_vAllMarks);
645cdf0e10cSrcweir #endif
646cdf0e10cSrcweir     }
647cdf0e10cSrcweir 
648dec99bbdSOliver-Rainer Wittmann 
deleteMarks(const SwNodeIndex & rStt,const SwNodeIndex & rEnd,::std::vector<SaveBookmark> * pSaveBkmk,const SwIndex * pSttIdx,const SwIndex * pEndIdx)649cdf0e10cSrcweir     void MarkManager::deleteMarks(
650cdf0e10cSrcweir             const SwNodeIndex& rStt,
651cdf0e10cSrcweir             const SwNodeIndex& rEnd,
652cdf0e10cSrcweir             ::std::vector<SaveBookmark>* pSaveBkmk,
653cdf0e10cSrcweir             const SwIndex* pSttIdx,
654cdf0e10cSrcweir             const SwIndex* pEndIdx )
655cdf0e10cSrcweir     {
656de5fde26SOliver-Rainer Wittmann         ::std::vector<const_iterator_t> vMarksToDelete;
657de5fde26SOliver-Rainer Wittmann         bool bIsSortingNeeded = false;
658dec99bbdSOliver-Rainer Wittmann 
659fb3f75f2SOliver-Rainer Wittmann         // boolean indicating, if at least one mark has been moved while colleting marks for deletion
660fb3f75f2SOliver-Rainer Wittmann         bool bMarksMoved = false;
661fb3f75f2SOliver-Rainer Wittmann 
662cdf0e10cSrcweir         // copy all bookmarks in the move area to a vector storing all position data as offset
663cdf0e10cSrcweir         // reassignment is performed after the move
664dec99bbdSOliver-Rainer Wittmann         for(iterator_t ppMark = m_vAllMarks.begin();
665dec99bbdSOliver-Rainer Wittmann             ppMark != m_vAllMarks.end();
666cdf0e10cSrcweir             ppMark++)
667cdf0e10cSrcweir         {
668cdf0e10cSrcweir             // navigator marks should not be moved
669cdf0e10cSrcweir             // TODO: Check if this might make them invalid
670cdf0e10cSrcweir             if(IDocumentMarkAccess::GetType(**ppMark) == NAVIGATOR_REMINDER)
671cdf0e10cSrcweir                 continue;
672cdf0e10cSrcweir 
673cdf0e10cSrcweir             ::sw::mark::MarkBase* pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
674cdf0e10cSrcweir             // on position ??
675de5fde26SOliver-Rainer Wittmann             bool bIsPosInRange = lcl_GreaterThan(pMark->GetMarkPos(), rStt, pSttIdx)
676de5fde26SOliver-Rainer Wittmann                                  && lcl_Lower(pMark->GetMarkPos(), rEnd, pEndIdx);
677de5fde26SOliver-Rainer Wittmann             bool bIsOtherPosInRange = pMark->IsExpanded()
678de5fde26SOliver-Rainer Wittmann                                       && lcl_GreaterThan(pMark->GetOtherMarkPos(), rStt, pSttIdx)
679de5fde26SOliver-Rainer Wittmann                                       && lcl_Lower(pMark->GetOtherMarkPos(), rEnd, pEndIdx);
680cdf0e10cSrcweir             // special case: completely in range, touching the end?
681332f371aSOliver-Rainer Wittmann             if ( pEndIdx != NULL
682de5fde26SOliver-Rainer Wittmann                  && ( ( bIsOtherPosInRange
683cdf0e10cSrcweir                         && pMark->GetMarkPos().nNode == rEnd
684cdf0e10cSrcweir                         && pMark->GetMarkPos().nContent == *pEndIdx )
685de5fde26SOliver-Rainer Wittmann                       || ( bIsPosInRange
686cdf0e10cSrcweir                            && pMark->IsExpanded()
687cdf0e10cSrcweir                            && pMark->GetOtherMarkPos().nNode == rEnd
688cdf0e10cSrcweir                            && pMark->GetOtherMarkPos().nContent == *pEndIdx ) ) )
689cdf0e10cSrcweir             {
690de5fde26SOliver-Rainer Wittmann                 bIsPosInRange = true, bIsOtherPosInRange = true;
691cdf0e10cSrcweir             }
692cdf0e10cSrcweir 
693de5fde26SOliver-Rainer Wittmann             if ( bIsPosInRange
694de5fde26SOliver-Rainer Wittmann                  && ( bIsOtherPosInRange
6953b32dd21SOliver-Rainer Wittmann                       || !pMark->IsExpanded() ) )
696cdf0e10cSrcweir             {
697cdf0e10cSrcweir                 // completely in range
698cdf0e10cSrcweir 
699de5fde26SOliver-Rainer Wittmann                 bool bDeleteMark = true;
700cdf0e10cSrcweir                 {
701de5fde26SOliver-Rainer Wittmann                     switch ( IDocumentMarkAccess::GetType( *pMark ) )
702cdf0e10cSrcweir                     {
703de5fde26SOliver-Rainer Wittmann                     case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
704de5fde26SOliver-Rainer Wittmann                     case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
705de5fde26SOliver-Rainer Wittmann                         // no delete of cross-reference bookmarks, if range is inside one paragraph
706de5fde26SOliver-Rainer Wittmann                         bDeleteMark = rStt != rEnd;
707de5fde26SOliver-Rainer Wittmann                         break;
708de5fde26SOliver-Rainer Wittmann                     case IDocumentMarkAccess::UNO_BOOKMARK:
709de5fde26SOliver-Rainer Wittmann                         // no delete of UNO mark, if it is not expanded and only touches the start of the range
710de5fde26SOliver-Rainer Wittmann                         bDeleteMark = bIsOtherPosInRange
711de5fde26SOliver-Rainer Wittmann                                       || pMark->IsExpanded()
712de5fde26SOliver-Rainer Wittmann                                       || pSttIdx == NULL
713de5fde26SOliver-Rainer Wittmann                                       || !( pMark->GetMarkPos().nNode == rStt
714de5fde26SOliver-Rainer Wittmann                                             && pMark->GetMarkPos().nContent == *pSttIdx );
715de5fde26SOliver-Rainer Wittmann                         break;
716de5fde26SOliver-Rainer Wittmann                     default:
717de5fde26SOliver-Rainer Wittmann                         bDeleteMark = true;
718de5fde26SOliver-Rainer Wittmann                         break;
719cdf0e10cSrcweir                     }
720cdf0e10cSrcweir                 }
721de5fde26SOliver-Rainer Wittmann 
722de5fde26SOliver-Rainer Wittmann                 if ( bDeleteMark )
723cdf0e10cSrcweir                 {
724cdf0e10cSrcweir                     if ( pSaveBkmk )
725de5fde26SOliver-Rainer Wittmann                     {
726cdf0e10cSrcweir                         pSaveBkmk->push_back( SaveBookmark( true, true, *pMark, rStt, pSttIdx ) );
727de5fde26SOliver-Rainer Wittmann                     }
728cdf0e10cSrcweir                     vMarksToDelete.push_back(ppMark);
729cdf0e10cSrcweir                 }
730cdf0e10cSrcweir             }
731de5fde26SOliver-Rainer Wittmann             else if ( bIsPosInRange ^ bIsOtherPosInRange )
732cdf0e10cSrcweir             {
733cdf0e10cSrcweir                 // the bookmark is partitially in the range
734cdf0e10cSrcweir                 // move position of that is in the range out of it
735cdf0e10cSrcweir 
736de5fde26SOliver-Rainer Wittmann                 ::std::auto_ptr< SwPosition > pNewPos;
737332f371aSOliver-Rainer Wittmann                 {
738332f371aSOliver-Rainer Wittmann                     if ( pEndIdx != NULL )
739332f371aSOliver-Rainer Wittmann                     {
740de5fde26SOliver-Rainer Wittmann                         pNewPos = ::std::auto_ptr< SwPosition >( new SwPosition( rEnd, *pEndIdx ) );
741332f371aSOliver-Rainer Wittmann                     }
742332f371aSOliver-Rainer Wittmann                     else
743332f371aSOliver-Rainer Wittmann                     {
744fb3f75f2SOliver-Rainer Wittmann                         pNewPos =
745fb3f75f2SOliver-Rainer Wittmann                             lcl_FindExpelPosition( rStt, rEnd, bIsPosInRange ? pMark->GetOtherMarkPos() : pMark->GetMarkPos() );
746332f371aSOliver-Rainer Wittmann                     }
747332f371aSOliver-Rainer Wittmann                 }
748332f371aSOliver-Rainer Wittmann 
749332f371aSOliver-Rainer Wittmann                 bool bMoveMark = true;
750332f371aSOliver-Rainer Wittmann                 {
751332f371aSOliver-Rainer Wittmann                     switch ( IDocumentMarkAccess::GetType( *pMark ) )
752332f371aSOliver-Rainer Wittmann                     {
753332f371aSOliver-Rainer Wittmann                     case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
754332f371aSOliver-Rainer Wittmann                     case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
755332f371aSOliver-Rainer Wittmann                         // no move of cross-reference bookmarks, if move occurs inside a certain node
756332f371aSOliver-Rainer Wittmann                         bMoveMark = pMark->GetMarkPos().nNode != pNewPos->nNode;
757332f371aSOliver-Rainer Wittmann                         break;
758332f371aSOliver-Rainer Wittmann                     case IDocumentMarkAccess::ANNOTATIONMARK:
759332f371aSOliver-Rainer Wittmann                         // no move of annotation marks, if method is called to collect deleted marks
760332f371aSOliver-Rainer Wittmann                         bMoveMark = pSaveBkmk == NULL;
761332f371aSOliver-Rainer Wittmann                         break;
762332f371aSOliver-Rainer Wittmann                     default:
763332f371aSOliver-Rainer Wittmann                         bMoveMark = true;
764332f371aSOliver-Rainer Wittmann                         break;
765332f371aSOliver-Rainer Wittmann                     }
766332f371aSOliver-Rainer Wittmann                 }
767332f371aSOliver-Rainer Wittmann                 if ( bMoveMark )
768cdf0e10cSrcweir                 {
769de5fde26SOliver-Rainer Wittmann                     if ( bIsPosInRange )
770cdf0e10cSrcweir                         pMark->SetMarkPos(*pNewPos);
771cdf0e10cSrcweir                     else
772cdf0e10cSrcweir                         pMark->SetOtherMarkPos(*pNewPos);
773fb3f75f2SOliver-Rainer Wittmann                     bMarksMoved = true;
774cdf0e10cSrcweir 
775cdf0e10cSrcweir                     // illegal selection? collapse the mark and restore sorting later
776de5fde26SOliver-Rainer Wittmann                     bIsSortingNeeded |= lcl_FixCorrectedMark( bIsPosInRange, bIsOtherPosInRange, pMark );
777cdf0e10cSrcweir                 }
778cdf0e10cSrcweir             }
779cdf0e10cSrcweir         }
780cdf0e10cSrcweir 
781fb3f75f2SOliver-Rainer Wittmann         // If needed, sort mark containers containing subsets of the marks in order to assure sorting.
782fb3f75f2SOliver-Rainer Wittmann         // The sorting is critical for the deletion of a mark as it is searched in these container for deletion.
783fb3f75f2SOliver-Rainer Wittmann         if ( vMarksToDelete.size() > 0 && bMarksMoved )
784fb3f75f2SOliver-Rainer Wittmann         {
785fb3f75f2SOliver-Rainer Wittmann             sortSubsetMarks();
786fb3f75f2SOliver-Rainer Wittmann         }
787cdf0e10cSrcweir         // we just remembered the iterators to delete, so we do not need to search
788dec99bbdSOliver-Rainer Wittmann         // for the shared_ptr<> (the entry in m_vAllMarks) again
789cdf0e10cSrcweir         // reverse iteration, since erasing an entry invalidates iterators
790cdf0e10cSrcweir         // behind it (the iterators in vMarksToDelete are sorted)
791de5fde26SOliver-Rainer Wittmann         for ( ::std::vector< const_iterator_t >::reverse_iterator pppMark = vMarksToDelete.rbegin();
792cdf0e10cSrcweir               pppMark != vMarksToDelete.rend();
793fb3f75f2SOliver-Rainer Wittmann               ++pppMark )
794cdf0e10cSrcweir         {
795cdf0e10cSrcweir             deleteMark(*pppMark);
796cdf0e10cSrcweir         }
797fb3f75f2SOliver-Rainer Wittmann 
798de5fde26SOliver-Rainer Wittmann         if ( bIsSortingNeeded )
799fb3f75f2SOliver-Rainer Wittmann         {
800cdf0e10cSrcweir             sortMarks();
801fb3f75f2SOliver-Rainer Wittmann         }
802fb3f75f2SOliver-Rainer Wittmann 
803cdf0e10cSrcweir #if 0
804cdf0e10cSrcweir         OSL_TRACE("deleteMarks");
805dec99bbdSOliver-Rainer Wittmann         lcl_DebugMarks(m_vAllMarks);
806cdf0e10cSrcweir #endif
807cdf0e10cSrcweir     }
808cdf0e10cSrcweir 
809dec99bbdSOliver-Rainer Wittmann 
deleteMark(const const_iterator_t ppMark)810cdf0e10cSrcweir     void MarkManager::deleteMark(const const_iterator_t ppMark)
811cdf0e10cSrcweir     {
812dec99bbdSOliver-Rainer Wittmann         if(ppMark == m_vAllMarks.end()) return;
813cdf0e10cSrcweir 
814cdf0e10cSrcweir         switch(IDocumentMarkAccess::GetType(**ppMark))
815cdf0e10cSrcweir         {
816cdf0e10cSrcweir             case IDocumentMarkAccess::BOOKMARK:
817cdf0e10cSrcweir             case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
818cdf0e10cSrcweir             case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
819cdf0e10cSrcweir                 {
820cdf0e10cSrcweir                     IDocumentMarkAccess::iterator_t ppBookmark = lcl_FindMark(m_vBookmarks, *ppMark);
8215b9fe260SOliver-Rainer Wittmann                     if ( ppBookmark != m_vBookmarks.end() )
8225b9fe260SOliver-Rainer Wittmann                     {
823cdf0e10cSrcweir                         m_vBookmarks.erase(ppBookmark);
8245b9fe260SOliver-Rainer Wittmann                     }
8255b9fe260SOliver-Rainer Wittmann                     else
8265b9fe260SOliver-Rainer Wittmann                     {
8275b9fe260SOliver-Rainer Wittmann                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Bookmark not found in Bookmark container.");
8285b9fe260SOliver-Rainer Wittmann                     }
8295b9fe260SOliver-Rainer Wittmann                 }
830dec99bbdSOliver-Rainer Wittmann                 break;
831dec99bbdSOliver-Rainer Wittmann 
832cdf0e10cSrcweir             case IDocumentMarkAccess::TEXT_FIELDMARK:
833cdf0e10cSrcweir             case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
834cdf0e10cSrcweir                 {
835cdf0e10cSrcweir                     IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark);
8365b9fe260SOliver-Rainer Wittmann                     if ( ppFieldmark != m_vFieldmarks.end() )
8375b9fe260SOliver-Rainer Wittmann                     {
838cdf0e10cSrcweir                         m_vFieldmarks.erase(ppFieldmark);
8395b9fe260SOliver-Rainer Wittmann                     }
8405b9fe260SOliver-Rainer Wittmann                     else
8415b9fe260SOliver-Rainer Wittmann                     {
8425b9fe260SOliver-Rainer Wittmann                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Fieldmark not found in Fieldmark container.");
8435b9fe260SOliver-Rainer Wittmann                     }
8443b32dd21SOliver-Rainer Wittmann 
8453b32dd21SOliver-Rainer Wittmann                     sw::mark::TextFieldmark* pTextFieldmark = dynamic_cast<sw::mark::TextFieldmark*>(ppMark->get());
8463b32dd21SOliver-Rainer Wittmann                     if ( pTextFieldmark )
8473b32dd21SOliver-Rainer Wittmann                     {
8483b32dd21SOliver-Rainer Wittmann                         pTextFieldmark->ReleaseDoc(m_pDoc);
8493b32dd21SOliver-Rainer Wittmann                     }
850dec99bbdSOliver-Rainer Wittmann 
8515b9fe260SOliver-Rainer Wittmann                 }
852dec99bbdSOliver-Rainer Wittmann                 break;
853dec99bbdSOliver-Rainer Wittmann 
854dec99bbdSOliver-Rainer Wittmann             case IDocumentMarkAccess::ANNOTATIONMARK:
855dec99bbdSOliver-Rainer Wittmann                 {
856dec99bbdSOliver-Rainer Wittmann                     IDocumentMarkAccess::iterator_t ppAnnotationMark = lcl_FindMark(m_vAnnotationMarks, *ppMark);
8575b9fe260SOliver-Rainer Wittmann                     if ( ppAnnotationMark != m_vAnnotationMarks.end() )
8585b9fe260SOliver-Rainer Wittmann                     {
859dec99bbdSOliver-Rainer Wittmann                         m_vAnnotationMarks.erase(ppAnnotationMark);
860dec99bbdSOliver-Rainer Wittmann                     }
8615b9fe260SOliver-Rainer Wittmann                     else
8625b9fe260SOliver-Rainer Wittmann                     {
8635b9fe260SOliver-Rainer Wittmann                         OSL_ENSURE( false, "<MarkManager::deleteMark(..)> - Annotation Mark not found in Annotation Mark container.");
8645b9fe260SOliver-Rainer Wittmann                     }
8655b9fe260SOliver-Rainer Wittmann                 }
866dec99bbdSOliver-Rainer Wittmann                 break;
867dec99bbdSOliver-Rainer Wittmann 
868cdf0e10cSrcweir             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
869cdf0e10cSrcweir             case IDocumentMarkAccess::DDE_BOOKMARK:
870cdf0e10cSrcweir             case IDocumentMarkAccess::UNO_BOOKMARK:
871*12ad4c42SOliver-Rainer Wittmann                 // no special marks container
872cdf0e10cSrcweir                 break;
873cdf0e10cSrcweir         }
874cdf0e10cSrcweir         DdeBookmark* const pDdeBookmark = dynamic_cast<DdeBookmark*>(ppMark->get());
875cdf0e10cSrcweir         if ( pDdeBookmark )
876b0b7a757SOliver-Rainer Wittmann         {
877cdf0e10cSrcweir             pDdeBookmark->DeregisterFromDoc(m_pDoc);
878b0b7a757SOliver-Rainer Wittmann         }
879b0b7a757SOliver-Rainer Wittmann         // keep a temporary instance of the to-be-deleted mark in order to avoid
880b0b7a757SOliver-Rainer Wittmann         // recursive deletion of the mark triggered via its destructor.
881b0b7a757SOliver-Rainer Wittmann         // the temporary hold instance assures that the mark is deleted after the
882b0b7a757SOliver-Rainer Wittmann         // mark container has been updated. Thus, the mark could not be found anymore
883b0b7a757SOliver-Rainer Wittmann         // in the mark container by other calls trying to recursively delete the mark.
884dec99bbdSOliver-Rainer Wittmann         iterator_t aToBeDeletedMarkIter = m_vAllMarks.begin() + (ppMark - m_vAllMarks.begin());
885b0b7a757SOliver-Rainer Wittmann         pMark_t pToBeDeletedMark = *aToBeDeletedMarkIter;
886dec99bbdSOliver-Rainer Wittmann         m_vAllMarks.erase( aToBeDeletedMarkIter );
887cdf0e10cSrcweir     }
888cdf0e10cSrcweir 
deleteMark(const IMark * const pMark)889cdf0e10cSrcweir     void MarkManager::deleteMark(const IMark* const pMark)
890cdf0e10cSrcweir     {
891cdf0e10cSrcweir         OSL_PRECOND(pMark->GetMarkPos().GetDoc() == m_pDoc,
892cdf0e10cSrcweir             "<MarkManager::repositionMark(..)>"
893cdf0e10cSrcweir             " - Mark is not in my doc.");
894cdf0e10cSrcweir         // finds the last Mark that is starting before pMark
895cdf0e10cSrcweir         // (pMarkLow < pMark)
896dec99bbdSOliver-Rainer Wittmann         iterator_t pMarkLow =
897dec99bbdSOliver-Rainer Wittmann             lower_bound(
898dec99bbdSOliver-Rainer Wittmann                 m_vAllMarks.begin(),
899dec99bbdSOliver-Rainer Wittmann                 m_vAllMarks.end(),
900cdf0e10cSrcweir                 pMark->GetMarkStart(),
901cdf0e10cSrcweir                 bind(&IMark::StartsBefore, _1, _2) );
902dec99bbdSOliver-Rainer Wittmann         iterator_t pMarkHigh = m_vAllMarks.end();
903dec99bbdSOliver-Rainer Wittmann         iterator_t pMarkFound =
904dec99bbdSOliver-Rainer Wittmann             find_if(
905dec99bbdSOliver-Rainer Wittmann                 pMarkLow,
906dec99bbdSOliver-Rainer Wittmann                 pMarkHigh,
907de5fde26SOliver-Rainer Wittmann                 boost::bind( ::std::equal_to<const IMark*>(), bind(&boost::shared_ptr<IMark>::get, _1), pMark ) );
908cdf0e10cSrcweir         if(pMarkFound != pMarkHigh)
909cdf0e10cSrcweir             deleteMark(pMarkFound);
910cdf0e10cSrcweir     }
911cdf0e10cSrcweir 
clearAllMarks()912cdf0e10cSrcweir     void MarkManager::clearAllMarks()
913cdf0e10cSrcweir     {
914cdf0e10cSrcweir         m_vFieldmarks.clear();
915cdf0e10cSrcweir         m_vBookmarks.clear();
916dec99bbdSOliver-Rainer Wittmann 
917dec99bbdSOliver-Rainer Wittmann         m_vAnnotationMarks.clear();
918dec99bbdSOliver-Rainer Wittmann 
919cdf0e10cSrcweir #ifdef DEBUG
920dec99bbdSOliver-Rainer Wittmann         for(iterator_t pBkmk = m_vAllMarks.begin();
921dec99bbdSOliver-Rainer Wittmann             pBkmk != m_vAllMarks.end();
922cdf0e10cSrcweir             ++pBkmk)
923cdf0e10cSrcweir             OSL_ENSURE( pBkmk->unique(),
924dec99bbdSOliver-Rainer Wittmann                         "<MarkManager::clearAllMarks(..)> - a Bookmark is still in use.");
925cdf0e10cSrcweir #endif
926dec99bbdSOliver-Rainer Wittmann         m_vAllMarks.clear();
927cdf0e10cSrcweir     }
928cdf0e10cSrcweir 
findMark(const::rtl::OUString & rName) const929cdf0e10cSrcweir     IDocumentMarkAccess::const_iterator_t MarkManager::findMark(const ::rtl::OUString& rName) const
930cdf0e10cSrcweir     {
931dec99bbdSOliver-Rainer Wittmann         return lcl_FindMarkByName(rName, m_vAllMarks.begin(), m_vAllMarks.end());
932cdf0e10cSrcweir     }
933cdf0e10cSrcweir 
findBookmark(const::rtl::OUString & rName) const934cdf0e10cSrcweir     IDocumentMarkAccess::const_iterator_t MarkManager::findBookmark(const ::rtl::OUString& rName) const
935cdf0e10cSrcweir     {
936cdf0e10cSrcweir         return lcl_FindMarkByName(rName, m_vBookmarks.begin(), m_vBookmarks.end());
937cdf0e10cSrcweir     }
938cdf0e10cSrcweir 
getAllMarksBegin() const939dec99bbdSOliver-Rainer Wittmann     IDocumentMarkAccess::const_iterator_t MarkManager::getAllMarksBegin() const
940dec99bbdSOliver-Rainer Wittmann         { return m_vAllMarks.begin(); }
941cdf0e10cSrcweir 
getAllMarksEnd() const942dec99bbdSOliver-Rainer Wittmann     IDocumentMarkAccess::const_iterator_t MarkManager::getAllMarksEnd() const
943dec99bbdSOliver-Rainer Wittmann         { return m_vAllMarks.end(); }
944cdf0e10cSrcweir 
getAllMarksCount() const945dec99bbdSOliver-Rainer Wittmann     sal_Int32 MarkManager::getAllMarksCount() const
946dec99bbdSOliver-Rainer Wittmann         { return m_vAllMarks.size(); }
947cdf0e10cSrcweir 
getBookmarksBegin() const948cdf0e10cSrcweir     IDocumentMarkAccess::const_iterator_t MarkManager::getBookmarksBegin() const
949cdf0e10cSrcweir         { return m_vBookmarks.begin(); }
950cdf0e10cSrcweir 
getBookmarksEnd() const951cdf0e10cSrcweir     IDocumentMarkAccess::const_iterator_t MarkManager::getBookmarksEnd() const
952cdf0e10cSrcweir         { return m_vBookmarks.end(); }
953cdf0e10cSrcweir 
getBookmarksCount() const954cdf0e10cSrcweir     sal_Int32 MarkManager::getBookmarksCount() const
955cdf0e10cSrcweir         { return m_vBookmarks.size(); }
956cdf0e10cSrcweir 
getFieldmarkFor(const SwPosition & rPos) const957cdf0e10cSrcweir     IFieldmark* MarkManager::getFieldmarkFor(const SwPosition& rPos) const
958cdf0e10cSrcweir     {
959cdf0e10cSrcweir         const_iterator_t pFieldmark = find_if(
960cdf0e10cSrcweir             m_vFieldmarks.begin(),
961cdf0e10cSrcweir             m_vFieldmarks.end( ),
962cdf0e10cSrcweir             bind(&IMark::IsCoveringPosition, _1, rPos));
963cdf0e10cSrcweir         if(pFieldmark == m_vFieldmarks.end()) return NULL;
964cdf0e10cSrcweir         return dynamic_cast<IFieldmark*>(pFieldmark->get());
965cdf0e10cSrcweir     }
966cdf0e10cSrcweir 
getFieldmarkAfter(const SwPosition & rPos) const967cdf0e10cSrcweir     IFieldmark* MarkManager::getFieldmarkAfter(const SwPosition& rPos) const
968cdf0e10cSrcweir         { return dynamic_cast<IFieldmark*>(lcl_getMarkAfter(m_vFieldmarks, rPos)); }
969cdf0e10cSrcweir 
getFieldmarkBefore(const SwPosition & rPos) const970cdf0e10cSrcweir     IFieldmark* MarkManager::getFieldmarkBefore(const SwPosition& rPos) const
971cdf0e10cSrcweir         { return dynamic_cast<IFieldmark*>(lcl_getMarkBefore(m_vFieldmarks, rPos)); }
972cdf0e10cSrcweir 
973dec99bbdSOliver-Rainer Wittmann 
getAnnotationMarksBegin() const974dec99bbdSOliver-Rainer Wittmann     IDocumentMarkAccess::const_iterator_t MarkManager::getAnnotationMarksBegin() const
975dec99bbdSOliver-Rainer Wittmann     {
976dec99bbdSOliver-Rainer Wittmann         return m_vAnnotationMarks.begin();
977dec99bbdSOliver-Rainer Wittmann     }
978dec99bbdSOliver-Rainer Wittmann 
getAnnotationMarksEnd() const979dec99bbdSOliver-Rainer Wittmann     IDocumentMarkAccess::const_iterator_t MarkManager::getAnnotationMarksEnd() const
980dec99bbdSOliver-Rainer Wittmann     {
981dec99bbdSOliver-Rainer Wittmann         return m_vAnnotationMarks.end();
982dec99bbdSOliver-Rainer Wittmann     }
983dec99bbdSOliver-Rainer Wittmann 
getAnnotationMarksCount() const984dec99bbdSOliver-Rainer Wittmann     sal_Int32 MarkManager::getAnnotationMarksCount() const
985dec99bbdSOliver-Rainer Wittmann     {
986dec99bbdSOliver-Rainer Wittmann         return m_vAnnotationMarks.size();
987dec99bbdSOliver-Rainer Wittmann     }
988dec99bbdSOliver-Rainer Wittmann 
findAnnotationMark(const::rtl::OUString & rName) const989dec99bbdSOliver-Rainer Wittmann     IDocumentMarkAccess::const_iterator_t MarkManager::findAnnotationMark( const ::rtl::OUString& rName ) const
990dec99bbdSOliver-Rainer Wittmann     {
991dec99bbdSOliver-Rainer Wittmann         return lcl_FindMarkByName( rName, m_vAnnotationMarks.begin(), m_vAnnotationMarks.end() );
992dec99bbdSOliver-Rainer Wittmann     }
993dec99bbdSOliver-Rainer Wittmann 
994dec99bbdSOliver-Rainer Wittmann 
getUniqueMarkName(const::rtl::OUString & rName) const995cdf0e10cSrcweir     ::rtl::OUString MarkManager::getUniqueMarkName(const ::rtl::OUString& rName) const
996cdf0e10cSrcweir     {
997cdf0e10cSrcweir         OSL_ENSURE(rName.getLength(),
998dec99bbdSOliver-Rainer Wittmann             "<MarkManager::getUniqueMarkName(..)> - a name should be proposed");
999dec99bbdSOliver-Rainer Wittmann         if ( findMark(rName) == getAllMarksEnd() )
1000dec99bbdSOliver-Rainer Wittmann         {
1001dec99bbdSOliver-Rainer Wittmann             return rName;
1002dec99bbdSOliver-Rainer Wittmann         }
1003dec99bbdSOliver-Rainer Wittmann 
1004cdf0e10cSrcweir         ::rtl::OUStringBuffer sBuf;
1005cdf0e10cSrcweir         ::rtl::OUString sTmp;
1006cdf0e10cSrcweir         for(sal_Int32 nCnt = 1; nCnt < SAL_MAX_INT32; nCnt++)
1007cdf0e10cSrcweir         {
1008cdf0e10cSrcweir             sTmp = sBuf.append(rName).append(nCnt).makeStringAndClear();
1009dec99bbdSOliver-Rainer Wittmann             if ( findMark(sTmp) == getAllMarksEnd() )
1010dec99bbdSOliver-Rainer Wittmann             {
1011dec99bbdSOliver-Rainer Wittmann                 break;
1012dec99bbdSOliver-Rainer Wittmann             }
1013cdf0e10cSrcweir         }
1014cdf0e10cSrcweir         return sTmp;
1015cdf0e10cSrcweir     }
1016cdf0e10cSrcweir 
assureSortedMarkContainers() const10175b9fe260SOliver-Rainer Wittmann     void MarkManager::assureSortedMarkContainers() const
10185b9fe260SOliver-Rainer Wittmann     {
10195b9fe260SOliver-Rainer Wittmann         const_cast< MarkManager* >(this)->sortMarks();
10205b9fe260SOliver-Rainer Wittmann     }
10215b9fe260SOliver-Rainer Wittmann 
sortSubsetMarks()1022fb3f75f2SOliver-Rainer Wittmann     void MarkManager::sortSubsetMarks()
1023cdf0e10cSrcweir     {
1024cdf0e10cSrcweir         sort(m_vBookmarks.begin(), m_vBookmarks.end(), &lcl_MarkOrderingByStart);
1025cdf0e10cSrcweir         sort(m_vFieldmarks.begin(), m_vFieldmarks.end(), &lcl_MarkOrderingByStart);
1026dec99bbdSOliver-Rainer Wittmann         sort(m_vAnnotationMarks.begin(), m_vAnnotationMarks.end(), &lcl_MarkOrderingByStart);
1027cdf0e10cSrcweir     }
1028cdf0e10cSrcweir 
sortMarks()1029fb3f75f2SOliver-Rainer Wittmann     void MarkManager::sortMarks()
1030fb3f75f2SOliver-Rainer Wittmann     {
1031fb3f75f2SOliver-Rainer Wittmann         sort(m_vAllMarks.begin(), m_vAllMarks.end(), &lcl_MarkOrderingByStart);
1032fb3f75f2SOliver-Rainer Wittmann         sortSubsetMarks();
1033fb3f75f2SOliver-Rainer Wittmann     }
1034fb3f75f2SOliver-Rainer Wittmann 
1035dec99bbdSOliver-Rainer Wittmann #if OSL_DEBUG_LEVEL > 1
dumpFieldmarks() const1036dec99bbdSOliver-Rainer Wittmann     void MarkManager::dumpFieldmarks( ) const
1037dec99bbdSOliver-Rainer Wittmann     {
1038dec99bbdSOliver-Rainer Wittmann         const_iterator_t pIt = m_vFieldmarks.begin();
1039dec99bbdSOliver-Rainer Wittmann         for (; pIt != m_vFieldmarks.end( ); pIt++)
1040dec99bbdSOliver-Rainer Wittmann         {
1041dec99bbdSOliver-Rainer Wittmann             rtl::OUString str = (*pIt)->ToString();
1042dec99bbdSOliver-Rainer Wittmann             OSL_TRACE("%s\n",
1043dec99bbdSOliver-Rainer Wittmann                 ::rtl::OUStringToOString(str, RTL_TEXTENCODING_UTF8).getStr());
1044dec99bbdSOliver-Rainer Wittmann         }
1045dec99bbdSOliver-Rainer Wittmann     }
1046dec99bbdSOliver-Rainer Wittmann #endif
1047dec99bbdSOliver-Rainer Wittmann 
1048cdf0e10cSrcweir }} // namespace ::sw::mark
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir 
1051cdf0e10cSrcweir // old implementation
1052cdf0e10cSrcweir 
1053cdf0e10cSrcweir //SV_IMPL_OP_PTRARR_SORT(SwBookmarks, SwBookmarkPtr)
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir #define PCURCRSR (_pCurrCrsr)
1056cdf0e10cSrcweir #define FOREACHPAM_START(pSttCrsr) \
1057cdf0e10cSrcweir 	{\
1058cdf0e10cSrcweir 		SwPaM *_pStartCrsr = pSttCrsr, *_pCurrCrsr = pSttCrsr; \
1059cdf0e10cSrcweir 		do {
1060cdf0e10cSrcweir 
1061cdf0e10cSrcweir #define FOREACHPAM_END() \
1062cdf0e10cSrcweir 		} while( (_pCurrCrsr=(SwPaM *)_pCurrCrsr->GetNext()) != _pStartCrsr ); \
1063cdf0e10cSrcweir 	}
1064cdf0e10cSrcweir #define PCURSH ((SwCrsrShell*)_pStartShell)
1065cdf0e10cSrcweir #define FOREACHSHELL_START( pEShell ) \
1066cdf0e10cSrcweir     {\
1067cdf0e10cSrcweir 		ViewShell *_pStartShell = pEShell; \
1068cdf0e10cSrcweir 		do { \
1069cdf0e10cSrcweir 			if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) \
1070cdf0e10cSrcweir 			{
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir #define FOREACHSHELL_END( pEShell ) \
1073cdf0e10cSrcweir 			} \
1074cdf0e10cSrcweir         } while((_pStartShell=(ViewShell*)_pStartShell->GetNext())!= pEShell ); \
1075cdf0e10cSrcweir 	}
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir namespace
1078cdf0e10cSrcweir {
1079cdf0e10cSrcweir     // Aufbau vom Array: 2 longs,
1080cdf0e10cSrcweir     //	1. Long enthaelt Type und Position im DocArray,
1081cdf0e10cSrcweir     //	2. die ContentPosition
1082cdf0e10cSrcweir     //
1083cdf0e10cSrcweir     //	CntntType --
1084cdf0e10cSrcweir     //			0x8000 = Bookmark Pos1
1085cdf0e10cSrcweir     //			0x8001 = Bookmark Pos2
1086cdf0e10cSrcweir     //			0x2000 = Absatzgebundener Rahmen
1087cdf0e10cSrcweir     //			0x2001 = Auto-Absatzgebundener Rahmen, der umgehaengt werden soll
1088cdf0e10cSrcweir     //			0x1000 = Redline Mark
1089cdf0e10cSrcweir     //			0x1001 = Redline Point
1090cdf0e10cSrcweir     //			0x0800 = Crsr aus der CrsrShell Mark
1091cdf0e10cSrcweir     //			0x0801 = Crsr aus der CrsrShell Point
1092cdf0e10cSrcweir     //			0x0400 = UnoCrsr Mark
1093cdf0e10cSrcweir     //			0x0401 = UnoCrsr Point
1094cdf0e10cSrcweir     //
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir     class _SwSaveTypeCountContent
1097cdf0e10cSrcweir     {
1098cdf0e10cSrcweir         union {
1099cdf0e10cSrcweir             struct { sal_uInt16 nType, nCount; } TC;
1100cdf0e10cSrcweir             sal_uLong nTypeCount;
1101cdf0e10cSrcweir             } TYPECOUNT;
1102cdf0e10cSrcweir         xub_StrLen nContent;
1103cdf0e10cSrcweir 
1104cdf0e10cSrcweir     public:
_SwSaveTypeCountContent()1105cdf0e10cSrcweir         _SwSaveTypeCountContent() { TYPECOUNT.nTypeCount = 0; nContent = 0; }
_SwSaveTypeCountContent(sal_uInt16 nType)1106cdf0e10cSrcweir         _SwSaveTypeCountContent( sal_uInt16 nType )
1107cdf0e10cSrcweir             {
1108cdf0e10cSrcweir                 SetTypeAndCount( nType, 0 );
1109cdf0e10cSrcweir                 nContent = 0;
1110cdf0e10cSrcweir             }
_SwSaveTypeCountContent(const SvULongs & rArr,sal_uInt16 & rPos)1111cdf0e10cSrcweir         _SwSaveTypeCountContent( const SvULongs& rArr, sal_uInt16& rPos )
1112cdf0e10cSrcweir             {
1113cdf0e10cSrcweir                 TYPECOUNT.nTypeCount = rArr[ rPos++ ];
1114cdf0e10cSrcweir                 nContent = static_cast<xub_StrLen>(rArr[ rPos++ ]);
1115cdf0e10cSrcweir             }
Add(SvULongs & rArr)1116cdf0e10cSrcweir         void Add( SvULongs& rArr )
1117cdf0e10cSrcweir         {
1118cdf0e10cSrcweir             rArr.Insert( TYPECOUNT.nTypeCount, rArr.Count() );
1119cdf0e10cSrcweir             rArr.Insert( nContent, rArr.Count() );
1120cdf0e10cSrcweir         }
1121cdf0e10cSrcweir 
SetType(sal_uInt16 n)1122cdf0e10cSrcweir         void SetType( sal_uInt16 n )		{ TYPECOUNT.TC.nType = n; }
GetType() const1123cdf0e10cSrcweir         sal_uInt16 GetType() const 			{ return TYPECOUNT.TC.nType; }
IncType()1124cdf0e10cSrcweir         void IncType() 	 				{ ++TYPECOUNT.TC.nType; }
DecType()1125cdf0e10cSrcweir         void DecType() 	 				{ --TYPECOUNT.TC.nType; }
1126cdf0e10cSrcweir 
SetCount(sal_uInt16 n)1127cdf0e10cSrcweir         void SetCount( sal_uInt16 n ) 		{ TYPECOUNT.TC.nCount = n; }
GetCount() const1128cdf0e10cSrcweir         sal_uInt16 GetCount() const 		{ return TYPECOUNT.TC.nCount; }
IncCount()1129cdf0e10cSrcweir         sal_uInt16 IncCount()  				{ return ++TYPECOUNT.TC.nCount; }
DecCount()1130cdf0e10cSrcweir         sal_uInt16 DecCount()  				{ return --TYPECOUNT.TC.nCount; }
1131cdf0e10cSrcweir 
SetTypeAndCount(sal_uInt16 nT,sal_uInt16 nC)1132cdf0e10cSrcweir         void SetTypeAndCount( sal_uInt16 nT, sal_uInt16 nC )
1133cdf0e10cSrcweir             { TYPECOUNT.TC.nCount = nC; TYPECOUNT.TC.nType = nT; }
1134cdf0e10cSrcweir 
SetContent(xub_StrLen n)1135cdf0e10cSrcweir         void SetContent( xub_StrLen n )		{ nContent = n; }
GetContent() const1136cdf0e10cSrcweir         xub_StrLen GetContent() const		{ return nContent; }
1137cdf0e10cSrcweir     };
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir     // #i59534: If a paragraph will be splitted we have to restore some redline positions
1140cdf0e10cSrcweir     // This help function checks a position compared with a node and an content index
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir     static const int BEFORE_NODE = 0;          // Position before the given node index
1143cdf0e10cSrcweir     static const int BEFORE_SAME_NODE = 1;     // Same node index but content index before given content index
1144cdf0e10cSrcweir     static const int SAME_POSITION = 2;        // Same node index and samecontent index
1145cdf0e10cSrcweir     static const int BEHIND_SAME_NODE = 3;     // Same node index but content index behind given content index
1146cdf0e10cSrcweir     static const int BEHIND_NODE = 4;          // Position behind the given node index
1147cdf0e10cSrcweir 
lcl_RelativePosition(const SwPosition & rPos,sal_uLong nNode,xub_StrLen nCntnt)1148cdf0e10cSrcweir     static int lcl_RelativePosition( const SwPosition& rPos, sal_uLong nNode, xub_StrLen nCntnt )
1149cdf0e10cSrcweir     {
1150cdf0e10cSrcweir         sal_uLong nIndex = rPos.nNode.GetIndex();
1151cdf0e10cSrcweir         int nReturn = BEFORE_NODE;
1152cdf0e10cSrcweir         if( nIndex == nNode )
1153cdf0e10cSrcweir         {
1154cdf0e10cSrcweir             xub_StrLen nCntIdx = rPos.nContent.GetIndex();
1155cdf0e10cSrcweir             if( nCntIdx < nCntnt )
1156cdf0e10cSrcweir                 nReturn = BEFORE_SAME_NODE;
1157cdf0e10cSrcweir             else if( nCntIdx == nCntnt )
1158cdf0e10cSrcweir                 nReturn = SAME_POSITION;
1159cdf0e10cSrcweir             else
1160cdf0e10cSrcweir                 nReturn = BEHIND_SAME_NODE;
1161cdf0e10cSrcweir         }
1162cdf0e10cSrcweir         else if( nIndex > nNode )
1163cdf0e10cSrcweir             nReturn = BEHIND_NODE;
1164cdf0e10cSrcweir         return nReturn;
1165cdf0e10cSrcweir     }
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir 
lcl_Greater(const SwPosition & rPos,const SwNodeIndex & rNdIdx,const SwIndex * pIdx)1168cdf0e10cSrcweir     static inline int lcl_Greater( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
1169cdf0e10cSrcweir     {
1170cdf0e10cSrcweir         return rPos.nNode > rNdIdx || ( pIdx && rPos.nNode == rNdIdx && rPos.nContent > pIdx->GetIndex() );
1171cdf0e10cSrcweir     }
1172cdf0e10cSrcweir 
lcl_ChkPaM(SvULongs & rSaveArr,sal_uLong nNode,xub_StrLen nCntnt,const SwPaM & rPam,_SwSaveTypeCountContent & rSave,sal_Bool bChkSelDirection)1173cdf0e10cSrcweir     static void lcl_ChkPaM( SvULongs& rSaveArr, sal_uLong nNode, xub_StrLen nCntnt,
1174cdf0e10cSrcweir                     const SwPaM& rPam, _SwSaveTypeCountContent& rSave,
1175cdf0e10cSrcweir                     sal_Bool bChkSelDirection )
1176cdf0e10cSrcweir     {
1177cdf0e10cSrcweir         // SelektionsRichtung beachten
1178cdf0e10cSrcweir         bool bBound1IsStart = !bChkSelDirection ? sal_True :
1179cdf0e10cSrcweir                             ( *rPam.GetPoint() < *rPam.GetMark()
1180cdf0e10cSrcweir                                 ? rPam.GetPoint() == &rPam.GetBound()
1181cdf0e10cSrcweir                                 : rPam.GetMark() == &rPam.GetBound());
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir         const SwPosition* pPos = &rPam.GetBound( sal_True );
1184cdf0e10cSrcweir         if( pPos->nNode.GetIndex() == nNode &&
1185cdf0e10cSrcweir             ( bBound1IsStart ? pPos->nContent.GetIndex() < nCntnt
1186cdf0e10cSrcweir                                 : pPos->nContent.GetIndex() <= nCntnt ))
1187cdf0e10cSrcweir         {
1188cdf0e10cSrcweir             rSave.SetContent( pPos->nContent.GetIndex() );
1189cdf0e10cSrcweir             rSave.Add( rSaveArr );
1190cdf0e10cSrcweir         }
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir         pPos = &rPam.GetBound( sal_False );
1193cdf0e10cSrcweir         if( pPos->nNode.GetIndex() == nNode &&
1194cdf0e10cSrcweir             ( (bBound1IsStart && bChkSelDirection)
1195cdf0e10cSrcweir                         ? pPos->nContent.GetIndex() <= nCntnt
1196cdf0e10cSrcweir                         : pPos->nContent.GetIndex() < nCntnt ))
1197cdf0e10cSrcweir         {
1198cdf0e10cSrcweir             rSave.SetContent( pPos->nContent.GetIndex() );
1199cdf0e10cSrcweir             rSave.IncType();
1200cdf0e10cSrcweir             rSave.Add( rSaveArr );
1201cdf0e10cSrcweir             rSave.DecType();
1202cdf0e10cSrcweir         }
1203cdf0e10cSrcweir     }
1204cdf0e10cSrcweir 
1205cdf0e10cSrcweir }
1206cdf0e10cSrcweir 
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir // IDocumentMarkAccess for SwDoc
1209cdf0e10cSrcweir 
getIDocumentMarkAccess()1210cdf0e10cSrcweir IDocumentMarkAccess* SwDoc::getIDocumentMarkAccess()
1211cdf0e10cSrcweir     { return static_cast< IDocumentMarkAccess* >(pMarkManager.get()); }
1212cdf0e10cSrcweir 
getIDocumentMarkAccess() const1213cdf0e10cSrcweir const IDocumentMarkAccess* SwDoc::getIDocumentMarkAccess() const
1214cdf0e10cSrcweir     { return static_cast< IDocumentMarkAccess* >(pMarkManager.get()); }
1215cdf0e10cSrcweir 
1216cdf0e10cSrcweir // SaveBookmark
1217cdf0e10cSrcweir 
SaveBookmark(bool bSavePos,bool bSaveOtherPos,const IMark & rBkmk,const SwNodeIndex & rMvPos,const SwIndex * pIdx)1218cdf0e10cSrcweir SaveBookmark::SaveBookmark(
1219cdf0e10cSrcweir     bool bSavePos,
1220cdf0e10cSrcweir     bool bSaveOtherPos,
1221cdf0e10cSrcweir     const IMark& rBkmk,
1222cdf0e10cSrcweir     const SwNodeIndex & rMvPos,
1223cdf0e10cSrcweir     const SwIndex* pIdx)
1224cdf0e10cSrcweir     : m_aName(rBkmk.GetName())
1225cdf0e10cSrcweir     , m_aShortName()
1226cdf0e10cSrcweir     , m_aCode()
1227cdf0e10cSrcweir     , m_bSavePos(bSavePos)
1228cdf0e10cSrcweir     , m_bSaveOtherPos(bSaveOtherPos)
1229cdf0e10cSrcweir     , m_eOrigBkmType(IDocumentMarkAccess::GetType(rBkmk))
1230cdf0e10cSrcweir {
1231cdf0e10cSrcweir     const IBookmark* const pBookmark = dynamic_cast< const IBookmark* >(&rBkmk);
1232cdf0e10cSrcweir     if(pBookmark)
1233cdf0e10cSrcweir     {
1234cdf0e10cSrcweir         m_aShortName = pBookmark->GetShortName();
1235cdf0e10cSrcweir         m_aCode = pBookmark->GetKeyCode();
1236cdf0e10cSrcweir 
1237cdf0e10cSrcweir         ::sfx2::Metadatable const*const pMetadatable(
1238cdf0e10cSrcweir                 dynamic_cast< ::sfx2::Metadatable const* >(pBookmark));
1239cdf0e10cSrcweir         if (pMetadatable)
1240cdf0e10cSrcweir         {
1241cdf0e10cSrcweir             m_pMetadataUndo = pMetadatable->CreateUndo();
1242cdf0e10cSrcweir         }
1243cdf0e10cSrcweir     }
1244cdf0e10cSrcweir     m_nNode1 = rBkmk.GetMarkPos().nNode.GetIndex();
1245cdf0e10cSrcweir     m_nCntnt1 = rBkmk.GetMarkPos().nContent.GetIndex();
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir     if(m_bSavePos)
1248cdf0e10cSrcweir     {
1249cdf0e10cSrcweir         m_nNode1 -= rMvPos.GetIndex();
1250cdf0e10cSrcweir         if(pIdx && !m_nNode1)
1251cdf0e10cSrcweir             m_nCntnt1 -= pIdx->GetIndex();
1252cdf0e10cSrcweir     }
1253cdf0e10cSrcweir 
1254cdf0e10cSrcweir     if(rBkmk.IsExpanded())
1255cdf0e10cSrcweir     {
1256cdf0e10cSrcweir         m_nNode2 = rBkmk.GetOtherMarkPos().nNode.GetIndex();
1257cdf0e10cSrcweir         m_nCntnt2 = rBkmk.GetOtherMarkPos().nContent.GetIndex();
1258cdf0e10cSrcweir 
1259cdf0e10cSrcweir         if(m_bSaveOtherPos)
1260cdf0e10cSrcweir         {
1261cdf0e10cSrcweir             m_nNode2 -= rMvPos.GetIndex();
1262cdf0e10cSrcweir             if(pIdx && !m_nNode2)
1263cdf0e10cSrcweir                 m_nCntnt2 -= pIdx->GetIndex();
1264cdf0e10cSrcweir         }
1265cdf0e10cSrcweir     }
1266cdf0e10cSrcweir     else
1267cdf0e10cSrcweir         m_nNode2 = ULONG_MAX, m_nCntnt2 = STRING_NOTFOUND;
1268cdf0e10cSrcweir }
1269cdf0e10cSrcweir 
SetInDoc(SwDoc * pDoc,const SwNodeIndex & rNewPos,const SwIndex * pIdx)1270cdf0e10cSrcweir void SaveBookmark::SetInDoc(
1271cdf0e10cSrcweir     SwDoc* pDoc,
1272cdf0e10cSrcweir     const SwNodeIndex& rNewPos,
1273cdf0e10cSrcweir     const SwIndex* pIdx)
1274cdf0e10cSrcweir {
1275cdf0e10cSrcweir     SwPaM aPam(rNewPos.GetNode());
1276cdf0e10cSrcweir     if(pIdx)
1277cdf0e10cSrcweir         aPam.GetPoint()->nContent = *pIdx;
1278cdf0e10cSrcweir 
1279cdf0e10cSrcweir     if(ULONG_MAX != m_nNode2)
1280cdf0e10cSrcweir     {
1281cdf0e10cSrcweir         aPam.SetMark();
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir         if(m_bSaveOtherPos)
1284cdf0e10cSrcweir         {
1285cdf0e10cSrcweir             aPam.GetMark()->nNode += m_nNode2;
1286cdf0e10cSrcweir             if(pIdx && !m_nNode2)
1287cdf0e10cSrcweir                 aPam.GetMark()->nContent += m_nCntnt2;
1288cdf0e10cSrcweir             else
1289cdf0e10cSrcweir                 aPam.GetMark()->nContent.Assign(aPam.GetCntntNode(sal_False), m_nCntnt2);
1290cdf0e10cSrcweir         }
1291cdf0e10cSrcweir         else
1292cdf0e10cSrcweir         {
1293cdf0e10cSrcweir             aPam.GetMark()->nNode = m_nNode2;
1294cdf0e10cSrcweir             aPam.GetMark()->nContent.Assign(aPam.GetCntntNode(sal_False), m_nCntnt2);
1295cdf0e10cSrcweir         }
1296cdf0e10cSrcweir     }
1297cdf0e10cSrcweir 
1298cdf0e10cSrcweir     if(m_bSavePos)
1299cdf0e10cSrcweir     {
1300cdf0e10cSrcweir         aPam.GetPoint()->nNode += m_nNode1;
1301cdf0e10cSrcweir 
1302cdf0e10cSrcweir         if(pIdx && !m_nNode1)
1303cdf0e10cSrcweir             aPam.GetPoint()->nContent += m_nCntnt1;
1304cdf0e10cSrcweir         else
1305cdf0e10cSrcweir             aPam.GetPoint()->nContent.Assign(aPam.GetCntntNode(), m_nCntnt1);
1306cdf0e10cSrcweir     }
1307cdf0e10cSrcweir     else
1308cdf0e10cSrcweir     {
1309cdf0e10cSrcweir         aPam.GetPoint()->nNode = m_nNode1;
1310cdf0e10cSrcweir         aPam.GetPoint()->nContent.Assign(aPam.GetCntntNode(), m_nCntnt1);
1311cdf0e10cSrcweir     }
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir     if(!aPam.HasMark()
1314cdf0e10cSrcweir         || CheckNodesRange(aPam.GetPoint()->nNode, aPam.GetMark()->nNode, sal_True))
1315cdf0e10cSrcweir     {
1316cdf0e10cSrcweir         ::sw::mark::IBookmark* const pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pDoc->getIDocumentMarkAccess()->makeMark(aPam, m_aName, m_eOrigBkmType));
1317cdf0e10cSrcweir         if(pBookmark)
1318cdf0e10cSrcweir         {
1319cdf0e10cSrcweir             pBookmark->SetKeyCode(m_aCode);
1320cdf0e10cSrcweir             pBookmark->SetShortName(m_aShortName);
1321cdf0e10cSrcweir             if (m_pMetadataUndo)
1322cdf0e10cSrcweir             {
1323cdf0e10cSrcweir                 ::sfx2::Metadatable * const pMeta(
1324cdf0e10cSrcweir                     dynamic_cast< ::sfx2::Metadatable* >(pBookmark));
1325cdf0e10cSrcweir                 OSL_ENSURE(pMeta, "metadata undo, but not metadatable?");
1326cdf0e10cSrcweir                 if (pMeta)
1327cdf0e10cSrcweir                 {
1328cdf0e10cSrcweir                     pMeta->RestoreMetadata(m_pMetadataUndo);
1329cdf0e10cSrcweir                 }
1330cdf0e10cSrcweir             }
1331cdf0e10cSrcweir         }
1332cdf0e10cSrcweir     }
1333cdf0e10cSrcweir }
1334cdf0e10cSrcweir 
1335de5fde26SOliver-Rainer Wittmann 
1336cdf0e10cSrcweir // _DelBookmarks, _{Save,Restore}CntntIdx
1337cdf0e10cSrcweir 
_DelBookmarks(const SwNodeIndex & rStt,const SwNodeIndex & rEnd,::std::vector<SaveBookmark> * pSaveBkmk,const SwIndex * pSttIdx,const SwIndex * pEndIdx)1338cdf0e10cSrcweir void _DelBookmarks(
1339cdf0e10cSrcweir     const SwNodeIndex& rStt,
1340cdf0e10cSrcweir     const SwNodeIndex& rEnd,
1341cdf0e10cSrcweir     ::std::vector<SaveBookmark> * pSaveBkmk,
1342cdf0e10cSrcweir     const SwIndex* pSttIdx,
1343cdf0e10cSrcweir     const SwIndex* pEndIdx)
1344cdf0e10cSrcweir {
1345cdf0e10cSrcweir     // illegal range ??
1346cdf0e10cSrcweir     if(rStt.GetIndex() > rEnd.GetIndex()
1347cdf0e10cSrcweir         || (rStt == rEnd && (!pSttIdx || pSttIdx->GetIndex() >= pEndIdx->GetIndex())))
1348cdf0e10cSrcweir         return;
1349cdf0e10cSrcweir     SwDoc* const pDoc = rStt.GetNode().GetDoc();
1350cdf0e10cSrcweir 
1351cdf0e10cSrcweir     pDoc->getIDocumentMarkAccess()->deleteMarks(rStt, rEnd, pSaveBkmk, pSttIdx, pEndIdx);
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir     // kopiere alle Redlines, die im Move Bereich stehen in ein
1354cdf0e10cSrcweir     // Array, das alle Angaben auf die Position als Offset speichert.
1355cdf0e10cSrcweir     // Die neue Zuordung erfolgt nach dem Moven.
1356cdf0e10cSrcweir     SwRedlineTbl& rTbl = (SwRedlineTbl&)pDoc->GetRedlineTbl();
1357cdf0e10cSrcweir     for(sal_uInt16 nCnt = 0; nCnt < rTbl.Count(); ++nCnt )
1358cdf0e10cSrcweir     {
1359cdf0e10cSrcweir         // liegt auf der Position ??
1360cdf0e10cSrcweir         SwRedline* pRedl = rTbl[ nCnt ];
1361cdf0e10cSrcweir 
1362cdf0e10cSrcweir         SwPosition *pRStt = &pRedl->GetBound(sal_True),
1363cdf0e10cSrcweir                    *pREnd = &pRedl->GetBound(sal_False);
1364cdf0e10cSrcweir         if( *pRStt > *pREnd )
1365cdf0e10cSrcweir         {
1366cdf0e10cSrcweir             SwPosition *pTmp = pRStt; pRStt = pREnd, pREnd = pTmp;
1367cdf0e10cSrcweir         }
1368cdf0e10cSrcweir 
1369cdf0e10cSrcweir         if( lcl_Greater( *pRStt, rStt, pSttIdx ) && lcl_Lower( *pRStt, rEnd, pEndIdx ))
1370cdf0e10cSrcweir         {
1371cdf0e10cSrcweir             pRStt->nNode = rEnd;
1372cdf0e10cSrcweir             if( pEndIdx )
1373cdf0e10cSrcweir                 pRStt->nContent = *pEndIdx;
1374cdf0e10cSrcweir             else
1375cdf0e10cSrcweir             {
1376cdf0e10cSrcweir                 sal_Bool bStt = sal_True;
1377cdf0e10cSrcweir                 SwCntntNode* pCNd = pRStt->nNode.GetNode().GetCntntNode();
1378cdf0e10cSrcweir                 if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoNext( &pRStt->nNode )) )
1379cdf0e10cSrcweir                 {
1380cdf0e10cSrcweir                     bStt = sal_False;
1381cdf0e10cSrcweir                     pRStt->nNode = rStt;
1382cdf0e10cSrcweir                     if( 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &pRStt->nNode )) )
1383cdf0e10cSrcweir                     {
1384cdf0e10cSrcweir                         pRStt->nNode = pREnd->nNode;
1385cdf0e10cSrcweir                         pCNd = pRStt->nNode.GetNode().GetCntntNode();
1386cdf0e10cSrcweir                     }
1387cdf0e10cSrcweir                 }
1388cdf0e10cSrcweir                 xub_StrLen nTmp = bStt ? 0 : pCNd->Len();
1389cdf0e10cSrcweir                 pRStt->nContent.Assign( pCNd, nTmp );
1390cdf0e10cSrcweir             }
1391cdf0e10cSrcweir         }
1392cdf0e10cSrcweir         if( lcl_Greater( *pREnd, rStt, pSttIdx ) && lcl_Lower( *pREnd, rEnd, pEndIdx ))
1393cdf0e10cSrcweir         {
1394cdf0e10cSrcweir             pREnd->nNode = rStt;
1395cdf0e10cSrcweir             if( pSttIdx )
1396cdf0e10cSrcweir                 pREnd->nContent = *pSttIdx;
1397cdf0e10cSrcweir             else
1398cdf0e10cSrcweir             {
1399cdf0e10cSrcweir                 sal_Bool bStt = sal_False;
1400cdf0e10cSrcweir                 SwCntntNode* pCNd = pREnd->nNode.GetNode().GetCntntNode();
1401cdf0e10cSrcweir                 if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &pREnd->nNode )) )
1402cdf0e10cSrcweir                 {
1403cdf0e10cSrcweir                     bStt = sal_True;
1404cdf0e10cSrcweir                     pREnd->nNode = rEnd;
1405cdf0e10cSrcweir                     if( 0 == ( pCNd = pDoc->GetNodes().GoNext( &pREnd->nNode )) )
1406cdf0e10cSrcweir                     {
1407cdf0e10cSrcweir                         pREnd->nNode = pRStt->nNode;
1408cdf0e10cSrcweir                         pCNd = pREnd->nNode.GetNode().GetCntntNode();
1409cdf0e10cSrcweir                     }
1410cdf0e10cSrcweir                 }
1411cdf0e10cSrcweir                 xub_StrLen nTmp = bStt ? 0 : pCNd->Len();
1412cdf0e10cSrcweir                 pREnd->nContent.Assign( pCNd, nTmp );
1413cdf0e10cSrcweir             }
1414cdf0e10cSrcweir         }
1415cdf0e10cSrcweir     }
1416cdf0e10cSrcweir }
1417cdf0e10cSrcweir 
_SaveCntntIdx(SwDoc * pDoc,sal_uLong nNode,xub_StrLen nCntnt,SvULongs & rSaveArr,sal_uInt8 nSaveFly)1418cdf0e10cSrcweir void _SaveCntntIdx(SwDoc* pDoc,
1419cdf0e10cSrcweir     sal_uLong nNode,
1420cdf0e10cSrcweir     xub_StrLen nCntnt,
1421cdf0e10cSrcweir     SvULongs& rSaveArr,
1422cdf0e10cSrcweir     sal_uInt8 nSaveFly)
1423cdf0e10cSrcweir {
1424cdf0e10cSrcweir     // 1. Bookmarks
1425cdf0e10cSrcweir     _SwSaveTypeCountContent aSave;
1426cdf0e10cSrcweir     aSave.SetTypeAndCount( 0x8000, 0 );
1427cdf0e10cSrcweir 
1428cdf0e10cSrcweir     IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1429dec99bbdSOliver-Rainer Wittmann     const sal_Int32 nMarksCount = pMarkAccess->getAllMarksCount();
1430dec99bbdSOliver-Rainer Wittmann     for ( ; aSave.GetCount() < nMarksCount; aSave.IncCount() )
1431cdf0e10cSrcweir     {
1432dec99bbdSOliver-Rainer Wittmann         bool bMarkPosEqual = false;
1433dec99bbdSOliver-Rainer Wittmann         const ::sw::mark::IMark* pBkmk = (pMarkAccess->getAllMarksBegin() + aSave.GetCount())->get();
1434cdf0e10cSrcweir         if(pBkmk->GetMarkPos().nNode.GetIndex() == nNode
1435cdf0e10cSrcweir             && pBkmk->GetMarkPos().nContent.GetIndex() <= nCntnt)
1436cdf0e10cSrcweir         {
1437cdf0e10cSrcweir             if(pBkmk->GetMarkPos().nContent.GetIndex() < nCntnt)
1438cdf0e10cSrcweir             {
1439cdf0e10cSrcweir                 aSave.SetContent(pBkmk->GetMarkPos().nContent.GetIndex());
1440cdf0e10cSrcweir                 aSave.Add(rSaveArr);
1441cdf0e10cSrcweir             }
1442cdf0e10cSrcweir             else // if a bookmark position is equal nCntnt, the other position
1443dec99bbdSOliver-Rainer Wittmann                 bMarkPosEqual = true; // has to decide if it is added to the array
1444cdf0e10cSrcweir         }
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir         if(pBkmk->IsExpanded()
1447cdf0e10cSrcweir             && pBkmk->GetOtherMarkPos().nNode.GetIndex() == nNode
1448cdf0e10cSrcweir             && pBkmk->GetOtherMarkPos().nContent.GetIndex() <= nCntnt)
1449cdf0e10cSrcweir         {
1450dec99bbdSOliver-Rainer Wittmann             if(bMarkPosEqual)
1451cdf0e10cSrcweir             { // the other position is before, the (main) position is equal
1452cdf0e10cSrcweir                 aSave.SetContent(pBkmk->GetMarkPos().nContent.GetIndex());
1453cdf0e10cSrcweir                 aSave.Add(rSaveArr);
1454cdf0e10cSrcweir             }
1455cdf0e10cSrcweir             aSave.SetContent(pBkmk->GetOtherMarkPos().nContent.GetIndex());
1456cdf0e10cSrcweir             aSave.IncType();
1457cdf0e10cSrcweir             aSave.Add(rSaveArr);
1458cdf0e10cSrcweir             aSave.DecType();
1459cdf0e10cSrcweir         }
1460cdf0e10cSrcweir     }
1461cdf0e10cSrcweir 
1462cdf0e10cSrcweir 	// 2. Redlines
1463cdf0e10cSrcweir 	aSave.SetTypeAndCount( 0x1000, 0 );
1464cdf0e10cSrcweir 	const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
1465cdf0e10cSrcweir 	for( ; aSave.GetCount() < rRedlTbl.Count(); aSave.IncCount() )
1466cdf0e10cSrcweir 	{
1467cdf0e10cSrcweir 		const SwRedline* pRdl = rRedlTbl[ aSave.GetCount() ];
1468cdf0e10cSrcweir         int nPointPos = lcl_RelativePosition( *pRdl->GetPoint(), nNode, nCntnt );
1469cdf0e10cSrcweir         int nMarkPos = pRdl->HasMark() ? lcl_RelativePosition( *pRdl->GetMark(), nNode, nCntnt ) :
1470cdf0e10cSrcweir                                           nPointPos;
1471cdf0e10cSrcweir         // #i59534: We have to store the positions inside the same node before the insert position
1472cdf0e10cSrcweir         // and the one at the insert position if the corresponding Point/Mark position is before
1473cdf0e10cSrcweir         // the insert position.
1474cdf0e10cSrcweir         if( nPointPos == BEFORE_SAME_NODE ||
1475cdf0e10cSrcweir             ( nPointPos == SAME_POSITION && nMarkPos < SAME_POSITION ) )
1476cdf0e10cSrcweir 		{
1477cdf0e10cSrcweir 			aSave.SetContent( pRdl->GetPoint()->nContent.GetIndex() );
1478cdf0e10cSrcweir 			aSave.IncType();
1479cdf0e10cSrcweir 			aSave.Add( rSaveArr );
1480cdf0e10cSrcweir 			aSave.DecType();
1481cdf0e10cSrcweir 		}
1482cdf0e10cSrcweir 		if( pRdl->HasMark() && ( nMarkPos == BEFORE_SAME_NODE ||
1483cdf0e10cSrcweir             ( nMarkPos == SAME_POSITION && nPointPos < SAME_POSITION ) ) )
1484cdf0e10cSrcweir         {
1485cdf0e10cSrcweir 			aSave.SetContent( pRdl->GetMark()->nContent.GetIndex() );
1486cdf0e10cSrcweir 			aSave.Add( rSaveArr );
1487cdf0e10cSrcweir 		}
1488cdf0e10cSrcweir 	}
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir 	// 4. Absatzgebundene Objekte
1491cdf0e10cSrcweir 	{
1492cdf0e10cSrcweir 		SwCntntNode *pNode = pDoc->GetNodes()[nNode]->GetCntntNode();
1493cdf0e10cSrcweir 		if( pNode )
1494cdf0e10cSrcweir 		{
1495cdf0e10cSrcweir 
1496cdf0e10cSrcweir 			SwFrm* pFrm = pNode->getLayoutFrm( pDoc->GetCurrentLayout() );
1497cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1498cdf0e10cSrcweir 			static sal_Bool bViaDoc = sal_False;
1499cdf0e10cSrcweir 			if( bViaDoc )
1500cdf0e10cSrcweir 				pFrm = NULL;
1501cdf0e10cSrcweir #endif
1502cdf0e10cSrcweir 			if( pFrm ) // gibt es ein Layout? Dann ist etwas billiger...
1503cdf0e10cSrcweir 			{
1504cdf0e10cSrcweir 				if( pFrm->GetDrawObjs() )
1505cdf0e10cSrcweir 				{
1506cdf0e10cSrcweir                     const SwSortedObjs& rDObj = *pFrm->GetDrawObjs();
1507cdf0e10cSrcweir                     for( sal_uInt32 n = rDObj.Count(); n; )
1508cdf0e10cSrcweir 					{
1509cdf0e10cSrcweir                         SwAnchoredObject* pObj = rDObj[ --n ];
1510cdf0e10cSrcweir                         const SwFrmFmt& rFmt = pObj->GetFrmFmt();
1511cdf0e10cSrcweir                         const SwFmtAnchor& rAnchor = rFmt.GetAnchor();
1512cdf0e10cSrcweir                         SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
1513cdf0e10cSrcweir                         if ( pAPos &&
1514cdf0e10cSrcweir                              ( ( nSaveFly &&
1515cdf0e10cSrcweir                                  FLY_AT_PARA == rAnchor.GetAnchorId() ) ||
1516cdf0e10cSrcweir                                ( FLY_AT_CHAR == rAnchor.GetAnchorId() ) ) )
1517cdf0e10cSrcweir                         {
1518cdf0e10cSrcweir 							aSave.SetType( 0x2000 );
1519cdf0e10cSrcweir 							aSave.SetContent( pAPos->nContent.GetIndex() );
1520cdf0e10cSrcweir 
1521cdf0e10cSrcweir 							OSL_ENSURE( nNode == pAPos->nNode.GetIndex(),
1522cdf0e10cSrcweir 									"_SaveCntntIdx: Wrong Node-Index" );
1523cdf0e10cSrcweir                             if ( FLY_AT_CHAR == rAnchor.GetAnchorId() )
1524cdf0e10cSrcweir 							{
1525cdf0e10cSrcweir 								if( nCntnt <= aSave.GetContent() )
1526cdf0e10cSrcweir 								{
1527cdf0e10cSrcweir 									if( SAVEFLY_SPLIT == nSaveFly )
1528cdf0e10cSrcweir 										aSave.IncType(); // = 0x2001;
1529cdf0e10cSrcweir 									else
1530cdf0e10cSrcweir 										continue;
1531cdf0e10cSrcweir 								}
1532cdf0e10cSrcweir 							}
1533cdf0e10cSrcweir 							aSave.SetCount( pDoc->GetSpzFrmFmts()->Count() );
1534cdf0e10cSrcweir 							while( aSave.GetCount() &&
1535cdf0e10cSrcweir                                     &rFmt != (*pDoc->GetSpzFrmFmts())[
1536cdf0e10cSrcweir                                     aSave.DecCount() ] )
1537cdf0e10cSrcweir 								; // nothing
1538cdf0e10cSrcweir                             OSL_ENSURE( &rFmt == (*pDoc->GetSpzFrmFmts())[
1539cdf0e10cSrcweir 													aSave.GetCount() ],
1540cdf0e10cSrcweir 									"_SaveCntntIdx: Lost FrameFormat" );
1541cdf0e10cSrcweir 							aSave.Add( rSaveArr );
1542cdf0e10cSrcweir 						}
1543cdf0e10cSrcweir 					}
1544cdf0e10cSrcweir 				}
1545cdf0e10cSrcweir 			}
1546cdf0e10cSrcweir 			else // Schade, kein Layout, dann ist es eben etwas teurer...
1547cdf0e10cSrcweir 			{
1548cdf0e10cSrcweir 				for( aSave.SetCount( pDoc->GetSpzFrmFmts()->Count() );
1549cdf0e10cSrcweir 						aSave.GetCount() ; )
1550cdf0e10cSrcweir 				{
1551cdf0e10cSrcweir 					SwFrmFmt* pFrmFmt = (*pDoc->GetSpzFrmFmts())[
1552cdf0e10cSrcweir 												aSave.DecCount() ];
1553cdf0e10cSrcweir 					if ( RES_FLYFRMFMT != pFrmFmt->Which() &&
1554cdf0e10cSrcweir 							RES_DRAWFRMFMT != pFrmFmt->Which() )
1555cdf0e10cSrcweir 						continue;
1556cdf0e10cSrcweir 
1557cdf0e10cSrcweir 					const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
1558cdf0e10cSrcweir                     SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
1559cdf0e10cSrcweir                     if ( pAPos && ( nNode == pAPos->nNode.GetIndex() ) &&
1560cdf0e10cSrcweir                          ( FLY_AT_PARA == rAnchor.GetAnchorId() ||
1561cdf0e10cSrcweir                            FLY_AT_CHAR == rAnchor.GetAnchorId() ) )
1562cdf0e10cSrcweir                     {
1563cdf0e10cSrcweir 						aSave.SetType( 0x2000 );
1564cdf0e10cSrcweir 						aSave.SetContent( pAPos->nContent.GetIndex() );
1565cdf0e10cSrcweir                         if ( FLY_AT_CHAR == rAnchor.GetAnchorId() )
1566cdf0e10cSrcweir 						{
1567cdf0e10cSrcweir 							if( nCntnt <= aSave.GetContent() )
1568cdf0e10cSrcweir 							{
1569cdf0e10cSrcweir 								if( SAVEFLY_SPLIT == nSaveFly )
1570cdf0e10cSrcweir 									aSave.IncType(); // = 0x2001;
1571cdf0e10cSrcweir 								else
1572cdf0e10cSrcweir 									continue;
1573cdf0e10cSrcweir 							}
1574cdf0e10cSrcweir 						}
1575cdf0e10cSrcweir 						aSave.Add( rSaveArr );
1576cdf0e10cSrcweir 					}
1577cdf0e10cSrcweir 				}
1578cdf0e10cSrcweir 			}
1579cdf0e10cSrcweir 		}
1580cdf0e10cSrcweir 	}
1581cdf0e10cSrcweir 	// 5. CrsrShell
1582cdf0e10cSrcweir 	{
1583cdf0e10cSrcweir 		SwCrsrShell* pShell = pDoc->GetEditShell();
1584cdf0e10cSrcweir 		if( pShell )
1585cdf0e10cSrcweir 		{
1586cdf0e10cSrcweir 			aSave.SetTypeAndCount( 0x800, 0 );
1587cdf0e10cSrcweir 			FOREACHSHELL_START( pShell )
1588cdf0e10cSrcweir 				SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
1589cdf0e10cSrcweir 				if( _pStkCrsr )
1590cdf0e10cSrcweir 				do {
1591cdf0e10cSrcweir 					lcl_ChkPaM( rSaveArr, nNode, nCntnt, *_pStkCrsr,
1592cdf0e10cSrcweir 								aSave, sal_False );
1593cdf0e10cSrcweir 					aSave.IncCount();
1594cdf0e10cSrcweir 				} while ( (_pStkCrsr != 0 ) &&
1595cdf0e10cSrcweir 					((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
1596cdf0e10cSrcweir 
1597cdf0e10cSrcweir 				FOREACHPAM_START( PCURSH->_GetCrsr() )
1598cdf0e10cSrcweir 					lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR,
1599cdf0e10cSrcweir 								aSave, sal_False );
1600cdf0e10cSrcweir 					aSave.IncCount();
1601cdf0e10cSrcweir 				FOREACHPAM_END()
1602cdf0e10cSrcweir 
1603cdf0e10cSrcweir 			FOREACHSHELL_END( pShell )
1604cdf0e10cSrcweir 		}
1605cdf0e10cSrcweir 	}
1606cdf0e10cSrcweir 	// 6. UnoCrsr
1607cdf0e10cSrcweir 	{
1608cdf0e10cSrcweir 		aSave.SetTypeAndCount( 0x400, 0 );
1609cdf0e10cSrcweir 		const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl();
1610cdf0e10cSrcweir 		for( sal_uInt16 n = 0; n < rTbl.Count(); ++n )
1611cdf0e10cSrcweir 		{
1612cdf0e10cSrcweir 			FOREACHPAM_START( rTbl[ n ] )
1613cdf0e10cSrcweir 				lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, sal_False );
1614cdf0e10cSrcweir 				aSave.IncCount();
1615cdf0e10cSrcweir 			FOREACHPAM_END()
1616cdf0e10cSrcweir 
1617cdf0e10cSrcweir             SwUnoTableCrsr* pUnoTblCrsr =
1618cdf0e10cSrcweir                 dynamic_cast<SwUnoTableCrsr*>(rTbl[ n ]);
1619cdf0e10cSrcweir 			if( pUnoTblCrsr )
1620cdf0e10cSrcweir 			{
1621cdf0e10cSrcweir 				FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
1622cdf0e10cSrcweir 					lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, sal_False );
1623cdf0e10cSrcweir 					aSave.IncCount();
1624cdf0e10cSrcweir 				FOREACHPAM_END()
1625cdf0e10cSrcweir 			}
1626cdf0e10cSrcweir 		}
1627cdf0e10cSrcweir 	}
1628cdf0e10cSrcweir }
1629cdf0e10cSrcweir 
1630cdf0e10cSrcweir 
_RestoreCntntIdx(SwDoc * pDoc,SvULongs & rSaveArr,sal_uLong nNode,xub_StrLen nOffset,sal_Bool bAuto)1631cdf0e10cSrcweir void _RestoreCntntIdx(SwDoc* pDoc,
1632cdf0e10cSrcweir     SvULongs& rSaveArr,
1633cdf0e10cSrcweir     sal_uLong nNode,
1634cdf0e10cSrcweir     xub_StrLen nOffset,
1635cdf0e10cSrcweir     sal_Bool bAuto)
1636cdf0e10cSrcweir {
1637cdf0e10cSrcweir 	SwCntntNode* pCNd = pDoc->GetNodes()[ nNode ]->GetCntntNode();
1638cdf0e10cSrcweir 	const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
1639cdf0e10cSrcweir 	SwSpzFrmFmts* pSpz = pDoc->GetSpzFrmFmts();
1640cdf0e10cSrcweir     IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1641cdf0e10cSrcweir 	sal_uInt16 n = 0;
1642cdf0e10cSrcweir 	while( n < rSaveArr.Count() )
1643cdf0e10cSrcweir 	{
1644cdf0e10cSrcweir 		_SwSaveTypeCountContent aSave( rSaveArr, n );
1645cdf0e10cSrcweir 		SwPosition* pPos = 0;
1646cdf0e10cSrcweir         switch( aSave.GetType() )
1647cdf0e10cSrcweir         {
1648cdf0e10cSrcweir             case 0x8000:
1649cdf0e10cSrcweir             {
1650dec99bbdSOliver-Rainer Wittmann                 MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aSave.GetCount()].get());
1651cdf0e10cSrcweir                 SwPosition aNewPos(pMark->GetMarkPos());
1652cdf0e10cSrcweir                 aNewPos.nNode = *pCNd;
1653cdf0e10cSrcweir                 aNewPos.nContent.Assign(pCNd, aSave.GetContent() + nOffset);
1654cdf0e10cSrcweir                 pMark->SetMarkPos(aNewPos);
1655cdf0e10cSrcweir             }
1656cdf0e10cSrcweir             break;
1657cdf0e10cSrcweir             case 0x8001:
1658cdf0e10cSrcweir             {
1659dec99bbdSOliver-Rainer Wittmann                 MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aSave.GetCount()].get());
1660cdf0e10cSrcweir                 SwPosition aNewPos(pMark->GetOtherMarkPos());
1661cdf0e10cSrcweir                 aNewPos.nNode = *pCNd;
1662cdf0e10cSrcweir                 aNewPos.nContent.Assign(pCNd, aSave.GetContent() + nOffset);
1663cdf0e10cSrcweir                 pMark->SetOtherMarkPos(aNewPos);
1664cdf0e10cSrcweir             }
1665cdf0e10cSrcweir             break;
1666cdf0e10cSrcweir             case 0x1001:
1667cdf0e10cSrcweir                 pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetPoint();
1668cdf0e10cSrcweir                 break;
1669cdf0e10cSrcweir             case 0x1000:
1670cdf0e10cSrcweir                 pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetMark();
1671cdf0e10cSrcweir                 break;
1672cdf0e10cSrcweir             case 0x2000:
1673cdf0e10cSrcweir                 {
1674cdf0e10cSrcweir                     SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
1675cdf0e10cSrcweir                     const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor();
1676cdf0e10cSrcweir                     if( rFlyAnchor.GetCntntAnchor() )
1677cdf0e10cSrcweir                     {
1678cdf0e10cSrcweir                         SwFmtAnchor aNew( rFlyAnchor );
1679cdf0e10cSrcweir                         SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() );
1680cdf0e10cSrcweir                         aNewPos.nNode = *pCNd;
1681cdf0e10cSrcweir                         if ( FLY_AT_CHAR == rFlyAnchor.GetAnchorId() )
1682cdf0e10cSrcweir                         {
1683cdf0e10cSrcweir                             aNewPos.nContent.Assign( pCNd,
1684cdf0e10cSrcweir                                                      aSave.GetContent() + nOffset );
1685cdf0e10cSrcweir                         }
1686cdf0e10cSrcweir                         else
1687cdf0e10cSrcweir                         {
1688cdf0e10cSrcweir                             aNewPos.nContent.Assign( 0, 0 );
1689cdf0e10cSrcweir                         }
1690cdf0e10cSrcweir                         aNew.SetAnchor( &aNewPos );
1691cdf0e10cSrcweir                         pFrmFmt->SetFmtAttr( aNew );
1692cdf0e10cSrcweir                     }
1693cdf0e10cSrcweir                 }
1694cdf0e10cSrcweir                 break;
1695cdf0e10cSrcweir             case 0x2001:
1696cdf0e10cSrcweir                 if( bAuto )
1697cdf0e10cSrcweir                 {
1698cdf0e10cSrcweir                     SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
1699cdf0e10cSrcweir                     SfxPoolItem *pAnchor = (SfxPoolItem*)&pFrmFmt->GetAnchor();
1700cdf0e10cSrcweir                     pFrmFmt->NotifyClients( pAnchor, pAnchor );
1701cdf0e10cSrcweir                 }
1702cdf0e10cSrcweir                 break;
1703cdf0e10cSrcweir 
1704cdf0e10cSrcweir             case 0x0800:
1705cdf0e10cSrcweir             case 0x0801:
1706cdf0e10cSrcweir                 {
1707cdf0e10cSrcweir                     sal_uInt16 nCnt = 0;
1708cdf0e10cSrcweir                     SwCrsrShell* pShell = pDoc->GetEditShell();
1709cdf0e10cSrcweir                     if( pShell )
1710cdf0e10cSrcweir                     {
1711cdf0e10cSrcweir                         FOREACHSHELL_START( pShell )
1712cdf0e10cSrcweir                             SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
1713cdf0e10cSrcweir                             if( _pStkCrsr )
1714cdf0e10cSrcweir                             do {
1715cdf0e10cSrcweir                                 if( aSave.GetCount() == nCnt )
1716cdf0e10cSrcweir                                 {
1717cdf0e10cSrcweir                                     pPos = &_pStkCrsr->GetBound( 0x0800 ==
1718cdf0e10cSrcweir                                                         aSave.GetType() );
1719cdf0e10cSrcweir                                     break;
1720cdf0e10cSrcweir                                 }
1721cdf0e10cSrcweir                                 ++nCnt;
1722cdf0e10cSrcweir                             } while ( (_pStkCrsr != 0 ) &&
1723cdf0e10cSrcweir                                 ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
1724cdf0e10cSrcweir 
1725cdf0e10cSrcweir                             if( pPos )
1726cdf0e10cSrcweir                                 break;
1727cdf0e10cSrcweir 
1728cdf0e10cSrcweir                             FOREACHPAM_START( PCURSH->_GetCrsr() )
1729cdf0e10cSrcweir                                 if( aSave.GetCount() == nCnt )
1730cdf0e10cSrcweir                                 {
1731cdf0e10cSrcweir                                     pPos = &PCURCRSR->GetBound( 0x0800 ==
1732cdf0e10cSrcweir                                                         aSave.GetType() );
1733cdf0e10cSrcweir                                     break;
1734cdf0e10cSrcweir                                 }
1735cdf0e10cSrcweir                                 ++nCnt;
1736cdf0e10cSrcweir                             FOREACHPAM_END()
1737cdf0e10cSrcweir                             if( pPos )
1738cdf0e10cSrcweir                                 break;
1739cdf0e10cSrcweir 
1740cdf0e10cSrcweir                         FOREACHSHELL_END( pShell )
1741cdf0e10cSrcweir                     }
1742cdf0e10cSrcweir             }
1743cdf0e10cSrcweir             break;
1744cdf0e10cSrcweir 
1745cdf0e10cSrcweir         case 0x0400:
1746cdf0e10cSrcweir         case 0x0401:
1747cdf0e10cSrcweir             {
1748cdf0e10cSrcweir                 sal_uInt16 nCnt = 0;
1749cdf0e10cSrcweir                 const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl();
1750cdf0e10cSrcweir                 for( sal_uInt16 i = 0; i < rTbl.Count(); ++i )
1751cdf0e10cSrcweir                 {
1752cdf0e10cSrcweir                     FOREACHPAM_START( rTbl[ i ] )
1753cdf0e10cSrcweir                         if( aSave.GetCount() == nCnt )
1754cdf0e10cSrcweir                         {
1755cdf0e10cSrcweir                             pPos = &PCURCRSR->GetBound( 0x0400 ==
1756cdf0e10cSrcweir                                                     aSave.GetType() );
1757cdf0e10cSrcweir                             break;
1758cdf0e10cSrcweir                         }
1759cdf0e10cSrcweir                         ++nCnt;
1760cdf0e10cSrcweir                     FOREACHPAM_END()
1761cdf0e10cSrcweir                     if( pPos )
1762cdf0e10cSrcweir                         break;
1763cdf0e10cSrcweir 
1764cdf0e10cSrcweir                     SwUnoTableCrsr* pUnoTblCrsr =
1765cdf0e10cSrcweir                         dynamic_cast<SwUnoTableCrsr*>(rTbl[ i ]);
1766cdf0e10cSrcweir                     if ( pUnoTblCrsr )
1767cdf0e10cSrcweir                     {
1768cdf0e10cSrcweir                         FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
1769cdf0e10cSrcweir                             if( aSave.GetCount() == nCnt )
1770cdf0e10cSrcweir                             {
1771cdf0e10cSrcweir                                 pPos = &PCURCRSR->GetBound( 0x0400 ==
1772cdf0e10cSrcweir                                                     aSave.GetType() );
1773cdf0e10cSrcweir                                 break;
1774cdf0e10cSrcweir                             }
1775cdf0e10cSrcweir                             ++nCnt;
1776cdf0e10cSrcweir                         FOREACHPAM_END()
1777cdf0e10cSrcweir                     }
1778cdf0e10cSrcweir                     if ( pPos )
1779cdf0e10cSrcweir                         break;
1780cdf0e10cSrcweir                 }
1781cdf0e10cSrcweir             }
1782cdf0e10cSrcweir             break;
1783cdf0e10cSrcweir         }
1784cdf0e10cSrcweir 
1785cdf0e10cSrcweir         if( pPos )
1786cdf0e10cSrcweir         {
1787cdf0e10cSrcweir             pPos->nNode = *pCNd;
1788cdf0e10cSrcweir             pPos->nContent.Assign( pCNd, aSave.GetContent() + nOffset );
1789cdf0e10cSrcweir         }
1790cdf0e10cSrcweir     }
1791cdf0e10cSrcweir }
1792cdf0e10cSrcweir 
_RestoreCntntIdx(SvULongs & rSaveArr,const SwNode & rNd,xub_StrLen nLen,xub_StrLen nChkLen)1793cdf0e10cSrcweir void _RestoreCntntIdx(SvULongs& rSaveArr,
1794cdf0e10cSrcweir     const SwNode& rNd,
1795cdf0e10cSrcweir     xub_StrLen nLen,
1796cdf0e10cSrcweir     xub_StrLen nChkLen)
1797cdf0e10cSrcweir {
1798cdf0e10cSrcweir     const SwDoc* pDoc = rNd.GetDoc();
1799cdf0e10cSrcweir     const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
1800cdf0e10cSrcweir     const SwSpzFrmFmts* pSpz = pDoc->GetSpzFrmFmts();
1801cdf0e10cSrcweir     const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1802cdf0e10cSrcweir     SwCntntNode* pCNd = (SwCntntNode*)rNd.GetCntntNode();
1803cdf0e10cSrcweir 
1804cdf0e10cSrcweir     sal_uInt16 n = 0;
1805cdf0e10cSrcweir     while( n < rSaveArr.Count() )
1806cdf0e10cSrcweir     {
1807cdf0e10cSrcweir         _SwSaveTypeCountContent aSave( rSaveArr, n );
1808cdf0e10cSrcweir         if( aSave.GetContent() >= nChkLen )
1809cdf0e10cSrcweir             rSaveArr[ n-1 ] -= nChkLen;
1810cdf0e10cSrcweir         else
1811cdf0e10cSrcweir         {
1812cdf0e10cSrcweir             SwPosition* pPos = 0;
1813cdf0e10cSrcweir             switch( aSave.GetType() )
1814cdf0e10cSrcweir             {
1815cdf0e10cSrcweir             case 0x8000:
1816cdf0e10cSrcweir             {
1817dec99bbdSOliver-Rainer Wittmann                 MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aSave.GetCount()].get());
1818cdf0e10cSrcweir                 SwPosition aNewPos(pMark->GetMarkPos());
1819cdf0e10cSrcweir                 aNewPos.nNode = rNd;
1820cdf0e10cSrcweir                 aNewPos.nContent.Assign(pCNd, Min(aSave.GetContent(), nLen));
1821cdf0e10cSrcweir                 pMark->SetMarkPos(aNewPos);
1822cdf0e10cSrcweir             }
1823cdf0e10cSrcweir             break;
1824cdf0e10cSrcweir             case 0x8001:
1825cdf0e10cSrcweir             {
1826dec99bbdSOliver-Rainer Wittmann                 MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aSave.GetCount()].get());
1827cdf0e10cSrcweir                 SwPosition aNewPos(pMark->GetOtherMarkPos());
1828cdf0e10cSrcweir                 aNewPos.nNode = rNd;
1829cdf0e10cSrcweir                 aNewPos.nContent.Assign(pCNd, Min(aSave.GetContent(), nLen));
1830cdf0e10cSrcweir                 pMark->SetOtherMarkPos(aNewPos);
1831cdf0e10cSrcweir             }
1832cdf0e10cSrcweir             break;
1833cdf0e10cSrcweir             case 0x1001:
1834cdf0e10cSrcweir                 pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetPoint();
1835cdf0e10cSrcweir                 break;
1836cdf0e10cSrcweir             case 0x1000:
1837cdf0e10cSrcweir                 pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetMark();
1838cdf0e10cSrcweir                 break;
1839cdf0e10cSrcweir             case 0x2000:
1840cdf0e10cSrcweir             case 0x2001:
1841cdf0e10cSrcweir                 {
1842cdf0e10cSrcweir                     SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
1843cdf0e10cSrcweir                     const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor();
1844cdf0e10cSrcweir                     if( rFlyAnchor.GetCntntAnchor() )
1845cdf0e10cSrcweir                     {
1846cdf0e10cSrcweir                         SwFmtAnchor aNew( rFlyAnchor );
1847cdf0e10cSrcweir                         SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() );
1848cdf0e10cSrcweir                         aNewPos.nNode = rNd;
1849cdf0e10cSrcweir                         if ( FLY_AT_CHAR == rFlyAnchor.GetAnchorId() )
1850cdf0e10cSrcweir                         {
1851cdf0e10cSrcweir                             aNewPos.nContent.Assign( pCNd, Min(
1852cdf0e10cSrcweir                                                      aSave.GetContent(), nLen ) );
1853cdf0e10cSrcweir                         }
1854cdf0e10cSrcweir                         else
1855cdf0e10cSrcweir                         {
1856cdf0e10cSrcweir                             aNewPos.nContent.Assign( 0, 0 );
1857cdf0e10cSrcweir                         }
1858cdf0e10cSrcweir                         aNew.SetAnchor( &aNewPos );
1859cdf0e10cSrcweir                         pFrmFmt->SetFmtAttr( aNew );
1860cdf0e10cSrcweir                     }
1861cdf0e10cSrcweir                 }
1862cdf0e10cSrcweir                 break;
1863cdf0e10cSrcweir 
1864cdf0e10cSrcweir             case 0x0800:
1865cdf0e10cSrcweir             case 0x0801:
1866cdf0e10cSrcweir                 {
1867cdf0e10cSrcweir                     sal_uInt16 nCnt = 0;
1868cdf0e10cSrcweir                     SwCrsrShell* pShell = pDoc->GetEditShell();
1869cdf0e10cSrcweir                     if( pShell )
1870cdf0e10cSrcweir                     {
1871cdf0e10cSrcweir                         FOREACHSHELL_START( pShell )
1872cdf0e10cSrcweir                             SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
1873cdf0e10cSrcweir                             if( _pStkCrsr )
1874cdf0e10cSrcweir                             do {
1875cdf0e10cSrcweir                                 if( aSave.GetCount() == nCnt )
1876cdf0e10cSrcweir                                 {
1877cdf0e10cSrcweir                                     pPos = &_pStkCrsr->GetBound( 0x0800 ==
1878cdf0e10cSrcweir                                                 aSave.GetType() );
1879cdf0e10cSrcweir                                     break;
1880cdf0e10cSrcweir                                 }
1881cdf0e10cSrcweir                                 ++nCnt;
1882cdf0e10cSrcweir                             } while ( (_pStkCrsr != 0 ) &&
1883cdf0e10cSrcweir                                 ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
1884cdf0e10cSrcweir 
1885cdf0e10cSrcweir                             if( pPos )
1886cdf0e10cSrcweir                                 break;
1887cdf0e10cSrcweir 
1888cdf0e10cSrcweir                             FOREACHPAM_START( PCURSH->_GetCrsr() )
1889cdf0e10cSrcweir                                 if( aSave.GetCount() == nCnt )
1890cdf0e10cSrcweir                                 {
1891cdf0e10cSrcweir                                     pPos = &PCURCRSR->GetBound( 0x0800 ==
1892cdf0e10cSrcweir                                                 aSave.GetType() );
1893cdf0e10cSrcweir                                     break;
1894cdf0e10cSrcweir                                 }
1895cdf0e10cSrcweir                                 ++nCnt;
1896cdf0e10cSrcweir                             FOREACHPAM_END()
1897cdf0e10cSrcweir                             if( pPos )
1898cdf0e10cSrcweir                                 break;
1899cdf0e10cSrcweir 
1900cdf0e10cSrcweir                         FOREACHSHELL_END( pShell )
1901cdf0e10cSrcweir                     }
1902cdf0e10cSrcweir                 }
1903cdf0e10cSrcweir                 break;
1904cdf0e10cSrcweir 
1905cdf0e10cSrcweir             case 0x0400:
1906cdf0e10cSrcweir             case 0x0401:
1907cdf0e10cSrcweir                 {
1908cdf0e10cSrcweir                     sal_uInt16 nCnt = 0;
1909cdf0e10cSrcweir                     const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl();
1910cdf0e10cSrcweir                     for( sal_uInt16 i = 0; i < rTbl.Count(); ++i )
1911cdf0e10cSrcweir                     {
1912cdf0e10cSrcweir                         FOREACHPAM_START( rTbl[ i ] )
1913cdf0e10cSrcweir                             if( aSave.GetCount() == nCnt )
1914cdf0e10cSrcweir                             {
1915cdf0e10cSrcweir                                 pPos = &PCURCRSR->GetBound( 0x0400 ==
1916cdf0e10cSrcweir                                                     aSave.GetType() );
1917cdf0e10cSrcweir                                 break;
1918cdf0e10cSrcweir                             }
1919cdf0e10cSrcweir                             ++nCnt;
1920cdf0e10cSrcweir                         FOREACHPAM_END()
1921cdf0e10cSrcweir                         if( pPos )
1922cdf0e10cSrcweir                             break;
1923cdf0e10cSrcweir 
1924cdf0e10cSrcweir                         SwUnoTableCrsr* pUnoTblCrsr =
1925cdf0e10cSrcweir                             dynamic_cast<SwUnoTableCrsr*>(rTbl[ i ]);
1926cdf0e10cSrcweir                         if ( pUnoTblCrsr )
1927cdf0e10cSrcweir                         {
1928cdf0e10cSrcweir                             FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
1929cdf0e10cSrcweir                                 if( aSave.GetCount() == nCnt )
1930cdf0e10cSrcweir                                 {
1931cdf0e10cSrcweir                                     pPos = &PCURCRSR->GetBound( 0x0400 ==
1932cdf0e10cSrcweir                                                     aSave.GetType() );
1933cdf0e10cSrcweir                                     break;
1934cdf0e10cSrcweir                                 }
1935cdf0e10cSrcweir                                 ++nCnt;
1936cdf0e10cSrcweir                             FOREACHPAM_END()
1937cdf0e10cSrcweir                         }
1938cdf0e10cSrcweir                         if ( pPos )
1939cdf0e10cSrcweir                             break;
1940cdf0e10cSrcweir                     }
1941cdf0e10cSrcweir                 }
1942cdf0e10cSrcweir                 break;
1943cdf0e10cSrcweir             }
1944cdf0e10cSrcweir 
1945cdf0e10cSrcweir             if( pPos )
1946cdf0e10cSrcweir             {
1947cdf0e10cSrcweir                 pPos->nNode = rNd;
1948cdf0e10cSrcweir                 pPos->nContent.Assign( pCNd, Min( aSave.GetContent(), nLen ) );
1949cdf0e10cSrcweir             }
1950cdf0e10cSrcweir             n -= 2;
1951cdf0e10cSrcweir             rSaveArr.Remove( n, 2 );
1952cdf0e10cSrcweir         }
1953cdf0e10cSrcweir     }
1954cdf0e10cSrcweir }
1955