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