xref: /trunk/main/sw/source/core/crsr/unocrsr.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <unocrsr.hxx>
33 #include <doc.hxx>
34 #include <swtable.hxx>
35 #include <docary.hxx>
36 #include <rootfrm.hxx>
37 
38 SV_IMPL_PTRARR( SwUnoCrsrTbl, SwUnoCrsrPtr )
39 
40 IMPL_FIXEDMEMPOOL_NEWDEL( SwUnoCrsr, 10, 10 )
41 
42 SwUnoCrsr::SwUnoCrsr( const SwPosition &rPos, SwPaM* pRing )
43     : SwCursor( rPos, pRing, false ), SwModify( 0 ),
44     bRemainInSection( sal_True ),
45     bSkipOverHiddenSections( sal_False ),
46     bSkipOverProtectSections( sal_False )
47 
48 {}
49 
50 SwUnoCrsr::~SwUnoCrsr()
51 {
52     SwDoc* pDoc = GetDoc();
53     if( !pDoc->IsInDtor() )
54     {
55         // dann muss der Cursor aus dem Array ausgetragen werden
56         SwUnoCrsrTbl& rTbl = (SwUnoCrsrTbl&)pDoc->GetUnoCrsrTbl();
57         sal_uInt16 nDelPos = rTbl.GetPos( this );
58 
59         if( USHRT_MAX != nDelPos )
60             rTbl.Remove( nDelPos );
61         else {
62             ASSERT( !this, "UNO Cursor nicht mehr im Array" );
63         }
64     }
65 
66     // den gesamten Ring loeschen!
67     while( GetNext() != this )
68     {
69         Ring* pNxt = GetNext();
70         pNxt->MoveTo( 0 );      // ausketten
71         delete pNxt;            // und loeschen
72     }
73 }
74 
75 SwUnoCrsr * SwUnoCrsr::Clone() const
76 {
77     SwUnoCrsr * pNewCrsr = GetDoc()->CreateUnoCrsr( *GetPoint() );
78     if (HasMark())
79     {
80         pNewCrsr->SetMark();
81         *pNewCrsr->GetMark() = *GetMark();
82     }
83     return pNewCrsr;
84 }
85 
86 SwUnoTableCrsr * SwUnoTableCrsr::Clone() const
87 {
88     SwUnoTableCrsr * pNewCrsr = dynamic_cast<SwUnoTableCrsr*>(
89         GetDoc()->CreateUnoCrsr(
90             *GetPoint(), sal_True /* create SwUnoTableCrsr */ ) );
91     OSL_ENSURE(pNewCrsr, "Clone: cannot create SwUnoTableCrsr?");
92     if (HasMark())
93     {
94         pNewCrsr->SetMark();
95         *pNewCrsr->GetMark() = *GetMark();
96     }
97     return pNewCrsr;
98 }
99 
100 
101 bool SwUnoCrsr::IsReadOnlyAvailable() const
102 {
103     return true;
104 }
105 
106 const SwCntntFrm*
107 SwUnoCrsr::DoSetBidiLevelLeftRight( sal_Bool &, sal_Bool, sal_Bool )
108 {
109     return 0; // not for uno cursor
110 }
111 
112 void SwUnoCrsr::DoSetBidiLevelUpDown()
113 {
114     return; // not for uno cursor
115 }
116 
117 sal_Bool SwUnoCrsr::IsSelOvr( int eFlags )
118 {
119     if( bRemainInSection )
120     {
121         SwDoc* pDoc = GetDoc();
122         SwNodeIndex aOldIdx( *pDoc->GetNodes()[ GetSavePos()->nNode ] );
123         SwNodeIndex& rPtIdx = GetPoint()->nNode;
124         SwStartNode *pOldSttNd = aOldIdx.GetNode().StartOfSectionNode(),
125                     *pNewSttNd = rPtIdx.GetNode().StartOfSectionNode();
126         if( pOldSttNd != pNewSttNd )
127         {
128             sal_Bool bMoveDown = GetSavePos()->nNode < rPtIdx.GetIndex();
129             sal_Bool bValidPos = sal_False;
130 
131             // search the correct surrounded start node - which the index
132             // can't leave.
133             while( pOldSttNd->IsSectionNode() )
134                 pOldSttNd = pOldSttNd->StartOfSectionNode();
135 
136             // is the new index inside this surrounded section?
137             if( rPtIdx > *pOldSttNd &&
138                 rPtIdx < pOldSttNd->EndOfSectionIndex() )
139             {
140                 // check if it a valid move inside this section
141                 // (only over SwSection's !)
142                 const SwStartNode* pInvalidNode;
143                 do {
144                     pInvalidNode = 0;
145                     pNewSttNd = rPtIdx.GetNode().StartOfSectionNode();
146 
147                     const SwStartNode *pSttNd = pNewSttNd, *pEndNd = pOldSttNd;
148                     if( pSttNd->EndOfSectionIndex() >
149                         pEndNd->EndOfSectionIndex() )
150                     {
151                         pEndNd = pNewSttNd;
152                         pSttNd = pOldSttNd;
153                     }
154 
155                     while( pSttNd->GetIndex() > pEndNd->GetIndex() )
156                     {
157                         if( !pSttNd->IsSectionNode() )
158                             pInvalidNode = pSttNd;
159                         pSttNd = pSttNd->StartOfSectionNode();
160                     }
161                     if( pInvalidNode )
162                     {
163                         if( bMoveDown )
164                         {
165                             rPtIdx.Assign( *pInvalidNode->EndOfSectionNode(), 1 );
166 
167                             if( !rPtIdx.GetNode().IsCntntNode() &&
168                                 ( !pDoc->GetNodes().GoNextSection( &rPtIdx ) ||
169                                   rPtIdx > pOldSttNd->EndOfSectionIndex() ) )
170                                 break;
171                         }
172                         else
173                         {
174                             rPtIdx.Assign( *pInvalidNode, -1 );
175 
176                             if( !rPtIdx.GetNode().IsCntntNode() &&
177                                 ( !pDoc->GetNodes().GoPrevSection( &rPtIdx ) ||
178                                   rPtIdx < *pOldSttNd ) )
179                                 break;
180                         }
181                     }
182                     else
183                         bValidPos = sal_True;
184                 } while ( pInvalidNode );
185             }
186 
187             if( bValidPos )
188             {
189                 SwCntntNode* pCNd = GetCntntNode();
190                 sal_uInt16 nCnt = 0;
191                 if( pCNd && !bMoveDown )
192                     nCnt = pCNd->Len();
193                 GetPoint()->nContent.Assign( pCNd, nCnt );
194             }
195             else
196             {
197                 rPtIdx = GetSavePos()->nNode;
198                 GetPoint()->nContent.Assign( GetCntntNode(), GetSavePos()->nCntnt );
199                 return sal_True;
200             }
201         }
202     }
203     return SwCursor::IsSelOvr( eFlags );
204 }
205 
206 
207 /*  */
208 
209 SwUnoTableCrsr::SwUnoTableCrsr(const SwPosition& rPos)
210     : SwCursor(rPos,0,false), SwUnoCrsr(rPos), SwTableCursor(rPos), aTblSel(rPos,0,false)
211 {
212     SetRemainInSection(sal_False);
213 }
214 
215 SwUnoTableCrsr::~SwUnoTableCrsr()
216 {
217     while( aTblSel.GetNext() != &aTblSel )
218         delete aTblSel.GetNext();           // und loeschen
219 }
220 
221 
222 /*
223 SwCursor* SwUnoTableCrsr::Create( SwPaM* pRing ) const
224 {
225     return SwUnoCrsr::Create( pRing );
226 }
227 */
228 
229 sal_Bool SwUnoTableCrsr::IsSelOvr( int eFlags )
230 {
231     sal_Bool bRet = SwUnoCrsr::IsSelOvr( eFlags );
232     if( !bRet )
233     {
234         const SwTableNode* pTNd = GetPoint()->nNode.GetNode().FindTableNode();
235         bRet = !(pTNd == GetDoc()->GetNodes()[ GetSavePos()->nNode ]->
236                 FindTableNode() && (!HasMark() ||
237                 pTNd == GetMark()->nNode.GetNode().FindTableNode() ));
238     }
239     return bRet;
240 }
241 
242 void SwUnoTableCrsr::MakeBoxSels()
243 {
244     const SwCntntNode* pCNd;
245     bool bMakeTblCrsrs = true;
246     if( GetPoint()->nNode.GetIndex() && GetMark()->nNode.GetIndex() &&
247             0 != ( pCNd = GetCntntNode() ) && pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() ) &&
248             0 != ( pCNd = GetCntntNode(sal_False) ) && pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() ) )
249         bMakeTblCrsrs = GetDoc()->GetCurrentLayout()->MakeTblCrsrs( *this );
250 
251     if ( !bMakeTblCrsrs )
252     {
253         SwSelBoxes& rTmpBoxes = (SwSelBoxes&)GetBoxes();
254         sal_uInt16 nCount = 0;
255         while( nCount < rTmpBoxes.Count() )
256             DeleteBox( nCount );
257     }
258 
259     if( IsChgd() )
260     {
261         SwTableCursor::MakeBoxSels( &aTblSel );
262         if( !GetBoxesCount() )
263         {
264             const SwTableBox* pBox;
265             const SwNode* pBoxNd = GetPoint()->nNode.GetNode().FindTableBoxStartNode();
266             const SwTableNode* pTblNd = pBoxNd ? pBoxNd->FindTableNode() : 0;
267             if( pTblNd && 0 != ( pBox = pTblNd->GetTable().GetTblBox( pBoxNd->GetIndex() )) )
268                 InsertBox( *pBox );
269         }
270     }
271 }
272 
273