1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: shellio.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <hintids.hxx>
34 #include <tools/date.hxx>
35 #include <tools/time.hxx>
36 #include <svtools/urihelper.hxx>
37 #ifndef SVTOOLS_FSTATHELPER_HXX
38 #include <svtools/fstathelper.hxx>
40 #include <svtools/moduleoptions.hxx>
41 #include <sfx2/docfile.hxx>
42 #include <svx/lrspitem.hxx>
43 #include <svx/ulspitem.hxx>
44 #include <svx/boxitem.hxx>
45 #include <svx/paperinf.hxx>
48 #include <fmtanchr.hxx>
49 #include <fmtfsize.hxx>
50 #include <fmtpdsc.hxx>
51 #include <swtypes.hxx>
52 #include <shellio.hxx>
56 #include <undobj.hxx> // fuer Undo Insert-Dokument
57 #include <swundo.hxx> // fuer Undo Insert-Dokument
58 #include <swtable.hxx>
60 #include <pagedesc.hxx>
61 #include <poolfmt.hxx>
66 #include <redline.hxx>
71 // --> OD 2007-03-30 #i73788#
72 #include <pausethreadstarting.hxx>
75 using namespace ::com::sun::star
;
77 //////////////////////////////////////////////////////////////////////////
79 ULONG
SwReader::Read( const Reader
& rOptions
)
81 // Variable uebertragen
82 Reader
* po
= (Reader
*) &rOptions
;
86 po
->bInsertMode
= 0 != pCrsr
;
88 // ist ein Medium angegeben, dann aus diesem die Streams besorgen
89 if( 0 != (po
->pMedium
= pMedium
) &&
90 !po
->SetStrmStgPtr() )
92 po
->SetReadUTF8( FALSE
);
93 po
->SetBlockMode( FALSE
);
94 po
->SetOrganizerMode( FALSE
);
95 po
->SetIgnoreHTMLComments( FALSE
);
96 return ERR_SWG_FILE_FORMAT_ERROR
;
103 // am Sw3-Reader noch den pIo-Pointer "loeschen"
105 if( po == ReadSw3 && pDoc->GetDocShell() &&
106 ((Sw3Reader*)po)->GetSw3Io() != pDoc->GetDocShell()->GetIoSystem() )
107 ((Sw3Reader*)po)->SetSw3Io( pDoc->GetDocShell()->GetIoSystem() );*/
109 // waehrend des einlesens kein OLE-Modified rufen
110 Link
aOLELink( pDoc
->GetOle2Link() );
111 pDoc
->SetOle2Link( Link() );
113 pDoc
->SetInReading( true );
114 pDoc
->SetInXMLImport( 0 != dynamic_cast< XMLReader
* >(po
) );
121 // Wenn der Reader nicht mit einem Shell konstruiert wurde,
122 // selber einen Pam machen.
123 SwNodeIndex
nNode( pDoc
->GetNodes().GetEndOfContent(), -1 );
124 pPam
= new SwPaM( nNode
);
125 // Bei Web-Dokumenten wird die Default-Vorlage schon im InitNew
126 // gesetzt und braucht deshalb nicht nochmal gesetzt zu werden.
127 // Das gilt natuerlich nicht, wenn der Filter nicht der HTML-Filter
128 // ist oder im ConvertFrom zuvor ein SetTemplateName gerufen
130 if( !pDoc
->get(IDocumentSettingAccess::HTML_MODE
) || ReadHTML
!= po
|| !po
->pTemplate
)
131 po
->SetTemplate( *pDoc
);
134 // Pams sind ringfoermig verkettet. Aufhoeren, wenn man wieder beim
137 SwUndoInsDoc
* pUndo
= 0;
139 BOOL bReadPageDescs
= FALSE
;
140 BOOL bDocUndo
= pDoc
->DoesUndo();
141 BOOL bSaveUndo
= bDocUndo
&& pCrsr
;
144 // das Einlesen von Seitenvorlagen ist nicht Undofaehig!
145 if( 0 != ( bReadPageDescs
= po
->aOpt
.IsPageDescs() ) )
148 pDoc
->DelAllUndoObj();
153 pDoc
->StartUndo( UNDO_INSDOKUMENT
, NULL
);
156 pDoc
->DoUndo( FALSE
);
158 SwNodeIndex
aSplitIdx( pDoc
->GetNodes() );
160 RedlineMode_t eOld
= pDoc
->GetRedlineMode();
161 pDoc
->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE
);
163 // Array von FlyFormaten
164 SwSpzFrmFmts aFlyFrmArr
;
165 // only read templates? then ignore multi selection!
166 BOOL bFmtsOnly
= po
->aOpt
.IsFmtsOnly();
171 pUndo
= new SwUndoInsDoc( *pPam
);
174 if( bDocUndo
|| pCrsr
)
176 // Pam auf den Node davor setzen damit er nicht mit verschoben wird
177 const SwNodeIndex
& rTmp
= pPam
->GetPoint()->nNode
;
178 pUndoPam
= new SwPaM( rTmp
, rTmp
, 0, -1 );
181 // Speicher mal alle Fly's
183 aFlyFrmArr
.Insert( pDoc
->GetSpzFrmFmts(), 0L );
185 xub_StrLen nSttCntnt
= pPam
->GetPoint()->nContent
.GetIndex();
187 // damit fuer alle Reader die Ende-Position immer stimmt, hier
189 SwCntntNode
* pCNd
= pPam
->GetCntntNode();
190 xub_StrLen nEndCntnt
= pCNd
? pCNd
->Len() - nSttCntnt
: 0;
191 SwNodeIndex
aEndPos( pPam
->GetPoint()->nNode
, 1 );
193 nError
= po
->Read( *pDoc
, GetBaseURL(), *pPam
, aFileName
);
195 if( !IsError( nError
)) // dann setzen wir das Ende mal richtig
198 pCNd
= aEndPos
.GetNode().GetCntntNode();
199 if( !pCNd
&& 0 == ( pCNd
= pDoc
->GetNodes().GoPrevious( &aEndPos
) ))
200 pCNd
= pDoc
->GetNodes().GoNext( &aEndPos
);
202 pPam
->GetPoint()->nNode
= aEndPos
;
203 xub_StrLen nLen
= pCNd
->Len();
204 if( nLen
< nEndCntnt
)
207 nEndCntnt
= nLen
- nEndCntnt
;
208 pPam
->GetPoint()->nContent
.Assign( pCNd
, nEndCntnt
);
213 *pUndoPam
->GetMark() = *pPam
->GetPoint();
214 pUndoPam
->GetPoint()->nNode
++;
215 SwNode
* pNd
= pUndoPam
->GetNode();
216 if( pNd
->IsCntntNode() )
217 pUndoPam
->GetPoint()->nContent
.Assign(
218 (SwCntntNode
*)pNd
, nSttCntnt
);
220 pUndoPam
->GetPoint()->nContent
.Assign( 0, 0 );
222 int bChkHeaderFooter
= pNd
->FindHeaderStartNode() ||
223 pNd
->FindFooterStartNode();
225 // Suche alle neuen Fly's und speicher sie als einzelne Undo
227 for( USHORT n
= 0; n
< pDoc
->GetSpzFrmFmts()->Count(); ++n
)
229 SwFrmFmt
* pFrmFmt
= (*pDoc
->GetSpzFrmFmts())[ n
];
230 const SwFmtAnchor
& rAnchor
= pFrmFmt
->GetAnchor();
231 if( USHRT_MAX
== aFlyFrmArr
.GetPos( pFrmFmt
) )
233 if( FLY_PAGE
== rAnchor
.GetAnchorId() ||
234 ( FLY_AT_CNTNT
== rAnchor
.GetAnchorId() &&
235 rAnchor
.GetCntntAnchor() &&
236 ( pUndoPam
->GetPoint()->nNode
==
237 rAnchor
.GetCntntAnchor()->nNode
||
238 pUndoPam
->GetMark()->nNode
==
239 rAnchor
.GetCntntAnchor()->nNode
) ) )
241 if( bChkHeaderFooter
&&
242 FLY_AT_CNTNT
== rAnchor
.GetAnchorId() &&
243 RES_DRAWFRMFMT
== pFrmFmt
->Which() )
245 // DrawObjecte in Kopf-/Fusszeilen ist nicht
248 pDoc
->DelFrmFmt( pFrmFmt
);
255 pDoc
->SetRedlineMode_intern( eOld
);
256 pDoc
->AppendUndo( new SwUndoInsLayFmt( pFrmFmt
,0,0 ) );
257 pDoc
->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE
);
259 if( pFrmFmt
->GetDepends() )
261 // beim Insert legen Draw-Objecte einen Frame an
266 if( FLY_PAGE
== rAnchor
.GetAnchorId() )
268 if( !rAnchor
.GetCntntAnchor() )
271 // seitengebundene Flys eingefuegt, dann schalte
272 // die Optimierungs-Flags vom SwDoc ab. Sonst
273 // werden die Flys nicht an der Position erzeugt.
274 pDoc
->SetLoaded( FALSE
);
282 if( aFlyFrmArr
.Count() )
283 aFlyFrmArr
.Remove( 0, aFlyFrmArr
.Count() );
285 pDoc
->SetRedlineMode_intern( eOld
);
286 if( pDoc
->IsRedlineOn() )
287 pDoc
->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT
, *pUndoPam
), true);
289 pDoc
->SplitRedline( *pUndoPam
);
290 pDoc
->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE
);
294 pDoc
->SetRedlineMode_intern( eOld
);
295 pUndo
->SetInsertRange( *pUndoPam
, FALSE
);
296 pDoc
->AppendUndo( pUndo
);
297 pDoc
->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE
);
302 pPam
= (SwPaM
*) pPam
->GetNext();
306 // only read templates? then ignore multi selection! Bug 68593
311 * !!! man muss selbst den Status vom Stream zuruecksetzen. !!!
312 * Beim seekg wird der akt. Status, eof- und bad-Bit
313 * gesetzt, warum weiss keiner
322 pDoc
->SetInReading( false );
323 pDoc
->SetInXMLImport( false );
325 pDoc
->InvalidateNumRules();
326 pDoc
->UpdateNumRule();
327 pDoc
->ChkCondColls();
328 pDoc
->SetAllUniqueFlyNames();
331 pDoc
->DoUndo( TRUE
);
334 pDoc
->DoUndo( bDocUndo
);
337 pDoc
->SetRedlineMode_intern( eOld
);
338 pDoc
->EndUndo( UNDO_INSDOKUMENT
, NULL
);
339 pDoc
->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE
);
343 // Wenn der Pam nur fuers Lesen konstruiert wurde, jetzt zerstoeren.
346 delete pPam
; // ein neues aufgemacht.
348 // --> FME 2005-02-25 #i42634# Moved common code of SwReader::Read() and
349 // SwDocShell::UpdateLinks() to new SwDoc::UpdateLinks():
350 // ATM still with Update
351 pDoc
->UpdateLinks( TRUE
);
354 eOld
= (RedlineMode_t
)(pDoc
->GetRedlineMode() & ~nsRedlineMode_t::REDLINE_IGNORE
);
356 pDoc
->SetFieldsDirty(false, NULL
, 0);
359 pDoc
->SetRedlineMode_intern( eOld
);
360 pDoc
->SetOle2Link( aOLELink
);
362 if( pCrsr
) // das Doc ist jetzt modifiziert
364 // --> OD 2005-02-11 #i38810# - If links have been updated, the document
365 // have to be modified. During update of links the OLE link at the document
366 // isn't set. Thus, the document's modified state has to be set again after
367 // the OLE link is restored - see above <pDoc->SetOle2Link( aOLELink )>.
368 if ( pDoc
->LinksUpdated() )
374 // if( po == ReadSw3 ) // am Sw3-Reader noch den pIo-Pointer "loeschen"
375 // ((Sw3Reader*)po)->SetSw3Io( 0 );
377 po
->SetReadUTF8( FALSE
);
378 po
->SetBlockMode( FALSE
);
379 po
->SetOrganizerMode( FALSE
);
380 po
->SetIgnoreHTMLComments( FALSE
);
387 * Konstruktoren, Destruktor
390 // Initiales Einlesben
393 SwReader::SwReader(SvStorage& rStg, const String& rFileName, SwDoc *pDoc)
394 : SwDocFac(pDoc), pStrm(0), pStg(&rStg), pMedium(0), pCrsr(0),
399 SwReader::SwReader(const uno::Reference < embed::XStorage >& rStg, const String& rFileName, SwDoc *pDoc)
400 : SwDocFac(pDoc), pStrm(0), pMedium(0), pCrsr(0), xStg( rStg ), aFileName(rFileName)
404 SwReader::SwReader(SfxMedium
& rMedium
, const String
& rFileName
, SwDoc
*pDocument
)
405 : SwDocFac(pDocument
), pStrm(0), pMedium(&rMedium
), pCrsr(0),
408 SetBaseURL( rMedium
.GetBaseURL() );
411 // In ein existierendes Dokument einlesen
413 SwReader::SwReader(SvStream
& rStrm
, const String
& rFileName
, const String
& rBaseURL
, SwPaM
& rPam
)
414 : SwDocFac(rPam
.GetDoc()), pStrm(&rStrm
), pMedium(0), pCrsr(&rPam
),
417 SetBaseURL( rBaseURL
);
420 SwReader::SwReader(SvStorage& rStg, const String& rFileName, SwPaM& rPam)
421 : SwDocFac(rPam.GetDoc()), pStrm(0), pStg(&rStg), pMedium(0), pCrsr(&rPam),
426 SwReader::SwReader(SfxMedium
& rMedium
, const String
& rFileName
, SwPaM
& rPam
)
427 : SwDocFac(rPam
.GetDoc()), pStrm(0), pMedium(&rMedium
),
428 pCrsr(&rPam
), aFileName(rFileName
)
430 SetBaseURL( rMedium
.GetBaseURL() );
433 SwReader::SwReader( const uno::Reference
< embed::XStorage
> &rStg
, const String
& rFilename
, SwPaM
&rPam
)
434 : SwDocFac(rPam
.GetDoc()), pStrm(0), xStg( rStg
), pMedium(0), pCrsr(&rPam
), aFileName(rFilename
)
439 : pTemplate(0), pStrm(0), pMedium(0), bInsertMode(0),
440 bTmplBrowseMode(0), bReadUTF8(0), bBlockMode(0), bOrganizerMode(0),
441 bHasAskTemplateName(0), bIgnoreHTMLComments(0)
450 String
Reader::GetTemplateName() const
455 // Die Filter-Vorlage laden, setzen und wieder freigeben
456 SwDoc
* Reader::GetTemplateDoc()
458 if( !bHasAskTemplateName
)
460 SetTemplateName( GetTemplateName() );
461 bHasAskTemplateName
= TRUE
;
464 if( !aTemplateNm
.Len() )
468 INetURLObject
aTDir( aTemplateNm
);
469 String aFileName
= aTDir
.GetMainURL( INetURLObject::NO_DECODE
);
470 DBG_ASSERT( !aTDir
.HasError(), "No absolute path for template name!" );
471 DateTime aCurrDateTime
;
474 // Wenn das Template schon mal geladen wurde, nur einmal pro
475 // Minute nachschauen, ob es geaendert wurde.
476 if( !pTemplate
|| aCurrDateTime
>= aChkDateTime
)
480 if( FStatHelper::GetModifiedDateTimeOfFile(
481 aTDir
.GetMainURL( INetURLObject::NO_DECODE
),
482 &aTstDate
, &aTstTime
) &&
483 ( !pTemplate
|| aDStamp
!= aTstDate
|| aTStamp
!= aTstTime
))
490 // Erst in einer Minute wieder mal nachschauen, ob sich die
491 // Vorlage geaendert hat.
492 aChkDateTime
= aCurrDateTime
;
493 aChkDateTime
+= Time( 0L, 1L );
499 ASSERT( !pTemplate
, "Who holds the template doc?" );
501 // #95605#: If the writer module is not installed,
502 // we cannot create a SwDocShell. We could create a
503 // SwWebDocShell however, because this exists always
505 SvtModuleOptions aModuleOptions
;
506 if( aModuleOptions
.IsWriter() )
509 new SwDocShell ( SFX_CREATE_MODE_INTERNAL
);
510 SfxObjectShellRef xDocSh
= pDocSh
;
511 if( pDocSh
->DoInitNew( 0 ) )
513 pTemplate
= pDocSh
->GetDoc();
514 pTemplate
->SetOle2Link( Link() );
515 pTemplate
->DoUndo( FALSE
); // always FALSE
516 pTemplate
->set(IDocumentSettingAccess::BROWSE_MODE
, bTmplBrowseMode
);
517 pTemplate
->RemoveAllFmtLanguageDependencies();
519 ReadXML
->SetOrganizerMode( TRUE
);
520 SfxMedium
aMedium( aFileName
, FALSE
);
521 SwReader
aRdr( aMedium
, aEmptyStr
, pTemplate
);
522 aRdr
.Read( *ReadXML
);
523 ReadXML
->SetOrganizerMode( FALSE
);
525 pTemplate
->acquire();
530 ASSERT( !pTemplate
|| FStatHelper::IsDocument( aFileName
) ||
531 aTemplateNm
.EqualsAscii( "$$Dummy$$" ),
532 "TemplatePtr but no template exist!" );
538 BOOL
Reader::SetTemplate( SwDoc
& rDoc
)
545 rDoc
.RemoveAllFmtLanguageDependencies();
546 rDoc
.ReplaceStyles( *pTemplate
);
547 rDoc
.SetFixFields(false, NULL
);
554 void Reader::ClearTemplate()
558 if( 0 == pTemplate
->release() )
564 void Reader::SetTemplateName( const String
& rDir
)
566 if( rDir
.Len() && aTemplateNm
!= rDir
)
573 void Reader::MakeHTMLDummyTemplateDoc()
576 pTemplate
= new SwDoc
;
577 pTemplate
->acquire();
578 pTemplate
->set(IDocumentSettingAccess::BROWSE_MODE
, bTmplBrowseMode
);
579 pTemplate
->getPrinter( true );
580 pTemplate
->RemoveAllFmtLanguageDependencies();
581 aChkDateTime
= Date( 1, 1, 2300 ); // 2300. Jahrtausend sollte reichen
582 aTemplateNm
.AssignAscii( "$$Dummy$$" );
585 // alle die die Streams / Storages nicht geoeffnet brauchen,
586 // muessen die Methode ueberladen
587 int Reader::SetStrmStgPtr()
589 ASSERT( pMedium
, "Wo ist das Medium??" );
591 if( pMedium
->IsStorage() )
593 if( SW_STORAGE_READER
& GetReaderType() )
595 xStg
= pMedium
->GetStorage();
601 pStrm
= pMedium
->GetInStream();
602 if ( pStrm
&& SotStorage::IsStorageFile(pStrm
) && (SW_STORAGE_READER
& GetReaderType()) )
604 pStg
= new SotStorage( *pStrm
);
607 else if ( !(SW_STREAM_READER
& GetReaderType()) )
619 int Reader::GetReaderType()
621 return SW_STREAM_READER
;
625 void Reader::SetFltName( const String
& )
630 void Reader::SetNoOutlineNum( SwDoc
& /*rDoc*/ )
632 // JP 10.03.96: jetzt wieder keine Nummerierung in den Vorlagen
636 void Reader::ResetFrmFmtAttrs( SfxItemSet
&rFrmSet
)
638 rFrmSet
.Put( SvxLRSpaceItem(RES_LR_SPACE
) );
639 rFrmSet
.Put( SvxULSpaceItem(RES_UL_SPACE
) );
640 rFrmSet
.Put( SvxBoxItem(RES_BOX
) );
644 void Reader::ResetFrmFmts( SwDoc
& rDoc
)
646 for (USHORT i
=0; i
<3; ++i
)
652 ASSERT(i
== 0, "Impossible");
655 nPoolId
= RES_POOLFRM_FRAME
;
658 nPoolId
= RES_POOLFRM_GRAPHIC
;
661 nPoolId
= RES_POOLFRM_OLE
;
665 SwFrmFmt
*pFrmFmt
= rDoc
.GetFrmFmtFromPool( nPoolId
);
667 pFrmFmt
->ResetFmtAttr( RES_LR_SPACE
);
668 pFrmFmt
->ResetFmtAttr( RES_UL_SPACE
);
669 pFrmFmt
->ResetFmtAttr( RES_BOX
);
673 // read the sections of the document, which is equal to the medium.
674 // returns the count of it
675 USHORT
Reader::GetSectionList( SfxMedium
&, SvStrings
& ) const
680 // ------------------------------------------------
681 BOOL
SwReader::HasGlossaries( const Reader
& rOptions
)
683 // Variable uebertragen
684 Reader
* po
= (Reader
*) &rOptions
;
687 po
->bInsertMode
= FALSE
;
689 // ist ein Medium angegeben, dann aus diesem die Streams besorgen
691 if( !( 0 != (po
->pMedium
= pMedium
) && !po
->SetStrmStgPtr() ))
692 bRet
= po
->HasGlossaries();
696 BOOL
SwReader::ReadGlossaries( const Reader
& rOptions
,
697 SwTextBlocks
& rBlocks
, BOOL bSaveRelFiles
)
699 // Variable uebertragen
700 Reader
* po
= (Reader
*) &rOptions
;
703 po
->bInsertMode
= FALSE
;
705 // ist ein Medium angegeben, dann aus diesem die Streams besorgen
707 if( !( 0 != (po
->pMedium
= pMedium
) && !po
->SetStrmStgPtr() ))
708 bRet
= po
->ReadGlossaries( rBlocks
, bSaveRelFiles
);
712 BOOL
Reader::HasGlossaries() const
717 BOOL
Reader::ReadGlossaries( SwTextBlocks
&, BOOL
) const
722 // ------------------------------------------------
724 int StgReader::GetReaderType()
726 return SW_STORAGE_READER
;
737 * Konstruktoren, Destruktoren sind inline (inc/shellio.hxx).
740 SwWriter::SwWriter(SvStream
& rStrm
, SwCrsrShell
&rShell
, BOOL bInWriteAll
)
741 : pStrm(&rStrm
), pMedium(0), pOutPam(0), pShell(&rShell
),
742 rDoc(*rShell
.GetDoc()), bWriteAll(bInWriteAll
)
746 SwWriter::SwWriter(SvStream
& rStrm
,SwDoc
&rDocument
)
747 : pStrm(&rStrm
), pMedium(0), pOutPam(0), pShell(0), rDoc(rDocument
),
752 SwWriter::SwWriter(SvStream
& rStrm
, SwPaM
& rPam
, BOOL bInWriteAll
)
753 : pStrm(&rStrm
), pMedium(0), pOutPam(&rPam
), pShell(0),
754 rDoc(*rPam
.GetDoc()), bWriteAll(bInWriteAll
)
758 SwWriter::SwWriter( const uno::Reference
< embed::XStorage
>& rStg
, SwDoc
&rDocument
)
759 : pStrm(0), xStg( rStg
), pMedium(0), pOutPam(0), pShell(0), rDoc(rDocument
), bWriteAll(true)
763 SwWriter::SwWriter(SfxMedium
& rMedium
, SwCrsrShell
&rShell
, BOOL bInWriteAll
)
764 : pStrm(0), pMedium(&rMedium
), pOutPam(0), pShell(&rShell
),
765 rDoc(*rShell
.GetDoc()), bWriteAll(bInWriteAll
)
769 SwWriter::SwWriter(SfxMedium
& rMedium
, SwDoc
&rDocument
)
770 : pStrm(0), pMedium(&rMedium
), pOutPam(0), pShell(0), rDoc(rDocument
),
775 ULONG
SwWriter::Write( WriterRef
& rxWriter
, const String
* pRealFileName
)
777 // --> OD 2007-03-30 #i73788#
778 SwPauseThreadStarting aPauseThreadStarting
;
781 BOOL bHasMark
= FALSE
;
785 SfxObjectShellRef
* pRefForDocSh
= 0;
787 if ( pShell
&& !bWriteAll
&& pShell
->IsTableMode() )
792 pRefForDocSh
= new SfxObjectShellRef();
793 pDoc
->SetRefForDocShell( pRefForDocSh
);
795 // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
796 // von der Originalen an und kopiere die selectierten Boxen.
797 // Die Groessen werden prozentual korrigiert.
799 // lasse ueber das Layout die Boxen suchen
801 GetTblSel( *pShell
, aBoxes
);
802 SwTableNode
* pTblNd
= (SwTableNode
*)aBoxes
[0]->GetSttNd()->StartOfSectionNode();
803 SwNodeIndex
aIdx( pDoc
->GetNodes().GetEndOfExtras(), 2 );
804 SwCntntNode
*pNd
= aIdx
.GetNode().GetCntntNode();
805 ASSERT( pNd
, "Node not found" );
806 SwPosition
aPos( aIdx
, SwIndex( pNd
) );
807 pTblNd
->GetTable().MakeCopy( pDoc
, aPos
, aBoxes
);
810 if( !bWriteAll
&& ( pShell
|| pOutPam
))
813 pPam
= pShell
->GetCrsr();
819 // Erste Runde: Nachsehen, ob eine Selektion besteht.
822 bHasMark
= bHasMark
|| pPam
->HasMark();
823 pPam
= (SwPaM
*) pPam
->GetNext();
824 if(bHasMark
|| pPam
== pEnd
)
828 // Wenn keine Selektion besteht, eine ueber das ganze Dokument aufspannen.
834 pShell
->SttEndDoc(TRUE
);
836 pShell
->SttEndDoc(FALSE
);
840 pPam
= new SwPaM( *pPam
);
841 pPam
->Move( fnMoveBackward
, fnGoDoc
);
843 pPam
->Move( fnMoveForward
, fnGoDoc
);
846 // pPam ist immer noch der akt. Cursor !!
850 // keine Shell oder alles schreiben -> eigenen Pam erzeugen
851 SwDoc
* pOutDoc
= pDoc
? pDoc
: &rDoc
;
852 pPam
= new SwPaM( pOutDoc
->GetNodes().GetEndOfContent() );
853 if( pOutDoc
->IsClipBoard() )
855 pPam
->Move( fnMoveBackward
, fnGoDoc
);
857 pPam
->Move( fnMoveForward
, fnGoDoc
);
862 pPam
->Move( fnMoveBackward
, fnGoDoc
);
866 rxWriter
->bWriteAll
= bWriteAll
;
867 SwDoc
* pOutDoc
= pDoc
? pDoc
: &rDoc
;
869 // falls der Standart PageDesc. immer noch auf initalen Werten steht
870 // (wenn z.B. kein Drucker gesetzt wurde) dann setze jetzt auf DIN A4
871 // --> OD 2004-11-17 #i37248# - Modifications are only allowed at a new document.
872 // <pOutDoc> contains a new document, if <pDoc> is set - see above.
873 if ( pDoc
&& !pOutDoc
->getPrinter( false ) )
876 const SwPageDesc
& rPgDsc
= const_cast<const SwDoc
*>(pOutDoc
)->GetPageDesc( 0 );
877 //const SwPageDesc& rPgDsc = *pOutDoc->GetPageDescFromPool( RES_POOLPAGE_STANDARD );;
878 const SwFmtFrmSize
& rSz
= rPgDsc
.GetMaster().GetFrmSize();
879 // Clipboard-Dokument wird immer ohne Drucker angelegt, so ist
880 // der Std.PageDesc immer aug LONG_MAX !! Mappe dann auf DIN A4
881 if( LONG_MAX
== rSz
.GetHeight() || LONG_MAX
== rSz
.GetWidth() )
883 SwPageDesc
aNew( rPgDsc
);
884 SwFmtFrmSize
aNewSz( rSz
);
885 Size
a4(SvxPaperInfo::GetPaperSize( PAPER_A4
));
886 aNewSz
.SetHeight( a4
.Width() );
887 aNewSz
.SetWidth( a4
.Height() );
888 aNew
.GetMaster().SetFmtAttr( aNewSz
);
889 pOutDoc
->ChgPageDesc( 0, aNew
);
893 BOOL
bLockedView(FALSE
);
894 SwEditShell
* pESh
= pOutDoc
->GetEditShell();
897 bLockedView
= pESh
->IsViewLocked();
898 pESh
->LockView( TRUE
); //lock visible section
899 pESh
->StartAllAction();
902 BOOL bWasPurgeOle
= pOutDoc
->get(IDocumentSettingAccess::PURGE_OLE
);
903 pOutDoc
->set(IDocumentSettingAccess::PURGE_OLE
, false);
907 nError
= rxWriter
->Write( *pPam
, *pMedium
, pRealFileName
);
909 nError
= rxWriter
->Write( *pPam
, *pStg
, pRealFileName
);
911 nError
= rxWriter
->Write( *pPam
, *pStrm
, pRealFileName
);
913 nError
= rxWriter
->Write( *pPam
, xStg
, pRealFileName
);
915 pOutDoc
->set(IDocumentSettingAccess::PURGE_OLE
, bWasPurgeOle
);
919 pESh
->EndAllAction();
920 pESh
->LockView( bLockedView
);
923 // Falls nur zum Schreiben eine Selektion aufgespannt wurde, vor der
924 // Rueckkehr den alten Crsr wieder herstellen.
925 if( !bWriteAll
&& ( pShell
|| pOutPam
))
930 pShell
->Pop( FALSE
);
937 delete pPam
; // loesche den hier erzeugten Pam
938 // Alles erfolgreich geschrieben? Sag' das dem Dokument!
939 if ( !IsError( nError
) && !pDoc
)
941 rDoc
.ResetModified();
942 // --> OD 2005-02-11 #i38810# - reset also flag, that indicates
944 rDoc
.SetLinksUpdated( sal_False
);
952 if ( !pDoc
->release() )
963 // ----------------------------------------------------------------------
966 BOOL
SetHTMLTemplate( SwDoc
& rDoc
)
968 // Vorlagennamen von den Sfx-HTML-Filter besorgen!!!
969 if( !ReadHTML
->GetTemplateDoc() )
970 ReadHTML
->MakeHTMLDummyTemplateDoc();
972 BOOL bRet
= ReadHTML
->SetTemplate( rDoc
);
974 SwNodes
& rNds
= rDoc
.GetNodes();
975 SwNodeIndex
aIdx( rNds
.GetEndOfExtras(), 1 );
976 SwCntntNode
* pCNd
= rNds
.GoNext( &aIdx
);
980 ( SwFmtPageDesc(rDoc
.GetPageDescFromPool(RES_POOLPAGE_HTML
, false) ) );
981 pCNd
->ChgFmtColl( rDoc
.GetTxtCollFromPool( RES_POOLCOLL_TEXT
, false ));