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 #include <hintids.hxx>
27
28 #define _SVSTDARR_STRINGSSORTDTOR
29 #include <svl/svstdarr.hxx>
30
31 #include <sot/storage.hxx>
32 #include <sfx2/docfile.hxx>
33 #include <svl/urihelper.hxx>
34 #include <svtools/filter.hxx>
35 #include <editeng/fontitem.hxx>
36 #include <editeng/eeitem.hxx>
37 #include <shellio.hxx>
38 #include <pam.hxx>
39 #include <doc.hxx>
40 #include <docary.hxx>
41 #include <IMark.hxx>
42 #include <numrule.hxx>
43 #include <swerror.h>
44 #include <boost/bind.hpp>
45
46 using namespace ::com::sun::star;
47
48
49 // Stringbuffer fuer die umgewandelten Zahlen
50 static sal_Char aNToABuf[] = "0000000000000000000000000";
51 #define NTOABUFLEN (sizeof(aNToABuf))
52
53 DECLARE_TABLE( SwBookmarkNodeTable, SvPtrarr* )
54
55 struct Writer_Impl
56 {
57 SvStream * m_pStream;
58
59 SvStringsSortDtor *pSrcArr, *pDestArr;
60 SvPtrarr* pFontRemoveLst, *pBkmkArr;
61 SwBookmarkNodeTable* pBkmkNodePos;
62
63 Writer_Impl();
64 ~Writer_Impl();
65
66 void RemoveFontList( SwDoc& rDoc );
67 void InsertBkmk( const ::sw::mark::IMark& rBkmk );
68 };
69
Writer_Impl()70 Writer_Impl::Writer_Impl()
71 : m_pStream(0)
72 , pSrcArr( 0 ), pDestArr( 0 ), pFontRemoveLst( 0 ), pBkmkNodePos( 0 )
73 {
74 }
75
~Writer_Impl()76 Writer_Impl::~Writer_Impl()
77 {
78 delete pSrcArr;
79 delete pDestArr;
80 delete pFontRemoveLst;
81
82 if( pBkmkNodePos )
83 {
84 for( SvPtrarr* p = pBkmkNodePos->First(); p; p = pBkmkNodePos->Next() )
85 delete p;
86 delete pBkmkNodePos;
87 }
88 }
89
RemoveFontList(SwDoc & rDoc)90 void Writer_Impl::RemoveFontList( SwDoc& rDoc )
91 {
92 ASSERT( pFontRemoveLst, "wo ist die FontListe?" );
93 for( sal_uInt16 i = pFontRemoveLst->Count(); i; )
94 {
95 SvxFontItem* pItem = (SvxFontItem*)(*pFontRemoveLst)[ --i ];
96 rDoc.GetAttrPool().Remove( *pItem );
97 }
98 }
99
InsertBkmk(const::sw::mark::IMark & rBkmk)100 void Writer_Impl::InsertBkmk(const ::sw::mark::IMark& rBkmk)
101 {
102 if( !pBkmkNodePos )
103 pBkmkNodePos = new SwBookmarkNodeTable;
104
105 sal_uLong nNd = rBkmk.GetMarkPos().nNode.GetIndex();
106 SvPtrarr* pArr = pBkmkNodePos->Get( nNd );
107 if( !pArr )
108 {
109 pArr = new SvPtrarr( 1, 4 );
110 pBkmkNodePos->Insert( nNd, pArr );
111 }
112
113 void* p = (void*)&rBkmk;
114 pArr->Insert( p, pArr->Count() );
115
116 if(rBkmk.IsExpanded() && rBkmk.GetOtherMarkPos().nNode != nNd)
117 {
118 nNd = rBkmk.GetOtherMarkPos().nNode.GetIndex();
119 pArr = pBkmkNodePos->Get( nNd );
120 if( !pArr )
121 {
122 pArr = new SvPtrarr( 1, 4 );
123 pBkmkNodePos->Insert( nNd, pArr );
124 }
125 pArr->Insert( p, pArr->Count() );
126 }
127 }
128
129 /*
130 * Dieses Modul ist die Zentrale-Sammelstelle fuer alle Write-Filter
131 * und ist eine DLL !
132 *
133 * Damit der Writer mit den unterschiedlichen Writern arbeiten kann,
134 * muessen fuer diese die Ausgabe-Funktionen der Inhalts tragenden
135 * Objecte auf die verschiedenen Ausgabe-Funktionen gemappt werden.
136 *
137 * Dazu kann fuer jedes Object ueber den Which-Wert in einen Tabelle ge-
138 * griffen werden, um seine Ausgabe-Funktion zu erfragen.
139 * Diese Funktionen stehen in den entsprechenden Writer-DLL's.
140 */
141
Writer()142 Writer::Writer()
143 : m_pImpl(new Writer_Impl)
144 , pOrigPam(0), pOrigFileName(0), pDoc(0), pCurPam(0)
145 {
146 bWriteAll = bShowProgress = bUCS2_WithStartChar = true;
147 bASCII_NoLastLineEnd = bASCII_ParaAsBlanc = bASCII_ParaAsCR =
148 bWriteClipboardDoc = bWriteOnlyFirstTable = bBlock =
149 bOrganizerMode = false;
150 bExportPargraphNumbering = sal_True;
151 }
152
~Writer()153 Writer::~Writer()
154 {
155 }
156
157 /*
158 * Document Interface Access
159 */
getIDocumentSettingAccess()160 IDocumentSettingAccess* Writer::getIDocumentSettingAccess() { return pDoc; }
getIDocumentSettingAccess() const161 const IDocumentSettingAccess* Writer::getIDocumentSettingAccess() const { return pDoc; }
getIDocumentStylePoolAccess()162 IDocumentStylePoolAccess* Writer::getIDocumentStylePoolAccess() { return pDoc; }
getIDocumentStylePoolAccess() const163 const IDocumentStylePoolAccess* Writer::getIDocumentStylePoolAccess() const { return pDoc; }
164
ResetWriter()165 void Writer::ResetWriter()
166 {
167 if (m_pImpl->pFontRemoveLst)
168 {
169 m_pImpl->RemoveFontList( *pDoc );
170 }
171 m_pImpl.reset(new Writer_Impl);
172
173 if( pCurPam )
174 {
175 while( pCurPam->GetNext() != pCurPam )
176 delete pCurPam->GetNext();
177 delete pCurPam;
178 }
179 pCurPam = 0;
180 pOrigFileName = 0;
181 pDoc = 0;
182
183 bShowProgress = bUCS2_WithStartChar = sal_True;
184 bASCII_NoLastLineEnd = bASCII_ParaAsBlanc = bASCII_ParaAsCR =
185 bWriteClipboardDoc = bWriteOnlyFirstTable = bBlock =
186 bOrganizerMode = sal_False;
187 }
188
CopyNextPam(SwPaM ** ppPam)189 sal_Bool Writer::CopyNextPam( SwPaM ** ppPam )
190 {
191 if( (*ppPam)->GetNext() == pOrigPam )
192 {
193 *ppPam = pOrigPam; // wieder auf den Anfangs-Pam setzen
194 return sal_False; // Ende vom Ring
195 }
196
197 // ansonsten kopiere den die Werte aus dem naechsten Pam
198 *ppPam = ((SwPaM*)(*ppPam)->GetNext() );
199
200 *pCurPam->GetPoint() = *(*ppPam)->Start();
201 *pCurPam->GetMark() = *(*ppPam)->End();
202
203 return sal_True;
204 }
205
206 // suche die naechste Bookmark-Position aus der Bookmark-Tabelle
207
FindPos_Bkmk(const SwPosition & rPos) const208 sal_Int32 Writer::FindPos_Bkmk(const SwPosition& rPos) const
209 {
210 const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
211 const IDocumentMarkAccess::const_iterator_t ppBkmk = ::std::lower_bound(
212 pMarkAccess->getAllMarksBegin(),
213 pMarkAccess->getAllMarksEnd(),
214 rPos,
215 ::boost::bind(&::sw::mark::IMark::StartsBefore, _1, _2)); // find the first Mark that does not start before
216 if(ppBkmk != pMarkAccess->getAllMarksEnd())
217 return ppBkmk - pMarkAccess->getAllMarksBegin();
218 return -1;
219 }
220
221
222 SwPaM *
NewSwPaM(SwDoc & rDoc,sal_uLong const nStartIdx,sal_uLong const nEndIdx)223 Writer::NewSwPaM(SwDoc & rDoc, sal_uLong const nStartIdx, sal_uLong const nEndIdx)
224 {
225 SwNodes *const pNds = &rDoc.GetNodes();
226
227 SwNodeIndex aStt( *pNds, nStartIdx );
228 SwCntntNode* pCNode = aStt.GetNode().GetCntntNode();
229 if( !pCNode && 0 == ( pCNode = pNds->GoNext( &aStt )) )
230 {
231 ASSERT( false, "An StartPos kein ContentNode mehr" );
232 }
233
234 SwPaM* pNew = new SwPaM( aStt );
235 pNew->SetMark();
236 aStt = nEndIdx;
237 if( 0 == (pCNode = aStt.GetNode().GetCntntNode()) &&
238 0 == (pCNode = pNds->GoPrevious( &aStt )) )
239 {
240 ASSERT( false, "An StartPos kein ContentNode mehr" );
241 }
242 pCNode->MakeEndIndex( &pNew->GetPoint()->nContent );
243 pNew->GetPoint()->nNode = aStt;
244 return pNew;
245 }
246
247 /////////////////////////////////////////////////////////////////////////////
248
249 // Stream-spezifisches
Strm()250 SvStream& Writer::Strm()
251 {
252 ASSERT( m_pImpl->m_pStream, "Oh-oh. Writer with no Stream!" );
253 return *m_pImpl->m_pStream;
254 }
255
SetStream(SvStream * const pStream)256 void Writer::SetStream(SvStream *const pStream)
257 { m_pImpl->m_pStream = pStream; }
258
259
OutHex(SvStream & rStrm,sal_uLong nHex,sal_uInt8 nLen)260 SvStream& Writer::OutHex( SvStream& rStrm, sal_uLong nHex, sal_uInt8 nLen )
261 { // in einen Stream aus
262 // Pointer an das Bufferende setzen
263 sal_Char* pStr = aNToABuf + (NTOABUFLEN-1);
264 for( sal_uInt8 n = 0; n < nLen; ++n )
265 {
266 *(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
267 if( *pStr > '9' )
268 *pStr += 39;
269 nHex >>= 4;
270 }
271 return rStrm << pStr;
272 }
273
OutLong(SvStream & rStrm,long nVal)274 SvStream& Writer::OutLong( SvStream& rStrm, long nVal )
275 {
276 // Pointer an das Bufferende setzen
277 sal_Char* pStr = aNToABuf + (NTOABUFLEN-1);
278
279 int bNeg = nVal < 0;
280 if( bNeg )
281 nVal = -nVal;
282
283 do {
284 *(--pStr) = (sal_Char)(nVal % 10 ) + 48;
285 nVal /= 10;
286 } while( nVal );
287
288 // Ist Zahl negativ, dann noch -
289 if( bNeg )
290 *(--pStr) = '-';
291
292 return rStrm << pStr;
293 }
294
OutULong(SvStream & rStrm,sal_uLong nVal)295 SvStream& Writer::OutULong( SvStream& rStrm, sal_uLong nVal )
296 {
297 // Pointer an das Bufferende setzen
298 sal_Char* pStr = aNToABuf + (NTOABUFLEN-1);
299
300 do {
301 *(--pStr) = (sal_Char)(nVal % 10 ) + 48;
302 nVal /= 10;
303 } while ( nVal );
304 return rStrm << pStr;
305 }
306
307
Write(SwPaM & rPaM,SvStream & rStrm,const String * pFName)308 sal_uLong Writer::Write( SwPaM& rPaM, SvStream& rStrm, const String* pFName )
309 {
310 if ( IsStgWriter() )
311 {
312 SotStorageRef aRef = new SotStorage( rStrm );
313 sal_uLong nResult = Write( rPaM, *aRef, pFName );
314 if ( nResult == ERRCODE_NONE )
315 aRef->Commit();
316 return nResult;
317 }
318
319 pDoc = rPaM.GetDoc();
320 pOrigFileName = pFName;
321 m_pImpl->m_pStream = &rStrm;
322
323 // PaM kopieren, damit er veraendert werden kann
324 pCurPam = new SwPaM( *rPaM.End(), *rPaM.Start() );
325 // zum Vergleich auf den akt. Pam sichern
326 pOrigPam = &rPaM;
327
328 sal_uLong nRet = WriteStream();
329
330 ResetWriter();
331
332 return nRet;
333 }
334
Write(SwPaM & rPam,SfxMedium & rMed,const String * pFileName)335 sal_uLong Writer::Write( SwPaM& rPam, SfxMedium& rMed, const String* pFileName )
336 {
337 // This method must be overloaded in SwXMLWriter a storage from medium will be used there.
338 // The microsoft format can write to storage but the storage will be based on the stream.
339 return Write( rPam, *rMed.GetOutStream(), pFileName );
340 }
341
Write(SwPaM &,SvStorage &,const String *)342 sal_uLong Writer::Write( SwPaM& /*rPam*/, SvStorage&, const String* )
343 {
344 ASSERT( sal_False, "Write in storage on a stream?" );
345 return ERR_SWG_WRITE_ERROR;
346 }
347
Write(SwPaM &,const uno::Reference<embed::XStorage> &,const String *,SfxMedium *)348 sal_uLong Writer::Write( SwPaM&, const uno::Reference < embed::XStorage >&, const String*, SfxMedium* )
349 {
350 ASSERT( sal_False, "Write in storage on a stream?" );
351 return ERR_SWG_WRITE_ERROR;
352 }
353
CopyLocalFileToINet(String & rFileNm)354 sal_Bool Writer::CopyLocalFileToINet( String& rFileNm )
355 {
356 if( !pOrigFileName ) // can be happen, by example if we
357 return sal_False; // write into the clipboard
358
359 sal_Bool bRet = sal_False;
360 INetURLObject aFileUrl( rFileNm ), aTargetUrl( *pOrigFileName );
361
362 // JP 01.11.00: what is the correct question for the portal??
363 // if( aFileUrl.GetProtocol() == aFileUrl.GetProtocol() )
364 // return bRet;
365 // this is our old without the Mail-Export
366 if( ! ( INET_PROT_FILE == aFileUrl.GetProtocol() &&
367 INET_PROT_FILE != aTargetUrl.GetProtocol() &&
368 INET_PROT_FTP <= aTargetUrl.GetProtocol() &&
369 INET_PROT_NEWS >= aTargetUrl.GetProtocol() ) )
370 return bRet;
371
372 if (m_pImpl->pSrcArr)
373 {
374 // wurde die Datei schon verschoben
375 sal_uInt16 nPos;
376 if (m_pImpl->pSrcArr->Seek_Entry( &rFileNm, &nPos ))
377 {
378 rFileNm = *(*m_pImpl->pDestArr)[ nPos ];
379 return sal_True;
380 }
381 }
382 else
383 {
384 m_pImpl->pSrcArr = new SvStringsSortDtor( 4, 4 );
385 m_pImpl->pDestArr = new SvStringsSortDtor( 4, 4 );
386 }
387
388 String *pSrc = new String( rFileNm );
389 String *pDest = new String( aTargetUrl.GetPartBeforeLastName() );
390 *pDest += String(aFileUrl.GetName());
391
392 SfxMedium aSrcFile( *pSrc, STREAM_READ, sal_False );
393 SfxMedium aDstFile( *pDest, STREAM_WRITE | STREAM_SHARE_DENYNONE, sal_False );
394
395 *aDstFile.GetOutStream() << *aSrcFile.GetInStream();
396
397 aSrcFile.Close();
398 aDstFile.Commit();
399
400 bRet = 0 == aDstFile.GetError();
401
402 if( bRet )
403 {
404 m_pImpl->pSrcArr->Insert( pSrc );
405 m_pImpl->pDestArr->Insert( pDest );
406 rFileNm = *pDest;
407 }
408 else
409 {
410 delete pSrc;
411 delete pDest;
412 }
413
414 return bRet;
415 }
416
PutNumFmtFontsInAttrPool()417 void Writer::PutNumFmtFontsInAttrPool()
418 {
419 // dann gibt es noch in den NumRules ein paar Fonts
420 // Diese in den Pool putten. Haben sie danach einen RefCount > 1
421 // kann es wieder entfernt werden - ist schon im Pool
422 SfxItemPool& rPool = pDoc->GetAttrPool();
423 const SwNumRuleTbl& rListTbl = pDoc->GetNumRuleTbl();
424 const SwNumRule* pRule;
425 const SwNumFmt* pFmt;
426 // --> OD 2006-06-27 #b644095#
427 // const Font *pFont, *pDefFont = &SwNumRule::GetDefBulletFont();
428 const Font* pFont;
429 const Font* pDefFont = &numfunc::GetDefBulletFont();
430 // <--
431 sal_Bool bCheck = sal_False;
432
433 for( sal_uInt16 nGet = rListTbl.Count(); nGet; )
434 if( pDoc->IsUsed( *(pRule = rListTbl[ --nGet ] )))
435 for( sal_uInt8 nLvl = 0; nLvl < MAXLEVEL; ++nLvl )
436 if( SVX_NUM_CHAR_SPECIAL == (pFmt = &pRule->Get( nLvl ))->GetNumberingType() ||
437 SVX_NUM_BITMAP == pFmt->GetNumberingType() )
438 {
439 if( 0 == ( pFont = pFmt->GetBulletFont() ) )
440 pFont = pDefFont;
441
442 if( bCheck )
443 {
444 if( *pFont == *pDefFont )
445 continue;
446 }
447 else if( *pFont == *pDefFont )
448 bCheck = sal_True;
449
450 _AddFontItem( rPool, SvxFontItem( pFont->GetFamily(),
451 pFont->GetName(), pFont->GetStyleName(),
452 pFont->GetPitch(), pFont->GetCharSet(), RES_CHRATR_FONT ));
453 }
454 }
455
PutEditEngFontsInAttrPool(sal_Bool bIncl_CJK_CTL)456 void Writer::PutEditEngFontsInAttrPool( sal_Bool bIncl_CJK_CTL )
457 {
458 SfxItemPool& rPool = pDoc->GetAttrPool();
459 if( rPool.GetSecondaryPool() )
460 {
461 _AddFontItems( rPool, EE_CHAR_FONTINFO );
462 if( bIncl_CJK_CTL )
463 {
464 _AddFontItems( rPool, EE_CHAR_FONTINFO_CJK );
465 _AddFontItems( rPool, EE_CHAR_FONTINFO_CTL );
466 }
467 }
468 }
469
PutCJKandCTLFontsInAttrPool()470 void Writer::PutCJKandCTLFontsInAttrPool()
471 {
472 SfxItemPool& rPool = pDoc->GetAttrPool();
473 _AddFontItems( rPool, RES_CHRATR_CJK_FONT );
474 _AddFontItems( rPool, RES_CHRATR_CTL_FONT );
475 }
476
477
_AddFontItems(SfxItemPool & rPool,sal_uInt16 nW)478 void Writer::_AddFontItems( SfxItemPool& rPool, sal_uInt16 nW )
479 {
480 const SvxFontItem* pFont = (const SvxFontItem*)&rPool.GetDefaultItem( nW );
481 _AddFontItem( rPool, *pFont );
482
483 if( 0 != ( pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem( nW )) )
484 _AddFontItem( rPool, *pFont );
485
486 sal_uInt32 nMaxItem = rPool.GetItemCount2( nW );
487 for( sal_uInt32 nGet = 0; nGet < nMaxItem; ++nGet )
488 if( 0 != (pFont = (const SvxFontItem*)rPool.GetItem2( nW, nGet )) )
489 _AddFontItem( rPool, *pFont );
490 }
491
_AddFontItem(SfxItemPool & rPool,const SvxFontItem & rFont)492 void Writer::_AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont )
493 {
494 const SvxFontItem* pItem;
495 if( RES_CHRATR_FONT != rFont.Which() )
496 {
497 SvxFontItem aFont( rFont );
498 aFont.SetWhich( RES_CHRATR_FONT );
499 pItem = (SvxFontItem*)&rPool.Put( aFont );
500 }
501 else
502 pItem = (SvxFontItem*)&rPool.Put( rFont );
503
504 if( 1 < pItem->GetRefCount() )
505 rPool.Remove( *pItem );
506 else
507 {
508 if (!m_pImpl->pFontRemoveLst)
509 {
510 m_pImpl->pFontRemoveLst = new SvPtrarr( 0, 10 );
511 }
512
513 void* p = (void*)pItem;
514 m_pImpl->pFontRemoveLst->Insert( p, m_pImpl->pFontRemoveLst->Count() );
515 }
516 }
517
518 // build a bookmark table, which is sort by the node position. The
519 // OtherPos of the bookmarks also inserted.
CreateBookmarkTbl()520 void Writer::CreateBookmarkTbl()
521 {
522 const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
523 for(IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->getBookmarksBegin();
524 ppBkmk != pMarkAccess->getBookmarksEnd();
525 ++ppBkmk)
526 {
527 m_pImpl->InsertBkmk(**ppBkmk);
528 }
529 }
530
531
532 // search alle Bookmarks in the range and return it in the Array
GetBookmarks(const SwCntntNode & rNd,xub_StrLen nStt,xub_StrLen nEnd,SvPtrarr & rArr)533 sal_uInt16 Writer::GetBookmarks(const SwCntntNode& rNd, xub_StrLen nStt,
534 xub_StrLen nEnd, SvPtrarr& rArr)
535 {
536 ASSERT( !rArr.Count(), "es sind noch Eintraege vorhanden" );
537
538 sal_uLong nNd = rNd.GetIndex();
539 SvPtrarr* pArr = (m_pImpl->pBkmkNodePos) ?
540 m_pImpl->pBkmkNodePos->Get( nNd ) : 0;
541 if( pArr )
542 {
543 // there exist some bookmarks, search now all which is in the range
544 if( !nStt && nEnd == rNd.Len() )
545 // all
546 rArr.Insert( pArr, 0 );
547 else
548 {
549 sal_uInt16 n;
550 xub_StrLen nCntnt;
551 for( n = 0; n < pArr->Count(); ++n )
552 {
553 void* p = (*pArr)[ n ];
554 const ::sw::mark::IMark& rBkmk = *(::sw::mark::IMark *)p;
555 if( rBkmk.GetMarkPos().nNode == nNd &&
556 (nCntnt = rBkmk.GetMarkPos().nContent.GetIndex() ) >= nStt &&
557 nCntnt < nEnd )
558 {
559 rArr.Insert( p, rArr.Count() );
560 }
561 else if( rBkmk.IsExpanded() && nNd ==
562 rBkmk.GetOtherMarkPos().nNode.GetIndex() && (nCntnt =
563 rBkmk.GetOtherMarkPos().nContent.GetIndex() ) >= nStt &&
564 nCntnt < nEnd )
565 {
566 rArr.Insert( p, rArr.Count() );
567 }
568 }
569 }
570 }
571 return rArr.Count();
572 }
573
574 ////////////////////////////////////////////////////////////////////////////
575
576 // Storage-spezifisches
577
WriteStream()578 sal_uLong StgWriter::WriteStream()
579 {
580 ASSERT( sal_False, "Write in streams on a storage?" );
581 return ERR_SWG_WRITE_ERROR;
582 }
583
Write(SwPaM & rPaM,SvStorage & rStg,const String * pFName)584 sal_uLong StgWriter::Write( SwPaM& rPaM, SvStorage& rStg, const String* pFName )
585 {
586 SetStream(0);
587 pStg = &rStg;
588 pDoc = rPaM.GetDoc();
589 pOrigFileName = pFName;
590
591 // PaM kopieren, damit er veraendert werden kann
592 pCurPam = new SwPaM( *rPaM.End(), *rPaM.Start() );
593 // zum Vergleich auf den akt. Pam sichern
594 pOrigPam = &rPaM;
595
596 sal_uLong nRet = WriteStorage();
597
598 pStg = NULL;
599 ResetWriter();
600
601 return nRet;
602 }
603
Write(SwPaM & rPaM,const uno::Reference<embed::XStorage> & rStg,const String * pFName,SfxMedium * pMedium)604 sal_uLong StgWriter::Write( SwPaM& rPaM, const uno::Reference < embed::XStorage >& rStg, const String* pFName, SfxMedium* pMedium )
605 {
606 SetStream(0);
607 pStg = 0;
608 xStg = rStg;
609 pDoc = rPaM.GetDoc();
610 pOrigFileName = pFName;
611
612 // PaM kopieren, damit er veraendert werden kann
613 pCurPam = new SwPaM( *rPaM.End(), *rPaM.Start() );
614 // zum Vergleich auf den akt. Pam sichern
615 pOrigPam = &rPaM;
616
617 sal_uLong nRet = pMedium ? WriteMedium( *pMedium ) : WriteStorage();
618
619 pStg = NULL;
620 ResetWriter();
621
622 return nRet;
623 }
624
625