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