merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / edit / eddel.cxx
blob823dee6054255ea5f468f69f37bd06a0478f9b8a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eddel.cxx,v $
10 * $Revision: 1.16 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <doc.hxx>
37 #include <editsh.hxx>
38 #include <cntfrm.hxx>
39 #include <pam.hxx>
40 #include <swundo.hxx> // fuer die UndoIds
41 #include <edimp.hxx>
42 #include <IMark.hxx>
43 #include <docary.hxx>
44 #include <SwRewriter.hxx>
45 #include <undobj.hxx>
46 #include <globals.hrc>
48 #include <comcore.hrc>
49 #include <list>
51 /************************************************************
52 * Loeschen
53 ************************************************************/
55 void SwEditShell::DeleteSel( SwPaM& rPam, BOOL* pUndo )
57 // nur bei Selektion
58 if( !rPam.HasMark() || *rPam.GetPoint() == *rPam.GetMark())
59 return;
61 // besteht eine Selection in einer Tabelle ?
62 // dann nur den Inhalt der selektierten Boxen loeschen
63 // jetzt gibt es 2 Faelle die beachtet werden muessen:
64 // 1. Point und Mark stehen in einer Box, Selection normal loeschen
65 // 2. Point und Mark stehen in unterschiedlichen Boxen, alle
66 // selektierten Boxen suchen in den Inhalt loeschen
67 if( rPam.GetNode()->FindTableNode() &&
68 rPam.GetNode()->StartOfSectionNode() !=
69 rPam.GetNode(FALSE)->StartOfSectionNode() )
71 // in Tabellen das Undo gruppieren
72 if( pUndo && !*pUndo )
74 GetDoc()->StartUndo( UNDO_START, NULL );
75 *pUndo = TRUE;
77 SwPaM aDelPam( *rPam.Start() );
78 const SwPosition* pEndSelPos = rPam.End();
79 do {
80 aDelPam.SetMark();
81 SwNode* pNd = aDelPam.GetNode();
82 const SwNode& rEndNd = *pNd->EndOfSectionNode();
83 if( pEndSelPos->nNode.GetIndex() <= rEndNd.GetIndex() )
85 *aDelPam.GetPoint() = *pEndSelPos;
86 pEndSelPos = 0; // Pointer als Flag missbrauchen
88 else
90 // dann ans Ende der Section
91 aDelPam.GetPoint()->nNode = rEndNd;
92 aDelPam.Move( fnMoveBackward, fnGoCntnt );
94 // geschuetze Boxen ueberspringen !
95 if( !pNd->IsCntntNode() ||
96 !((SwCntntNode*)pNd)->GetFrm()->IsProtected() )
98 // alles loeschen
99 GetDoc()->DeleteAndJoin( aDelPam );
100 SaveTblBoxCntnt( aDelPam.GetPoint() );
103 if( !pEndSelPos ) // am Ende der Selection
104 break;
105 aDelPam.DeleteMark();
106 aDelPam.Move( fnMoveForward, fnGoCntnt ); // naechste Box
107 } while( pEndSelPos );
109 else
111 // alles loeschen
112 GetDoc()->DeleteAndJoin( rPam );
113 SaveTblBoxCntnt( rPam.GetPoint() );
116 // Selection wird nicht mehr benoetigt.
117 rPam.DeleteMark();
121 long SwEditShell::Delete()
123 SET_CURR_SHELL( this );
124 long nRet = 0;
125 if( !HasReadonlySel() )
127 StartAllAction();
129 BOOL bUndo = GetCrsr()->GetNext() != GetCrsr();
130 if( bUndo ) // mehr als eine Selection ?
132 SwRewriter aRewriter;
133 aRewriter.AddRule(UNDO_ARG1, String(SW_RES(STR_MULTISEL)));
135 GetDoc()->StartUndo( UNDO_DELETE, &aRewriter );
138 FOREACHPAM_START(this)
139 DeleteSel( *PCURCRSR, &bUndo );
140 FOREACHPAM_END()
142 // falls eine Undo-Klammerung, dann hier beenden
143 if( bUndo )
144 GetDoc()->EndUndo( UNDO_DELETE, NULL );
145 EndAllAction();
146 nRet = 1;
148 return nRet;
151 long SwEditShell::Copy( SwEditShell* pDestShell )
153 if( !pDestShell )
154 pDestShell = this;
156 SET_CURR_SHELL( pDestShell );
158 // List of insert positions for smart insert of block selections
159 std::list< boost::shared_ptr<SwPosition> > aInsertList;
161 // Fill list of insert positions
163 SwPosition * pPos = 0;
164 boost::shared_ptr<SwPosition> pInsertPos;
165 USHORT nMove = 0;
166 FOREACHPAM_START(this)
168 if( !pPos )
170 if( pDestShell == this )
172 // First cursor represents the target position!!
173 PCURCRSR->DeleteMark();
174 pPos = (SwPosition*)PCURCRSR->GetPoint();
175 continue;
177 else
178 pPos = pDestShell->GetCrsr()->GetPoint();
180 if( IsBlockMode() )
181 { // In block mode different insert positions will be calculated
182 // by simulated cursor movements from the given first insert position
183 if( nMove )
185 SwCursor aCrsr( *pPos, 0, false);
186 if( aCrsr.UpDown( FALSE, nMove, 0, 0 ) )
188 pInsertPos.reset( new SwPosition( *aCrsr.GetPoint() ) );
189 aInsertList.push_back( pInsertPos );
192 else
193 pInsertPos.reset( new SwPosition( *pPos ) );
194 ++nMove;
196 SwPosition *pTmp = IsBlockMode() ? pInsertPos.get() : pPos;
197 // Check if a selection would be copied into itself
198 if( pDestShell->GetDoc() == GetDoc() &&
199 *PCURCRSR->Start() <= *pTmp && *pTmp < *PCURCRSR->End() )
200 return FALSE;
201 FOREACHPAM_END()
204 pDestShell->StartAllAction();
205 SwPosition *pPos = 0;
206 BOOL bRet = FALSE;
207 BOOL bFirstMove = TRUE;
208 SwNodeIndex aSttNdIdx( pDestShell->GetDoc()->GetNodes() );
209 xub_StrLen nSttCntIdx = 0;
210 // For block selection this list is filled with the insert positions
211 std::list< boost::shared_ptr<SwPosition> >::iterator pNextInsert = aInsertList.begin();
213 pDestShell->GetDoc()->StartUndo( UNDO_START, NULL );
214 FOREACHPAM_START(this)
216 if( !pPos )
218 if( pDestShell == this )
220 // First cursor represents the target position!!
221 PCURCRSR->DeleteMark();
222 pPos = (SwPosition*)PCURCRSR->GetPoint();
223 continue;
225 else
226 pPos = pDestShell->GetCrsr()->GetPoint();
228 if( !bFirstMove )
230 if( pNextInsert != aInsertList.end() )
232 pPos = pNextInsert->get();
233 ++pNextInsert;
235 else if( IsBlockMode() )
236 GetDoc()->SplitNode( *pPos, false );
239 // nur bei Selektion (nicht Textnodes haben Selection,
240 // aber Point/GetMark sind gleich
241 if( !PCURCRSR->HasMark() || *PCURCRSR->GetPoint() == *PCURCRSR->GetMark() )
242 continue;
244 if( bFirstMove )
246 // Anfangs-Position vom neuen Bereich merken
247 aSttNdIdx = pPos->nNode.GetIndex()-1;
248 nSttCntIdx = pPos->nContent.GetIndex();
249 bFirstMove = FALSE;
252 const bool bSuccess( GetDoc()->CopyRange( *PCURCRSR, *pPos, false ) );
253 if (!bSuccess)
254 continue;
256 SwPaM aInsertPaM(*pPos, SwPosition(aSttNdIdx));
257 pDestShell->GetDoc()->MakeUniqueNumRules(aInsertPaM);
259 bRet = TRUE;
260 FOREACHPAM_END()
263 // Maybe nothing has been moved?
264 if( !bFirstMove )
266 SwPaM* pCrsr = pDestShell->GetCrsr();
267 pCrsr->SetMark();
268 pCrsr->GetPoint()->nNode = aSttNdIdx.GetIndex()+1;
269 pCrsr->GetPoint()->nContent.Assign( pCrsr->GetCntntNode(),nSttCntIdx);
270 pCrsr->Exchange();
272 else
274 // falls beim Move der Cursor "gewandert" ist, so setze hier auch
275 // seinen GetMark um, damit dieser nie in den Wald zeigt.
276 pDestShell->GetCrsr()->SetMark();
277 pDestShell->GetCrsr()->DeleteMark();
279 #if OSL_DEBUG_LEVEL > 1
280 // pruefe ob die Indizies auch in den richtigen Nodes angemeldet sind
282 SwPaM* pCmp = (SwPaM*)pDestShell->GetCrsr(); // sicher den Pointer auf Cursor
283 do {
284 ASSERT( pCmp->GetPoint()->nContent.GetIdxReg()
285 == pCmp->GetCntntNode(), "Point im falschen Node" );
286 ASSERT( pCmp->GetMark()->nContent.GetIdxReg()
287 == pCmp->GetCntntNode(FALSE), "Mark im falschen Node" );
288 BOOL bTst = *pCmp->GetPoint() == *pCmp->GetMark();
289 (void) bTst;
290 } while( pDestShell->GetCrsr() != ( pCmp = (SwPaM*)pCmp->GetNext() ) );
292 #endif
294 // Undo-Klammerung hier beenden
295 pDestShell->GetDoc()->EndUndo( UNDO_END, NULL );
296 pDestShell->EndAllAction();
298 pDestShell->SaveTblBoxCntnt( pDestShell->GetCrsr()->GetPoint() );
300 return (long)bRet;
304 // Ersetz einen selektierten Bereich in einem TextNode mit dem
305 // String. Ist fuers Suchen&Ersetzen gedacht.
306 // bRegExpRplc - ersetze Tabs (\\t) und setze den gefundenen String
307 // ein ( nicht \& )
308 // z.B.: Fnd: "zzz", Repl: "xx\t\\t..&..\&"
309 // --> "xx\t<Tab>..zzz..&"
310 BOOL SwEditShell::Replace( const String& rNewStr, BOOL bRegExpRplc )
312 SET_CURR_SHELL( this );
314 BOOL bRet = FALSE;
315 if( !HasReadonlySel() )
317 StartAllAction();
318 GetDoc()->StartUndo(UNDO_EMPTY, NULL);
320 FOREACHPAM_START(this)
321 if( PCURCRSR->HasMark() && *PCURCRSR->GetMark() != *PCURCRSR->GetPoint() )
323 bRet = GetDoc()->ReplaceRange( *PCURCRSR, rNewStr, bRegExpRplc )
324 || bRet;
325 SaveTblBoxCntnt( PCURCRSR->GetPoint() );
327 FOREACHPAM_END()
329 // Undo-Klammerung hier beenden
330 GetDoc()->EndUndo(UNDO_EMPTY, NULL);
331 EndAllAction();
333 return bRet;
337 // Special-Methode fuer JOE's- Wizzards
338 BOOL SwEditShell::DelFullPara()
340 BOOL bRet = FALSE;
341 if( !IsTableMode() )
343 SwPaM* pCrsr = GetCrsr();
344 // keine Mehrfach-Selection
345 if( pCrsr->GetNext() == pCrsr && !HasReadonlySel() )
347 SET_CURR_SHELL( this );
348 StartAllAction();
349 bRet = GetDoc()->DelFullPara( *pCrsr );
350 EndAllAction();
353 return bRet;