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 // 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 117 long SwEditShell::Delete() 118 { 119 SET_CURR_SHELL( this ); 120 long nRet = 0; 121 if( !HasReadonlySel() ) 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 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..&" 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 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