Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/embed/ElementModes.hpp>
21 : #include <com/sun/star/embed/XTransactedObject.hpp>
22 : #include <rtl/ustring.hxx>
23 : #include <sot/stg.hxx>
24 : #include <sfx2/docfile.hxx>
25 : #include <tools/urlobj.hxx>
26 : #include <unotools/localfilehelper.hxx>
27 : #include <unotools/ucbstreamhelper.hxx>
28 :
29 : #include <comphelper/storagehelper.hxx>
30 : #include <doc.hxx>
31 : #include <IDocumentUndoRedo.hxx>
32 : #include <IDocumentStylePoolAccess.hxx>
33 : #include <docsh.hxx>
34 : #include <pam.hxx>
35 : #include <swblocks.hxx>
36 : #include <ndtxt.hxx>
37 : #include <shellio.hxx>
38 : #include <poolfmt.hxx>
39 : #include <SwXMLTextBlocks.hxx>
40 : #include <SwXMLBlockImport.hxx>
41 : #include <SwXMLBlockExport.hxx>
42 : #include <swerror.h>
43 :
44 : using namespace ::com::sun::star;
45 :
46 87 : void SwXMLTextBlocks::InitBlockMode ( const uno::Reference < embed::XStorage >& rStorage )
47 : {
48 87 : xBlkRoot = rStorage;
49 87 : xRoot = 0;
50 87 : }
51 :
52 144 : void SwXMLTextBlocks::ResetBlockMode ( )
53 : {
54 144 : xBlkRoot = 0;
55 144 : xRoot = 0;
56 144 : }
57 :
58 61 : SwXMLTextBlocks::SwXMLTextBlocks( const OUString& rFile )
59 : : SwImpBlocks(rFile)
60 : , bAutocorrBlock(false)
61 : , bBlock(false)
62 : , nFlags(0)
63 61 : , nCurBlk(0)
64 : {
65 61 : SwDocShell* pDocSh = new SwDocShell ( SfxObjectCreateMode::INTERNAL );
66 61 : if( !pDocSh->DoInitNew( 0 ) )
67 61 : return;
68 61 : bReadOnly = true;
69 61 : pDoc = pDocSh->GetDoc();
70 61 : xDocShellRef = pDocSh;
71 61 : pDoc->SetOle2Link( Link<>() );
72 61 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
73 61 : pDoc->acquire();
74 61 : uno::Reference< embed::XStorage > refStg;
75 61 : if( !aDateModified.GetDate() || !aTimeModified.GetTime() )
76 2 : Touch(); // If it's created anew -> get a new timestamp
77 :
78 : try
79 : {
80 61 : refStg = comphelper::OStorageHelper::GetStorageFromURL( rFile, embed::ElementModes::READWRITE );
81 61 : bReadOnly = false;
82 : }
83 0 : catch(const uno::Exception&)
84 : {
85 : //FIXME: couldn't open the file - maybe it's readonly
86 : }
87 61 : if( !refStg.is())
88 : {
89 : try
90 : {
91 0 : refStg = comphelper::OStorageHelper::GetStorageFromURL( rFile, embed::ElementModes::READ );
92 : }
93 0 : catch(const uno::Exception&)
94 : {
95 : OSL_FAIL("exception while creating AutoText storage");
96 : }
97 : }
98 61 : InitBlockMode ( refStg );
99 61 : ReadInfo();
100 61 : ResetBlockMode ();
101 61 : bInfoChanged = false;
102 : }
103 :
104 2 : SwXMLTextBlocks::SwXMLTextBlocks( const uno::Reference < embed::XStorage >& rStg, const OUString& rName )
105 : : SwImpBlocks( rName )
106 : , bAutocorrBlock(false)
107 : , bBlock(false)
108 : , nFlags(0)
109 2 : , nCurBlk(0)
110 : {
111 2 : SwDocShell* pDocSh = new SwDocShell ( SfxObjectCreateMode::INTERNAL );
112 2 : if( !pDocSh->DoInitNew( 0 ) )
113 2 : return;
114 2 : bReadOnly = false;
115 2 : pDoc = pDocSh->GetDoc();
116 2 : xDocShellRef = pDocSh;
117 2 : pDoc->SetOle2Link( Link<>() );
118 2 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
119 2 : pDoc->acquire();
120 :
121 2 : InitBlockMode ( rStg );
122 2 : ReadInfo();
123 2 : bInfoChanged = false;
124 : }
125 :
126 189 : SwXMLTextBlocks::~SwXMLTextBlocks()
127 : {
128 63 : if ( bInfoChanged )
129 4 : WriteInfo();
130 63 : ResetBlockMode ();
131 63 : if(xDocShellRef.Is())
132 63 : xDocShellRef->DoClose();
133 63 : xDocShellRef = 0;
134 63 : if( pDoc && !pDoc->release() )
135 63 : delete pDoc;
136 126 : }
137 :
138 13 : void SwXMLTextBlocks::ClearDoc()
139 : {
140 13 : SwDocShell * pDocShell = pDoc->GetDocShell();
141 13 : pDocShell->InvalidateModel();
142 13 : pDocShell->ReactivateModel();
143 :
144 13 : pDoc->ClearDoc();
145 13 : pDocShell->ClearEmbeddedObjects();
146 13 : }
147 :
148 7 : void SwXMLTextBlocks::AddName( const OUString& rShort, const OUString& rLong, bool bOnlyText )
149 : {
150 7 : aPackageName = GeneratePackageName( rShort );
151 7 : AddName(rShort, rLong, aPackageName, bOnlyText);
152 7 : }
153 :
154 47 : void SwXMLTextBlocks::AddName( const OUString& rShort, const OUString& rLong,
155 : const OUString& rPackageName, bool bOnlyText )
156 : {
157 47 : sal_uInt16 nIdx = GetIndex( rShort );
158 47 : if (nIdx != USHRT_MAX)
159 : {
160 0 : delete aNames[nIdx];
161 0 : aNames.erase( aNames.begin() + nIdx );
162 : }
163 47 : SwBlockName* pNew = new SwBlockName( rShort, rLong, rPackageName );
164 47 : pNew->bIsOnlyTextFlagInit = true;
165 47 : pNew->bIsOnlyText = bOnlyText;
166 47 : aNames.insert( pNew );
167 47 : bInfoChanged = true;
168 47 : }
169 :
170 5 : sal_uLong SwXMLTextBlocks::Delete( sal_uInt16 n )
171 : {
172 5 : const OUString aPckName (aNames[n]->aPackageName);
173 10 : uno::Reference < container::XNameAccess > xAccess( xBlkRoot, uno::UNO_QUERY );
174 15 : if ( xAccess.is() &&
175 10 : xAccess->hasByName( aPckName ) && xBlkRoot->isStreamElement( aPckName ) )
176 : {
177 : try
178 : {
179 0 : xBlkRoot->removeElement ( aPckName );
180 0 : uno::Reference < embed::XTransactedObject > xTrans( xBlkRoot, uno::UNO_QUERY );
181 0 : if ( xTrans.is() )
182 0 : xTrans->commit();
183 0 : return 0;
184 : }
185 0 : catch (const uno::Exception&)
186 : {
187 0 : return ERR_SWG_WRITE_ERROR;
188 : }
189 : }
190 10 : return 0;
191 : }
192 :
193 1 : sal_uLong SwXMLTextBlocks::Rename( sal_uInt16 nIdx, const OUString& rNewShort, const OUString& )
194 : {
195 : OSL_ENSURE( xBlkRoot.is(), "No storage set" );
196 1 : if(!xBlkRoot.is())
197 0 : return 0;
198 1 : OUString aOldName (aNames[nIdx]->aPackageName);
199 1 : aShort = rNewShort;
200 1 : aPackageName = GeneratePackageName( aShort );
201 :
202 1 : if(aOldName != aPackageName)
203 : {
204 1 : if (IsOnlyTextBlock ( nIdx ) )
205 : {
206 1 : OUString sExt(".xml");
207 2 : OUString aOldStreamName( aOldName ); aOldStreamName += sExt;
208 2 : OUString aNewStreamName( aPackageName ); aNewStreamName += sExt;
209 :
210 1 : xRoot = xBlkRoot->openStorageElement( aOldName, embed::ElementModes::READWRITE );
211 : try
212 : {
213 1 : xRoot->renameElement ( aOldStreamName, aNewStreamName );
214 : }
215 0 : catch(const container::ElementExistException&)
216 : {
217 : SAL_WARN("sw", "Couldn't rename " << aOldStreamName << " to " << aNewStreamName);
218 : }
219 2 : uno::Reference < embed::XTransactedObject > xTrans( xRoot, uno::UNO_QUERY );
220 1 : if ( xTrans.is() )
221 1 : xTrans->commit();
222 2 : xRoot = 0;
223 : }
224 :
225 : try
226 : {
227 1 : xBlkRoot->renameElement ( aOldName, aPackageName );
228 : }
229 0 : catch(const container::ElementExistException&)
230 : {
231 : SAL_WARN("sw", "Couldn't rename " << aOldName << " to " << aPackageName);
232 : }
233 : }
234 2 : uno::Reference < embed::XTransactedObject > xTrans( xBlkRoot, uno::UNO_QUERY );
235 1 : if ( xTrans.is() )
236 1 : xTrans->commit();
237 : // No need to commit xBlkRoot here as SwTextBlocks::Rename calls
238 : // WriteInfo which does the commit
239 2 : return 0;
240 : }
241 :
242 0 : sal_uLong SwXMLTextBlocks::CopyBlock( SwImpBlocks& rDestImp, OUString& rShort,
243 : const OUString& rLong)
244 : {
245 0 : sal_uLong nError = 0;
246 0 : OpenFile(true);
247 0 : rDestImp.OpenFile(false);
248 0 : const OUString aGroup( rShort );
249 0 : bool bTextOnly = IsOnlyTextBlock ( rShort ) ;//pImp->pBlkRoot->IsStream( aGroup );
250 0 : sal_uInt16 nIndex = GetIndex ( rShort );
251 0 : OUString sDestShortName( GetPackageName (nIndex) );
252 0 : sal_uInt16 nIdx = 0;
253 :
254 : OSL_ENSURE( xBlkRoot.is(), "No storage set" );
255 0 : if(!xBlkRoot.is())
256 0 : return ERR_SWG_WRITE_ERROR;
257 :
258 0 : uno::Reference < container::XNameAccess > xAccess( static_cast<SwXMLTextBlocks&>(rDestImp).xBlkRoot, uno::UNO_QUERY );
259 0 : while ( xAccess->hasByName( sDestShortName ) )
260 : {
261 0 : ++nIdx;
262 : // If someone is that crazy ...
263 0 : if(USHRT_MAX == nIdx)
264 : {
265 0 : CloseFile();
266 0 : rDestImp.CloseFile();
267 0 : return ERR_SWG_WRITE_ERROR;
268 : }
269 0 : sDestShortName += OUString::number( nIdx );
270 : }
271 :
272 : try
273 : {
274 0 : uno::Reference < embed::XStorage > rSourceRoot = xBlkRoot->openStorageElement( aGroup, embed::ElementModes::READ );
275 0 : uno::Reference < embed::XStorage > rDestRoot = static_cast<SwXMLTextBlocks&>(rDestImp).xBlkRoot->openStorageElement( sDestShortName, embed::ElementModes::READWRITE );
276 0 : rSourceRoot->copyToStorage( rDestRoot );
277 : }
278 0 : catch (const uno::Exception&)
279 : {
280 0 : nError = ERR_SWG_WRITE_ERROR;
281 : }
282 :
283 0 : if(!nError)
284 : {
285 0 : rShort = sDestShortName;
286 0 : static_cast<SwXMLTextBlocks&>(rDestImp).AddName( rShort, rLong, bTextOnly );
287 0 : static_cast<SwXMLTextBlocks&>(rDestImp).MakeBlockList();
288 : }
289 0 : CloseFile();
290 0 : rDestImp.CloseFile();
291 0 : return nError;
292 : }
293 :
294 1 : sal_uLong SwXMLTextBlocks::StartPutBlock( const OUString& rShort, const OUString& rPackageName )
295 : {
296 : OSL_ENSURE( xBlkRoot.is(), "No storage set" );
297 1 : if(!xBlkRoot.is())
298 0 : return 0;
299 1 : GetIndex ( rShort );
300 : try
301 : {
302 1 : xRoot = xBlkRoot->openStorageElement( rPackageName, embed::ElementModes::READWRITE );
303 :
304 1 : uno::Reference< beans::XPropertySet > xRootProps( xRoot, uno::UNO_QUERY_THROW );
305 2 : OUString aPropName( "MediaType" );
306 2 : OUString aMime( SotExchange::GetFormatMimeType( SotClipboardFormatId::STARWRITER_8 ) );
307 2 : xRootProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
308 : }
309 0 : catch (const uno::Exception&)
310 : {
311 : }
312 1 : return 0;
313 : }
314 :
315 1 : sal_uLong SwXMLTextBlocks::BeginPutDoc( const OUString& rShort, const OUString& rLong )
316 : {
317 : // Store in base class
318 1 : aShort = rShort;
319 1 : aLong = rLong;
320 1 : aPackageName = GeneratePackageName( rShort );
321 1 : SetIsTextOnly( rShort, false);
322 1 : return StartPutBlock (rShort, aPackageName);
323 : }
324 :
325 1 : sal_uLong SwXMLTextBlocks::PutBlock( SwPaM& , const OUString& )
326 : {
327 1 : sal_uLong nRes = 0; // dead variable, this always returns 0
328 1 : sal_uInt16 nCommitFlags = nFlags & (SWXML_CONVBLOCK|SWXML_NOROOTCOMMIT);
329 :
330 1 : nFlags |= nCommitFlags;
331 :
332 1 : WriterRef xWrt;
333 1 : ::GetXMLWriter ( OUString(), GetBaseURL(), xWrt);
334 2 : SwWriter aWriter (xRoot, *pDoc );
335 :
336 1 : xWrt->bBlock = true;
337 1 : nRes = aWriter.Write ( xWrt );
338 1 : xWrt->bBlock = false;
339 : // Save OLE objects if there are some
340 1 : SwDocShell *pDocSh = pDoc->GetDocShell();
341 :
342 1 : bool bHasChildren = pDocSh && pDocSh->GetEmbeddedObjectContainer().HasEmbeddedObjects();
343 1 : if( !nRes && bHasChildren )
344 : {
345 : // we have to write to the temporary storage first, since the used below functions are optimized
346 : // TODO/LATER: it is only a temporary solution, that should be changed soon, the used methods should be
347 : // called without optimization
348 0 : bool bOK = false;
349 :
350 0 : if ( xRoot.is() )
351 : {
352 0 : SfxMedium* pTmpMedium = NULL;
353 : try
354 : {
355 : uno::Reference< embed::XStorage > xTempStorage =
356 0 : ::comphelper::OStorageHelper::GetTemporaryStorage();
357 :
358 0 : xRoot->copyToStorage( xTempStorage );
359 :
360 : // TODO/LATER: no progress bar?!
361 : // TODO/MBA: strange construct
362 0 : pTmpMedium = new SfxMedium( xTempStorage, GetBaseURL() );
363 0 : bool bTmpOK = pDocSh->SaveAsChildren( *pTmpMedium );
364 0 : if( bTmpOK )
365 0 : bTmpOK = pDocSh->SaveCompletedChildren( false );
366 :
367 0 : xTempStorage->copyToStorage( xRoot );
368 0 : bOK = bTmpOK;
369 : }
370 0 : catch(const uno::Exception&)
371 : {
372 : }
373 :
374 0 : if ( pTmpMedium )
375 0 : DELETEZ( pTmpMedium );
376 : }
377 :
378 0 : if( !bOK )
379 0 : nRes = ERR_SWG_WRITE_ERROR;
380 : }
381 :
382 : try
383 : {
384 1 : uno::Reference < embed::XTransactedObject > xTrans( xRoot, uno::UNO_QUERY );
385 1 : if ( xTrans.is() )
386 1 : xTrans->commit();
387 1 : xRoot = 0;
388 1 : if ( !nCommitFlags )
389 : {
390 1 : uno::Reference < embed::XTransactedObject > xTmpTrans( xBlkRoot, uno::UNO_QUERY );
391 1 : if ( xTmpTrans.is() )
392 1 : xTmpTrans->commit();
393 1 : }
394 : }
395 0 : catch (const uno::Exception&)
396 : {
397 : }
398 :
399 : //TODO/LATER: error handling
400 2 : return 0;
401 : }
402 :
403 1 : sal_uLong SwXMLTextBlocks::PutDoc()
404 : {
405 1 : SwPaM* pPaM = MakePaM();
406 1 : sal_uLong nErr = PutBlock(*pPaM, aLong);
407 1 : delete pPaM;
408 1 : return nErr;
409 : }
410 :
411 0 : sal_uLong SwXMLTextBlocks::GetText( sal_uInt16 nIdx, OUString& rText )
412 : {
413 0 : return GetBlockText( aNames[ nIdx ]->aShort, rText );
414 : }
415 :
416 2 : sal_uLong SwXMLTextBlocks::GetText( const OUString& rShort, OUString& rText )
417 : {
418 2 : return GetBlockText( rShort, rText );
419 : }
420 :
421 13 : sal_uLong SwXMLTextBlocks::MakeBlockList()
422 : {
423 13 : WriteInfo();
424 13 : return 0;
425 : }
426 :
427 0 : bool SwXMLTextBlocks::PutMuchEntries( bool bOn )
428 : {
429 0 : bool bRet = false;
430 0 : if( bOn )
431 : {
432 0 : if( bInPutMuchBlocks )
433 : {
434 : OSL_ENSURE( false, "Nested calls are not allowed");
435 : }
436 0 : else if( !IsFileChanged() )
437 : {
438 0 : bRet = 0 == OpenFile( false );
439 0 : if( bRet )
440 : {
441 0 : nFlags |= SWXML_NOROOTCOMMIT;
442 0 : bInPutMuchBlocks = true;
443 : }
444 : }
445 : }
446 0 : else if( bInPutMuchBlocks )
447 : {
448 0 : nFlags &= ~SWXML_NOROOTCOMMIT;
449 0 : if( xBlkRoot.is() )
450 : {
451 : try
452 : {
453 0 : uno::Reference < embed::XTransactedObject > xTrans( xBlkRoot, uno::UNO_QUERY );
454 0 : if ( xTrans.is() )
455 0 : xTrans->commit();
456 0 : MakeBlockList();
457 0 : CloseFile();
458 0 : Touch();
459 0 : bInPutMuchBlocks = false;
460 0 : bRet = true;
461 : }
462 0 : catch (const uno::Exception&)
463 : {
464 : }
465 : }
466 : }
467 0 : return bRet;
468 : }
469 :
470 24 : sal_uLong SwXMLTextBlocks::OpenFile( bool bRdOnly )
471 : {
472 24 : if( bAutocorrBlock )
473 0 : return 0;
474 24 : sal_uLong nRet = 0;
475 : try
476 : {
477 : uno::Reference < embed::XStorage > refStg = comphelper::OStorageHelper::GetStorageFromURL( aFile,
478 24 : bRdOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE );
479 24 : InitBlockMode ( refStg );
480 : }
481 0 : catch (const uno::Exception&)
482 : {
483 : //TODO/LATER: error handling
484 0 : nRet = 1;
485 : }
486 :
487 24 : return nRet;
488 : }
489 :
490 20 : void SwXMLTextBlocks::CloseFile()
491 : {
492 20 : if ( !bAutocorrBlock )
493 : {
494 20 : if (bInfoChanged)
495 0 : WriteInfo();
496 20 : ResetBlockMode();
497 : }
498 20 : }
499 :
500 7 : void SwXMLTextBlocks::SetIsTextOnly( const OUString& rShort, bool bNewValue )
501 : {
502 7 : sal_uInt16 nIdx = GetIndex ( rShort );
503 7 : if (nIdx != USHRT_MAX)
504 1 : aNames[nIdx]->bIsOnlyText = bNewValue;
505 7 : }
506 :
507 0 : bool SwXMLTextBlocks::IsOnlyTextBlock( const OUString& rShort ) const
508 : {
509 0 : sal_uInt16 nIdx = GetIndex ( rShort );
510 0 : bool bRet = false;
511 0 : if (nIdx != USHRT_MAX)
512 : {
513 0 : bRet = aNames[nIdx]->bIsOnlyText;
514 : }
515 0 : return bRet;
516 : }
517 17 : bool SwXMLTextBlocks::IsOnlyTextBlock( sal_uInt16 nIdx ) const
518 : {
519 17 : return aNames[nIdx]->bIsOnlyText;
520 : }
521 :
522 59 : bool SwXMLTextBlocks::IsFileUCBStorage( const OUString & rFileName)
523 : {
524 59 : OUString aName( rFileName );
525 118 : INetURLObject aObj( aName );
526 59 : if ( aObj.GetProtocol() == INetProtocol::NotValid )
527 : {
528 0 : OUString aURL;
529 0 : ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL );
530 0 : aObj.SetURL( aURL );
531 0 : aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
532 : }
533 :
534 59 : SvStream * pStm = ::utl::UcbStreamHelper::CreateStream( aName, STREAM_STD_READ );
535 59 : bool bRet = UCBStorage::IsStorageFile( pStm );
536 59 : delete pStm;
537 118 : return bRet;
538 : }
539 :
540 0 : short SwXMLTextBlocks::GetFileType() const
541 : {
542 0 : return SWBLK_XML;
543 : }
544 :
545 17 : OUString SwXMLTextBlocks::GeneratePackageName ( const OUString& rShort )
546 : {
547 17 : OString sByte(OUStringToOString(rShort, RTL_TEXTENCODING_UTF7));
548 34 : OUStringBuffer aBuf(OStringToOUString(sByte, RTL_TEXTENCODING_ASCII_US));
549 17 : const sal_Int32 nLen = aBuf.getLength();
550 242 : for (sal_Int32 nPos=0; nPos<nLen; ++nPos)
551 : {
552 225 : switch (aBuf[nPos])
553 : {
554 : case '!':
555 : case '/':
556 : case ':':
557 : case '.':
558 : case '\\':
559 0 : aBuf[nPos] = '_';
560 0 : break;
561 : default:
562 225 : break;
563 : }
564 : }
565 34 : return aBuf.makeStringAndClear();
566 : }
567 :
568 6 : sal_uLong SwXMLTextBlocks::PutText( const OUString& rShort, const OUString& rName,
569 : const OUString& rText )
570 : {
571 6 : sal_uLong nRes = 0;
572 6 : aShort = rShort;
573 6 : aLong = rName;
574 6 : aCur = rText;
575 6 : SetIsTextOnly( aShort, true );
576 6 : aPackageName = GeneratePackageName( rShort );
577 6 : ClearDoc();
578 6 : nRes = PutBlockText( rShort, rName, rText, aPackageName );
579 6 : return nRes;
580 : }
581 :
582 10 : void SwXMLTextBlocks::MakeBlockText( const OUString& rText )
583 : {
584 20 : SwTextNode* pTextNode = pDoc->GetNodes()[ pDoc->GetNodes().GetEndOfContent().
585 20 : GetIndex() - 1 ]->GetTextNode();
586 10 : if( pTextNode->GetTextColl() == pDoc->GetDfltTextFormatColl() )
587 0 : pTextNode->ChgFormatColl( pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_STANDARD ));
588 :
589 10 : sal_Int32 nPos = 0;
590 18 : do
591 : {
592 18 : if ( nPos )
593 : {
594 8 : pTextNode = static_cast<SwTextNode*>(pTextNode->AppendNode( SwPosition( *pTextNode ) ));
595 : }
596 18 : SwIndex aIdx( pTextNode );
597 18 : pTextNode->InsertText( rText.getToken( 0, '\015', nPos ), aIdx );
598 18 : } while ( -1 != nPos );
599 187 : }
600 :
601 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|