xref: /aoo42x/main/sw/source/core/edit/eddel.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 <hintids.hxx>
33 #include <doc.hxx>
34 #include <IDocumentUndoRedo.hxx>
35 #include <editsh.hxx>
36 #include <cntfrm.hxx>
37 #include <pam.hxx>
38 #include <swundo.hxx>		// fuer die UndoIds
39 #include <edimp.hxx>
40 #include <IMark.hxx>
41 #include <docary.hxx>
42 #include <SwRewriter.hxx>
43 #include <globals.hrc>
44 
45 #include <comcore.hrc>
46 #include <list>
47 
48 /************************************************************
49  * Loeschen
50  ************************************************************/
51 
52 void SwEditShell::DeleteSel( SwPaM& rPam, sal_Bool* pUndo )
53 {
54 	// nur bei Selektion
55 	if( !rPam.HasMark() || *rPam.GetPoint() == *rPam.GetMark())
56 		return;
57 
58 	// besteht eine Selection in einer Tabelle ?
59 	// dann nur den Inhalt der selektierten Boxen loeschen
60 	// jetzt gibt es 2 Faelle die beachtet werden muessen:
61 	//	1. Point und Mark stehen in einer Box, Selection normal loeschen
62 	//	2. Point und Mark stehen in unterschiedlichen Boxen, alle
63 	// selektierten Boxen suchen in den Inhalt loeschen
64 	if( rPam.GetNode()->FindTableNode() &&
65 		rPam.GetNode()->StartOfSectionNode() !=
66 		rPam.GetNode(sal_False)->StartOfSectionNode() )
67 	{
68 		// in Tabellen das Undo gruppieren
69 		if( pUndo && !*pUndo )
70         {
71             GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
72 			*pUndo = sal_True;
73 		}
74 		SwPaM aDelPam( *rPam.Start() );
75 		const SwPosition* pEndSelPos = rPam.End();
76 		do {
77 			aDelPam.SetMark();
78 			SwNode* pNd = aDelPam.GetNode();
79 			const SwNode& rEndNd = *pNd->EndOfSectionNode();
80 			if( pEndSelPos->nNode.GetIndex() <= rEndNd.GetIndex() )
81 			{
82 				*aDelPam.GetPoint() = *pEndSelPos;
83 				pEndSelPos = 0;		// Pointer als Flag missbrauchen
84 			}
85 			else
86 			{
87 				// dann ans Ende der Section
88 				aDelPam.GetPoint()->nNode = rEndNd;
89 				aDelPam.Move( fnMoveBackward, fnGoCntnt );
90 			}
91 				// geschuetze Boxen ueberspringen !
92 			if( !pNd->IsCntntNode() ||
93 				!((SwCntntNode*)pNd)->getLayoutFrm( GetLayout() )->IsProtected() )
94 			{
95 				// alles loeschen
96 				GetDoc()->DeleteAndJoin( aDelPam );
97 				SaveTblBoxCntnt( aDelPam.GetPoint() );
98 			}
99 
100 			if( !pEndSelPos )				// am Ende der Selection
101 				break;
102 			aDelPam.DeleteMark();
103 			aDelPam.Move( fnMoveForward, fnGoCntnt );	// naechste Box
104 		} while( pEndSelPos );
105 	}
106 	else
107 	{
108 			// alles loeschen
109 		GetDoc()->DeleteAndJoin( rPam );
110 		SaveTblBoxCntnt( rPam.GetPoint() );
111 	}
112 
113 	// Selection wird nicht mehr benoetigt.
114 	rPam.DeleteMark();
115 }
116 
117 
118 long SwEditShell::Delete()
119 {
120 	SET_CURR_SHELL( this );
121 	long nRet = 0;
122 	if( !HasReadonlySel() )
123 	{
124 		StartAllAction();
125 
126 		sal_Bool bUndo = GetCrsr()->GetNext() != GetCrsr();
127 		if( bUndo )     // mehr als eine Selection ?
128         {
129             SwRewriter aRewriter;
130             aRewriter.AddRule(UNDO_ARG1, String(SW_RES(STR_MULTISEL)));
131 
132             GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_DELETE, &aRewriter);
133         }
134 
135 		FOREACHPAM_START(this)
136 			DeleteSel( *PCURCRSR, &bUndo );
137 		FOREACHPAM_END()
138 
139 		// falls eine Undo-Klammerung, dann hier beenden
140 		if( bUndo )
141         {
142             GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_END, 0);
143         }
144 		EndAllAction();
145 		nRet = 1;
146 	}
147 	return nRet;
148 }
149 
150 long SwEditShell::Copy( SwEditShell* pDestShell )
151 {
152 	if( !pDestShell )
153 		pDestShell = this;
154 
155 	SET_CURR_SHELL( pDestShell );
156 
157 	// List of insert positions for smart insert of block selections
158 	std::list< boost::shared_ptr<SwPosition> > aInsertList;
159 
160 	// Fill list of insert positions
161 	{
162 		SwPosition * pPos = 0;
163 		boost::shared_ptr<SwPosition> pInsertPos;
164 		sal_uInt16 nMove = 0;
165 		FOREACHPAM_START(this)
166 
167 			if( !pPos )
168 			{
169 				if( pDestShell == this )
170 				{
171 					// First cursor represents the target position!!
172 					PCURCRSR->DeleteMark();
173 					pPos = (SwPosition*)PCURCRSR->GetPoint();
174 					continue;
175 				}
176 				else
177 					pPos = pDestShell->GetCrsr()->GetPoint();
178 			}
179 			if( IsBlockMode() )
180 			{	// In block mode different insert positions will be calculated
181 				// by simulated cursor movements from the given first insert position
182 				if( nMove )
183 				{
184 					SwCursor aCrsr( *pPos, 0, false);
185 					if( aCrsr.UpDown( sal_False, nMove, 0, 0 ) )
186 					{
187 						pInsertPos.reset( new SwPosition( *aCrsr.GetPoint() ) );
188 						aInsertList.push_back( pInsertPos );
189 					}
190 				}
191 				else
192 					pInsertPos.reset( new SwPosition( *pPos ) );
193 				++nMove;
194 			}
195 			SwPosition *pTmp = IsBlockMode() ? pInsertPos.get() : pPos;
196 			// Check if a selection would be copied into itself
197 			if( pDestShell->GetDoc() == GetDoc() &&
198 				*PCURCRSR->Start() <= *pTmp && *pTmp < *PCURCRSR->End() )
199 				return sal_False;
200 		FOREACHPAM_END()
201 	}
202 
203 	pDestShell->StartAllAction();
204 	SwPosition *pPos = 0;
205 	sal_Bool bRet = sal_False;
206 	sal_Bool bFirstMove = sal_True;
207 	SwNodeIndex aSttNdIdx( pDestShell->GetDoc()->GetNodes() );
208 	xub_StrLen nSttCntIdx = 0;
209 	// For block selection this list is filled with the insert positions
210 	std::list< boost::shared_ptr<SwPosition> >::iterator pNextInsert = aInsertList.begin();
211 
212     pDestShell->GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
213 	FOREACHPAM_START(this)
214 
215 		if( !pPos )
216 		{
217 			if( pDestShell == this )
218 			{
219 				// First cursor represents the target position!!
220 				PCURCRSR->DeleteMark();
221 				pPos = (SwPosition*)PCURCRSR->GetPoint();
222 				continue;
223 			}
224 			else
225 				pPos = pDestShell->GetCrsr()->GetPoint();
226 		}
227 		if( !bFirstMove )
228 		{
229 			if( pNextInsert != aInsertList.end() )
230 			{
231 				pPos = pNextInsert->get();
232 				++pNextInsert;
233 			}
234 			else if( IsBlockMode() )
235 				GetDoc()->SplitNode( *pPos, false );
236 		}
237 
238 		// nur bei Selektion (nicht Textnodes haben Selection,
239 		// aber Point/GetMark sind gleich
240 		if( !PCURCRSR->HasMark() || *PCURCRSR->GetPoint() == *PCURCRSR->GetMark() )
241 			continue;
242 
243 		if( bFirstMove )
244 		{
245 			// Anfangs-Position vom neuen Bereich merken
246 			aSttNdIdx = pPos->nNode.GetIndex()-1;
247 			nSttCntIdx = pPos->nContent.GetIndex();
248 			bFirstMove = sal_False;
249 		}
250 
251         const bool bSuccess( GetDoc()->CopyRange( *PCURCRSR, *pPos, false ) );
252         if (!bSuccess)
253 			continue;
254 
255         SwPaM aInsertPaM(*pPos, SwPosition(aSttNdIdx));
256         pDestShell->GetDoc()->MakeUniqueNumRules(aInsertPaM);
257 
258 		bRet = sal_True;
259 	FOREACHPAM_END()
260 
261 
262 	// Maybe nothing has been moved?
263 	if( !bFirstMove )
264 	{
265 		SwPaM* pCrsr = pDestShell->GetCrsr();
266 		pCrsr->SetMark();
267 		pCrsr->GetPoint()->nNode = aSttNdIdx.GetIndex()+1;
268 		pCrsr->GetPoint()->nContent.Assign( pCrsr->GetCntntNode(),nSttCntIdx);
269 		pCrsr->Exchange();
270 	}
271 	else
272 	{
273 		// falls beim Move der Cursor "gewandert" ist, so setze hier auch
274 		// seinen GetMark um, damit dieser nie in den Wald zeigt.
275 		pDestShell->GetCrsr()->SetMark();
276 		pDestShell->GetCrsr()->DeleteMark();
277 	}
278 #if OSL_DEBUG_LEVEL > 1
279 // pruefe ob die Indizies auch in den richtigen Nodes angemeldet sind
280 {
281 	SwPaM* pCmp = (SwPaM*)pDestShell->GetCrsr();        // sicher den Pointer auf Cursor
282 	do {
283 		ASSERT( pCmp->GetPoint()->nContent.GetIdxReg()
284 					== pCmp->GetCntntNode(), "Point im falschen Node" );
285 		ASSERT( pCmp->GetMark()->nContent.GetIdxReg()
286 					== pCmp->GetCntntNode(sal_False), "Mark im falschen Node" );
287 		sal_Bool bTst = *pCmp->GetPoint() == *pCmp->GetMark();
288         (void) bTst;
289 	} while( pDestShell->GetCrsr() != ( pCmp = (SwPaM*)pCmp->GetNext() ) );
290 }
291 #endif
292 
293 	// Undo-Klammerung hier beenden
294     pDestShell->GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
295 	pDestShell->EndAllAction();
296 
297 	pDestShell->SaveTblBoxCntnt( pDestShell->GetCrsr()->GetPoint() );
298 
299 	return (long)bRet;
300 }
301 
302 
303 	// Ersetz einen selektierten Bereich in einem TextNode mit dem
304 	// String. Ist fuers Suchen&Ersetzen gedacht.
305 	// bRegExpRplc - ersetze Tabs (\\t) und setze den gefundenen String
306 	//				 ein ( nicht \& )
307 	// 				z.B.: Fnd: "zzz", Repl: "xx\t\\t..&..\&"
308 	//						--> "xx\t<Tab>..zzz..&"
309 sal_Bool SwEditShell::Replace( const String& rNewStr, sal_Bool bRegExpRplc )
310 {
311 	SET_CURR_SHELL( this );
312 
313 	sal_Bool bRet = sal_False;
314 	if( !HasReadonlySel() )
315 	{
316 		StartAllAction();
317         GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
318 
319 		FOREACHPAM_START(this)
320 			if( PCURCRSR->HasMark() && *PCURCRSR->GetMark() != *PCURCRSR->GetPoint() )
321 			{
322                 bRet = GetDoc()->ReplaceRange( *PCURCRSR, rNewStr, bRegExpRplc )
323                     || bRet;
324 				SaveTblBoxCntnt( PCURCRSR->GetPoint() );
325 			}
326 		FOREACHPAM_END()
327 
328 		// Undo-Klammerung hier beenden
329         GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
330 		EndAllAction();
331 	}
332 	return bRet;
333 }
334 
335 
336 	// Special-Methode fuer JOE's- Wizzards
337 sal_Bool SwEditShell::DelFullPara()
338 {
339 	sal_Bool bRet = sal_False;
340 	if( !IsTableMode() )
341 	{
342 		SwPaM* pCrsr = GetCrsr();
343 		// keine Mehrfach-Selection
344 		if( pCrsr->GetNext() == pCrsr && !HasReadonlySel() )
345 		{
346 			SET_CURR_SHELL( this );
347 			StartAllAction();
348 			bRet = GetDoc()->DelFullPara( *pCrsr );
349 			EndAllAction();
350 		}
351 	}
352 	return bRet;
353 }
354 
355 
356 
357