xref: /aoo42x/main/sw/source/core/crsr/unocrsr.cxx (revision cdf0e10c)
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