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