xref: /AOO41X/main/sw/source/filter/writer/writer.cxx (revision dec99bbd1eb6ae693d6ee672c1a69e3a32d917e7)
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( !this, "Schreiben in Storages auf einem 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( !this, "Schreiben in Storages auf einem 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( !this, "Schreiben in Streams auf einem 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