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