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 #include <doc.hxx> 32 #include <IDocumentUndoRedo.hxx> 33 #include <editsh.hxx> 34 #include <pam.hxx> 35 #include <ndtxt.hxx> 36 #include <docary.hxx> 37 #include <swwait.hxx> 38 #include <swundo.hxx> // fuer die UndoIds 39 #include <section.hxx> 40 #include <doctxm.hxx> 41 #include <edglbldc.hxx> 42 43 44 SV_IMPL_OP_PTRARR_SORT( SwGlblDocContents, SwGlblDocContentPtr ) 45 46 sal_Bool SwEditShell::IsGlobalDoc() const 47 { 48 return getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT); 49 } 50 51 void SwEditShell::SetGlblDocSaveLinks( sal_Bool bFlag ) 52 { 53 getIDocumentSettingAccess()->set(IDocumentSettingAccess::GLOBAL_DOCUMENT_SAVE_LINKS, bFlag); 54 if( !GetDoc()->IsModified() ) // Bug 57028 55 { 56 GetDoc()->GetIDocumentUndoRedo().SetUndoNoResetModified(); 57 } 58 GetDoc()->SetModified(); 59 } 60 61 sal_Bool SwEditShell::IsGlblDocSaveLinks() const 62 { 63 return getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT_SAVE_LINKS); 64 } 65 66 sal_uInt16 SwEditShell::GetGlobalDocContent( SwGlblDocContents& rArr ) const 67 { 68 if( rArr.Count() ) 69 rArr.DeleteAndDestroy( 0, rArr.Count() ); 70 71 if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) 72 return 0; 73 74 // dann alle gelinkten Bereiche auf der obersten Ebene 75 SwDoc* pMyDoc = GetDoc(); 76 const SwSectionFmts& rSectFmts = pMyDoc->GetSections(); 77 sal_uInt16 n; 78 79 for( n = rSectFmts.Count(); n; ) 80 { 81 const SwSection* pSect = rSectFmts[ --n ]->GetGlobalDocSection(); 82 if( pSect ) 83 { 84 SwGlblDocContentPtr pNew; 85 switch( pSect->GetType() ) 86 { 87 case TOX_HEADER_SECTION: break; // ignore 88 case TOX_CONTENT_SECTION: 89 ASSERT( pSect->ISA( SwTOXBaseSection ), "keine TOXBaseSection!" ); 90 pNew = new SwGlblDocContent( (SwTOXBaseSection*)pSect ); 91 break; 92 93 default: 94 pNew = new SwGlblDocContent( pSect ); 95 break; 96 } 97 if( !rArr.Insert( pNew ) ) 98 delete pNew; 99 } 100 } 101 102 // und als letztes die Dummies (sonstiger Text) einfuegen 103 SwNode* pNd; 104 sal_uLong nSttIdx = pMyDoc->GetNodes().GetEndOfExtras().GetIndex() + 2; 105 for( n = 0; n < rArr.Count(); ++n ) 106 { 107 const SwGlblDocContent& rNew = *rArr[ n ]; 108 // suche von StartPos bis rNew.DocPos nach einem Content Node. 109 // Existiert dieser, so muss ein DummyEintrag eingefuegt werden. 110 for( ; nSttIdx < rNew.GetDocPos(); ++nSttIdx ) 111 if( ( pNd = pMyDoc->GetNodes()[ nSttIdx ])->IsCntntNode() 112 || pNd->IsSectionNode() || pNd->IsTableNode() ) 113 { 114 SwGlblDocContentPtr pNew = new SwGlblDocContent( nSttIdx ); 115 if( !rArr.Insert( pNew ) ) 116 delete pNew; 117 else 118 ++n; // auf die naechste Position 119 break; 120 } 121 122 // StartPosition aufs Ende setzen 123 nSttIdx = pMyDoc->GetNodes()[ rNew.GetDocPos() ]->EndOfSectionIndex(); 124 ++nSttIdx; 125 } 126 127 // sollte man das Ende auch noch setzen?? 128 if( rArr.Count() ) 129 { 130 sal_uLong nNdEnd = pMyDoc->GetNodes().GetEndOfContent().GetIndex(); 131 for( ; nSttIdx < nNdEnd; ++nSttIdx ) 132 if( ( pNd = pMyDoc->GetNodes()[ nSttIdx ])->IsCntntNode() 133 || pNd->IsSectionNode() || pNd->IsTableNode() ) 134 { 135 SwGlblDocContentPtr pNew = new SwGlblDocContent( nSttIdx ); 136 if( !rArr.Insert( pNew ) ) 137 delete pNew; 138 break; 139 } 140 } 141 else 142 { 143 SwGlblDocContentPtr pNew = new SwGlblDocContent( 144 pMyDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 ); 145 rArr.Insert( pNew ); 146 } 147 return rArr.Count(); 148 } 149 150 sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos, 151 SwSectionData & rNew) 152 { 153 if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) 154 return sal_False; 155 156 SET_CURR_SHELL( this ); 157 StartAllAction(); 158 159 SwPaM* pCrsr = GetCrsr(); 160 if( pCrsr->GetNext() != pCrsr || IsTableMode() ) 161 ClearMark(); 162 163 SwPosition& rPos = *pCrsr->GetPoint(); 164 rPos.nNode = rInsPos.GetDocPos(); 165 166 sal_Bool bEndUndo = sal_False; 167 SwDoc* pMyDoc = GetDoc(); 168 SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode(); 169 if( pTxtNd ) 170 rPos.nContent.Assign( pTxtNd, 0 ); 171 else 172 { 173 bEndUndo = sal_True; 174 pMyDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL ); 175 rPos.nNode--; 176 pMyDoc->AppendTxtNode( rPos ); 177 pCrsr->SetMark(); 178 } 179 180 InsertSection( rNew ); 181 182 if( bEndUndo ) 183 { 184 pMyDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL ); 185 } 186 EndAllAction(); 187 188 return sal_True; 189 } 190 191 sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos, 192 const SwTOXBase& rTOX ) 193 { 194 if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) 195 return sal_False; 196 197 SET_CURR_SHELL( this ); 198 StartAllAction(); 199 200 SwPaM* pCrsr = GetCrsr(); 201 if( pCrsr->GetNext() != pCrsr || IsTableMode() ) 202 ClearMark(); 203 204 SwPosition& rPos = *pCrsr->GetPoint(); 205 rPos.nNode = rInsPos.GetDocPos(); 206 207 sal_Bool bEndUndo = sal_False; 208 SwDoc* pMyDoc = GetDoc(); 209 SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode(); 210 if( pTxtNd && pTxtNd->GetTxt().Len() && rPos.nNode.GetIndex() + 1 != 211 pMyDoc->GetNodes().GetEndOfContent().GetIndex() ) 212 rPos.nContent.Assign( pTxtNd, 0 ); 213 else 214 { 215 bEndUndo = sal_True; 216 pMyDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL ); 217 rPos.nNode--; 218 pMyDoc->AppendTxtNode( rPos ); 219 } 220 221 InsertTableOf( rTOX ); 222 223 if( bEndUndo ) 224 { 225 pMyDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL ); 226 } 227 EndAllAction(); 228 229 return sal_True; 230 } 231 232 sal_Bool SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos ) 233 { 234 if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) 235 return sal_False; 236 237 SET_CURR_SHELL( this ); 238 StartAllAction(); 239 240 SwPaM* pCrsr = GetCrsr(); 241 if( pCrsr->GetNext() != pCrsr || IsTableMode() ) 242 ClearMark(); 243 244 SwPosition& rPos = *pCrsr->GetPoint(); 245 rPos.nNode = rInsPos.GetDocPos() - 1; 246 rPos.nContent.Assign( 0, 0 ); 247 248 SwDoc* pMyDoc = GetDoc(); 249 pMyDoc->AppendTxtNode( rPos ); 250 EndAllAction(); 251 return sal_True; 252 } 253 254 sal_Bool SwEditShell::DeleteGlobalDocContent( const SwGlblDocContents& rArr , 255 sal_uInt16 nDelPos ) 256 { 257 if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) 258 return sal_False; 259 260 SET_CURR_SHELL( this ); 261 StartAllAction(); 262 StartUndo( UNDO_START ); 263 264 SwPaM* pCrsr = GetCrsr(); 265 if( pCrsr->GetNext() != pCrsr || IsTableMode() ) 266 ClearMark(); 267 268 SwPosition& rPos = *pCrsr->GetPoint(); 269 270 SwDoc* pMyDoc = GetDoc(); 271 const SwGlblDocContent& rDelPos = *rArr[ nDelPos ]; 272 sal_uLong nDelIdx = rDelPos.GetDocPos(); 273 if( 1 == rArr.Count() ) 274 { 275 // ein Node muss aber da bleiben! 276 rPos.nNode = nDelIdx - 1; 277 rPos.nContent.Assign( 0, 0 ); 278 279 pMyDoc->AppendTxtNode( rPos ); 280 ++nDelIdx; 281 } 282 283 switch( rDelPos.GetType() ) 284 { 285 case GLBLDOC_UNKNOWN: 286 { 287 rPos.nNode = nDelIdx; 288 pCrsr->SetMark(); 289 if( ++nDelPos < rArr.Count() ) 290 rPos.nNode = rArr[ nDelPos ]->GetDocPos(); 291 else 292 rPos.nNode = pMyDoc->GetNodes().GetEndOfContent(); 293 rPos.nNode--; 294 if( !pMyDoc->DelFullPara( *pCrsr ) ) 295 Delete(); 296 } 297 break; 298 299 case GLBLDOC_TOXBASE: 300 { 301 SwTOXBaseSection* pTOX = (SwTOXBaseSection*)rDelPos.GetTOX(); 302 pMyDoc->DeleteTOX( *pTOX, sal_True ); 303 } 304 break; 305 306 case GLBLDOC_SECTION: 307 { 308 SwSectionFmt* pSectFmt = (SwSectionFmt*)rDelPos.GetSection()->GetFmt(); 309 pMyDoc->DelSectionFmt( pSectFmt, sal_True ); 310 } 311 break; 312 } 313 314 EndUndo( UNDO_END ); 315 EndAllAction(); 316 return sal_True; 317 } 318 319 sal_Bool SwEditShell::MoveGlobalDocContent( const SwGlblDocContents& rArr , 320 sal_uInt16 nFromPos, sal_uInt16 nToPos, 321 sal_uInt16 nInsPos ) 322 { 323 if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) || 324 nFromPos >= rArr.Count() || nToPos > rArr.Count() || 325 nInsPos > rArr.Count() || nFromPos >= nToPos || 326 ( nFromPos <= nInsPos && nInsPos <= nToPos ) ) 327 return sal_False; 328 329 SET_CURR_SHELL( this ); 330 StartAllAction(); 331 332 SwPaM* pCrsr = GetCrsr(); 333 if( pCrsr->GetNext() != pCrsr || IsTableMode() ) 334 ClearMark(); 335 336 SwDoc* pMyDoc = GetDoc(); 337 SwNodeRange aRg( pMyDoc->GetNodes(), rArr[ nFromPos ]->GetDocPos() ); 338 if( nToPos < rArr.Count() ) 339 aRg.aEnd = rArr[ nToPos ]->GetDocPos(); 340 else 341 aRg.aEnd = pMyDoc->GetNodes().GetEndOfContent(); 342 343 SwNodeIndex aInsPos( pMyDoc->GetNodes() ); 344 if( nInsPos < rArr.Count() ) 345 aInsPos = rArr[ nInsPos ]->GetDocPos(); 346 else 347 aInsPos = pMyDoc->GetNodes().GetEndOfContent(); 348 349 bool bRet = pMyDoc->MoveNodeRange( aRg, aInsPos, 350 static_cast<IDocumentContentOperations::SwMoveFlags>( 351 IDocumentContentOperations::DOC_MOVEALLFLYS 352 | IDocumentContentOperations::DOC_CREATEUNDOOBJ )); 353 354 EndAllAction(); 355 return bRet; 356 } 357 358 sal_Bool SwEditShell::GotoGlobalDocContent( const SwGlblDocContent& rPos ) 359 { 360 if( !getIDocumentSettingAccess()->get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) 361 return sal_False; 362 363 SET_CURR_SHELL( this ); 364 SttCrsrMove(); 365 366 SwPaM* pCrsr = GetCrsr(); 367 if( pCrsr->GetNext() != pCrsr || IsTableMode() ) 368 ClearMark(); 369 370 SwPosition& rCrsrPos = *pCrsr->GetPoint(); 371 rCrsrPos.nNode = rPos.GetDocPos(); 372 373 SwDoc* pMyDoc = GetDoc(); 374 SwCntntNode * pCNd = rCrsrPos.nNode.GetNode().GetCntntNode(); 375 if( !pCNd ) 376 pCNd = pMyDoc->GetNodes().GoNext( &rCrsrPos.nNode ); 377 378 rCrsrPos.nContent.Assign( pCNd, 0 ); 379 380 EndCrsrMove(); 381 return sal_True; 382 } 383 384 SwGlblDocContent::SwGlblDocContent( sal_uLong nPos ) 385 { 386 eType = GLBLDOC_UNKNOWN; 387 PTR.pTOX = 0; 388 nDocPos = nPos; 389 } 390 391 SwGlblDocContent::SwGlblDocContent( const SwTOXBaseSection* pTOX ) 392 { 393 eType = GLBLDOC_TOXBASE; 394 PTR.pTOX = pTOX; 395 396 const SwSectionNode* pSectNd = pTOX->GetFmt()->GetSectionNode(); 397 nDocPos = pSectNd ? pSectNd->GetIndex() : 0; 398 } 399 400 SwGlblDocContent::SwGlblDocContent( const SwSection* pSect ) 401 { 402 eType = GLBLDOC_SECTION; 403 PTR.pSect = pSect; 404 405 const SwSectionNode* pSectNd = pSect->GetFmt()->GetSectionNode(); 406 nDocPos = pSectNd ? pSectNd->GetIndex() : 0; 407 } 408 409 410 411