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