xref: /AOO41X/main/sw/source/filter/basflt/shellio.cxx (revision 6fddd7428c69a4b8f78f9480321a2ed35739f18d)
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 
27 #include <hintids.hxx>
28 #include <tools/date.hxx>
29 #include <tools/time.hxx>
30 #include <svl/urihelper.hxx>
31 #include <svl/fstathelper.hxx>
32 #include <unotools/moduleoptions.hxx>
33 #include <sfx2/docfile.hxx>
34 #include <editeng/lrspitem.hxx>
35 #include <editeng/ulspitem.hxx>
36 #include <editeng/boxitem.hxx>
37 #include <editeng/paperinf.hxx>
38 #include <node.hxx>
39 #include <docary.hxx>
40 #include <fmtanchr.hxx>
41 #include <fmtfsize.hxx>
42 #include <fmtpdsc.hxx>
43 #include <swtypes.hxx>
44 #include <shellio.hxx>
45 #include <doc.hxx>
46 #include <IDocumentUndoRedo.hxx>
47 #include <pam.hxx>
48 #include <editsh.hxx>
49 #include <undobj.hxx>           // fuer Undo Insert-Dokument
50 #include <swundo.hxx>           // fuer Undo Insert-Dokument
51 #include <swtable.hxx>
52 #include <tblsel.hxx>
53 #include <pagedesc.hxx>
54 #include <poolfmt.hxx>
55 #include <fltini.hxx>
56 #include <docsh.hxx>
57 #include <redline.hxx>
58 #include <swerror.h>
59 
60 #include <paratr.hxx>
61 
62 // --> OD 2007-03-30 #i73788#
63 #include <pausethreadstarting.hxx>
64 // <--
65 
66 
67 using namespace ::com::sun::star;
68 
69 //////////////////////////////////////////////////////////////////////////
70 
Read(const Reader & rOptions)71 sal_uLong SwReader::Read( const Reader& rOptions )
72 {
73     // Variable uebertragen
74     Reader* po = (Reader*) &rOptions;
75     po->pStrm = pStrm;
76     po->pStg  = pStg;
77     po->xStg  = xStg;
78     po->bInsertMode = 0 != pCrsr;
79 
80     // ist ein Medium angegeben, dann aus diesem die Streams besorgen
81     if( 0 != (po->pMedium = pMedium ) &&
82         !po->SetStrmStgPtr() )
83     {
84         po->SetReadUTF8( sal_False );
85         po->SetBlockMode( sal_False );
86         po->SetOrganizerMode( sal_False );
87         po->SetIgnoreHTMLComments( sal_False );
88         return ERR_SWG_FILE_FORMAT_ERROR;
89     }
90 
91     sal_uLong nError = 0L;
92 
93     GetDoc();
94 
95     // am Sw3-Reader noch den pIo-Pointer "loeschen"
96     /*
97     if( po == ReadSw3 && pDoc->GetDocShell() &&
98         ((Sw3Reader*)po)->GetSw3Io() != pDoc->GetDocShell()->GetIoSystem() )
99             ((Sw3Reader*)po)->SetSw3Io( pDoc->GetDocShell()->GetIoSystem() );*/
100 
101     // waehrend des einlesens kein OLE-Modified rufen
102     Link aOLELink( pDoc->GetOle2Link() );
103     pDoc->SetOle2Link( Link() );
104 
105     pDoc->SetInReading( true );
106     pDoc->SetInXMLImport( 0 != dynamic_cast< XMLReader* >(po) );
107 
108     SwPaM *pPam;
109     if( pCrsr )
110         pPam = pCrsr;
111     else
112     {
113         // Wenn der Reader nicht mit einem Shell konstruiert wurde,
114         // selber einen Pam machen.
115         SwNodeIndex nNode( pDoc->GetNodes().GetEndOfContent(), -1 );
116         pPam = new SwPaM( nNode );
117         // Bei Web-Dokumenten wird die Default-Vorlage schon im InitNew
118         // gesetzt und braucht deshalb nicht nochmal gesetzt zu werden.
119         // Das gilt natuerlich nicht, wenn der Filter nicht der HTML-Filter
120         // ist oder im ConvertFrom zuvor ein SetTemplateName gerufen
121         // wurde.
122         if( !pDoc->get(IDocumentSettingAccess::HTML_MODE) || ReadHTML != po || !po->pTemplate  )
123             po->SetTemplate( *pDoc );
124     }
125 
126     // Pams sind ringfoermig verkettet. Aufhoeren, wenn man wieder beim
127     // ersten ist.
128     SwPaM *pEnd = pPam;
129     SwUndoInsDoc* pUndo = 0;
130 
131     sal_Bool bReadPageDescs = sal_False;
132     bool const bDocUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
133     sal_Bool bSaveUndo = bDocUndo && pCrsr;
134     if( bSaveUndo )
135     {
136         // das Einlesen von Seitenvorlagen ist nicht Undofaehig!
137         if( 0 != ( bReadPageDescs = po->aOpt.IsPageDescs() ) )
138         {
139             bSaveUndo = sal_False;
140             pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
141         }
142         else
143         {
144             pDoc->GetIDocumentUndoRedo().ClearRedo();
145             pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_INSDOKUMENT, NULL );
146         }
147     }
148     pDoc->GetIDocumentUndoRedo().DoUndo(false);
149 
150     SwNodeIndex aSplitIdx( pDoc->GetNodes() );
151 
152     RedlineMode_t eOld = pDoc->GetRedlineMode();
153     RedlineMode_t ePostReadRedlineMode( nsRedlineMode_t::REDLINE_IGNORE );
154 
155     // Array von FlyFormaten
156     SwSpzFrmFmts aFlyFrmArr;
157     // only read templates? then ignore multi selection!
158     sal_Bool bFmtsOnly = po->aOpt.IsFmtsOnly();
159 
160     while( sal_True )
161     {
162         if( bSaveUndo )
163             pUndo = new SwUndoInsDoc( *pPam );
164 
165         pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
166 
167         SwPaM* pUndoPam = 0;
168         if( bDocUndo || pCrsr )
169         {
170             // Pam auf den Node davor setzen damit er nicht mit verschoben wird
171             const SwNodeIndex& rTmp = pPam->GetPoint()->nNode;
172             pUndoPam = new SwPaM( rTmp, rTmp, 0, -1 );
173         }
174 
175         // Speicher mal alle Fly's
176         if( pCrsr )
177             aFlyFrmArr.Insert( pDoc->GetSpzFrmFmts(), 0L );
178 
179         xub_StrLen nSttCntnt = pPam->GetPoint()->nContent.GetIndex();
180 
181         // damit fuer alle Reader die Ende-Position immer stimmt, hier
182         // pflegen.
183         SwCntntNode* pCNd = pPam->GetCntntNode();
184         xub_StrLen nEndCntnt = pCNd ? pCNd->Len() - nSttCntnt : 0;
185         SwNodeIndex aEndPos( pPam->GetPoint()->nNode, 1 );
186 
187         pDoc->SetRedlineMode_intern( eOld );
188 
189         nError = po->Read( *pDoc, GetBaseURL(), *pPam, aFileName );
190 
191         // an ODF document may contain redline mode in settings.xml; save it!
192         ePostReadRedlineMode = pDoc->GetRedlineMode();
193 
194         pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
195 
196         if( !IsError( nError ))     // dann setzen wir das Ende mal richtig
197         {
198             aEndPos--;
199             pCNd = aEndPos.GetNode().GetCntntNode();
200             if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &aEndPos ) ))
201                 pCNd = pDoc->GetNodes().GoNext( &aEndPos );
202 
203             pPam->GetPoint()->nNode = aEndPos;
204             xub_StrLen nLen = pCNd->Len();
205             if( nLen < nEndCntnt )
206                 nEndCntnt = 0;
207             else
208                 nEndCntnt = nLen - nEndCntnt;
209             pPam->GetPoint()->nContent.Assign( pCNd, nEndCntnt );
210         }
211 
212         if( pCrsr )
213         {
214             *pUndoPam->GetMark() = *pPam->GetPoint();
215             pUndoPam->GetPoint()->nNode++;
216             SwNode* pNd = pUndoPam->GetNode();
217             if( pNd->IsCntntNode() )
218                 pUndoPam->GetPoint()->nContent.Assign(
219                                     (SwCntntNode*)pNd, nSttCntnt );
220             else
221                 pUndoPam->GetPoint()->nContent.Assign( 0, 0 );
222 
223             int bChkHeaderFooter = pNd->FindHeaderStartNode() ||
224                                    pNd->FindFooterStartNode();
225 
226             // Suche alle neuen Fly's und speicher sie als einzelne Undo
227             // Objecte
228             for( sal_uInt16 n = 0; n < pDoc->GetSpzFrmFmts()->Count(); ++n )
229             {
230                 SwFrmFmt* pFrmFmt = (*pDoc->GetSpzFrmFmts())[ n ];
231                 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
232                 if( USHRT_MAX == aFlyFrmArr.GetPos( pFrmFmt) )
233                 {
234                     SwPosition const*const pFrameAnchor(
235                             rAnchor.GetCntntAnchor());
236                     if  (   (FLY_AT_PAGE == rAnchor.GetAnchorId())
237                         ||  (   pFrameAnchor
238                             &&  (   (   (FLY_AT_PARA == rAnchor.GetAnchorId())
239                                     &&  (   (pUndoPam->GetPoint()->nNode ==
240                                              pFrameAnchor->nNode)
241                                         ||  (pUndoPam->GetMark()->nNode ==
242                                              pFrameAnchor->nNode)
243                                         )
244                                     )
245                                 // #i97570# also check frames anchored AT char
246                                 ||  (   (FLY_AT_CHAR == rAnchor.GetAnchorId())
247                                     &&  !IsDestroyFrameAnchoredAtChar(
248                                               *pFrameAnchor,
249                                               *pUndoPam->GetPoint(),
250                                               *pUndoPam->GetMark())
251                                     )
252                                 )
253                             )
254                         )
255                     {
256                         if( bChkHeaderFooter &&
257                             (FLY_AT_PARA == rAnchor.GetAnchorId()) &&
258                             RES_DRAWFRMFMT == pFrmFmt->Which() )
259                         {
260                             // DrawObjecte in Kopf-/Fusszeilen ist nicht
261                             // erlaubt!
262                             pFrmFmt->DelFrms();
263                             pDoc->DelFrmFmt( pFrmFmt );
264                             --n;
265                         }
266                         else
267                         {
268                             if( bSaveUndo )
269                             {
270                                 pDoc->SetRedlineMode_intern( eOld );
271                                 // UGLY: temp. enable undo
272                                 pDoc->GetIDocumentUndoRedo().DoUndo(true);
273                                 pDoc->GetIDocumentUndoRedo().AppendUndo(
274                                     new SwUndoInsLayFmt( pFrmFmt,0,0 ) );
275                                 pDoc->GetIDocumentUndoRedo().DoUndo(false);
276                                 pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
277                             }
278                             if( pFrmFmt->GetDepends() )
279                             {
280                                 // beim Insert legen Draw-Objecte einen Frame an
281                                 // also weg damit.
282                                 pFrmFmt->DelFrms();
283                             }
284 
285                             if (FLY_AT_PAGE == rAnchor.GetAnchorId())
286                             {
287                                 if( !rAnchor.GetCntntAnchor() )
288                                 {
289                                     pFrmFmt->MakeFrms();
290                                 }
291                                 else if( pCrsr )
292                                 {
293                                     pDoc->SetContainsAtPageObjWithContentAnchor( true );
294                                 }
295                             }
296                             else
297                                 pFrmFmt->MakeFrms();
298                         }
299                     }
300                 }
301             }
302             if( aFlyFrmArr.Count() )
303                 aFlyFrmArr.Remove( 0, aFlyFrmArr.Count() );
304 
305             pDoc->SetRedlineMode_intern( eOld );
306             if( pDoc->IsRedlineOn() )
307                 pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, *pUndoPam ), true);
308             else
309                 pDoc->SplitRedline( *pUndoPam );
310             pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
311         }
312         if( bSaveUndo )
313         {
314             pDoc->SetRedlineMode_intern( eOld );
315             pUndo->SetInsertRange( *pUndoPam, sal_False );
316             // UGLY: temp. enable undo
317             pDoc->GetIDocumentUndoRedo().DoUndo(true);
318             pDoc->GetIDocumentUndoRedo().AppendUndo( pUndo );
319             pDoc->GetIDocumentUndoRedo().DoUndo(false);
320             pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
321         }
322 
323         delete pUndoPam;
324 
325         pPam = (SwPaM *) pPam->GetNext();
326         if( pPam == pEnd )
327             break;
328 
329         // only read templates? then ignore multi selection! Bug 68593
330         if( bFmtsOnly )
331             break;
332 
333         /*
334          * !!! man muss selbst den Status vom Stream zuruecksetzen. !!!
335          *     Beim seekg wird der akt. Status, eof- und bad-Bit
336          *     gesetzt, warum weiss keiner
337          */
338         if( pStrm )
339         {
340             pStrm->Seek(0);
341             pStrm->ResetError();
342         }
343     }
344 
345     pDoc->SetInReading( false );
346     pDoc->SetInXMLImport( false );
347 
348     pDoc->InvalidateNumRules();
349     pDoc->UpdateNumRule();
350     pDoc->ChkCondColls();
351     pDoc->SetAllUniqueFlyNames();
352     pDoc->SetLoaded( true );
353 
354     pDoc->GetIDocumentUndoRedo().DoUndo(bDocUndo);
355     if (!bReadPageDescs)
356     {
357         if( bSaveUndo )
358         {
359             pDoc->SetRedlineMode_intern( eOld );
360             pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_INSDOKUMENT, NULL );
361             pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
362         }
363     }
364 
365     // Wenn der Pam nur fuers Lesen konstruiert wurde, jetzt zerstoeren.
366     if( !pCrsr )
367     {
368         delete pPam;          // ein neues aufgemacht.
369 
370         // --> FME 2005-02-25 #i42634# Moved common code of SwReader::Read() and
371         // SwDocShell::UpdateLinks() to new SwDoc::UpdateLinks():
372     // ATM still with Update
373         pDoc->UpdateLinks( sal_True );
374         // <--
375 
376         // not insert: set the redline mode read from settings.xml
377         eOld = static_cast<RedlineMode_t>(
378                 ePostReadRedlineMode & ~nsRedlineMode_t::REDLINE_IGNORE);
379 
380         pDoc->SetFieldsDirty(false, NULL, 0);
381     }
382 
383     pDoc->SetRedlineMode_intern( eOld );
384     pDoc->SetOle2Link( aOLELink );
385 
386     if( pCrsr )                 // das Doc ist jetzt modifiziert
387         pDoc->SetModified();
388     // --> OD 2005-02-11 #i38810# - If links have been updated, the document
389     // have to be modified. During update of links the OLE link at the document
390     // isn't set. Thus, the document's modified state has to be set again after
391     // the OLE link is restored - see above <pDoc->SetOle2Link( aOLELink )>.
392     if ( pDoc->LinksUpdated() )
393     {
394         pDoc->SetModified();
395     }
396     // <--
397 
398 //  if( po == ReadSw3 )         // am Sw3-Reader noch den pIo-Pointer "loeschen"
399 //      ((Sw3Reader*)po)->SetSw3Io( 0 );
400 
401     po->SetReadUTF8( sal_False );
402     po->SetBlockMode( sal_False );
403     po->SetOrganizerMode( sal_False );
404     po->SetIgnoreHTMLComments( sal_False );
405 
406     return nError;
407 }
408 
409 
410 /*
411  * Konstruktoren, Destruktor
412  */
413 
414 // Initiales Einlesben
415 
416                                        /*
417 SwReader::SwReader(SvStorage& rStg, const String& rFileName, SwDoc *pDoc)
418     : SwDocFac(pDoc), pStrm(0), pStg(&rStg), pMedium(0), pCrsr(0),
419     aFileName(rFileName)
420 {
421 }
422 
423 SwReader::SwReader(const uno::Reference < embed::XStorage >& rStg, const String& rFileName, SwDoc *pDoc)
424     : SwDocFac(pDoc), pStrm(0), pMedium(0), pCrsr(0), xStg( rStg ), aFileName(rFileName)
425 {
426 }
427                                          */
SwReader(SfxMedium & rMedium,const String & rFileName,SwDoc * pDocument)428 SwReader::SwReader(SfxMedium& rMedium, const String& rFileName, SwDoc *pDocument)
429     : SwDocFac(pDocument), pStrm(0), pMedium(&rMedium), pCrsr(0),
430     aFileName(rFileName)
431 {
432     SetBaseURL( rMedium.GetBaseURL() );
433 }
434 
435 // In ein existierendes Dokument einlesen
436 
SwReader(SvStream & rStrm,const String & rFileName,const String & rBaseURL,SwPaM & rPam)437 SwReader::SwReader(SvStream& rStrm, const String& rFileName, const String& rBaseURL, SwPaM& rPam)
438     : SwDocFac(rPam.GetDoc()), pStrm(&rStrm), pMedium(0), pCrsr(&rPam),
439     aFileName(rFileName)
440 {
441     SetBaseURL( rBaseURL );
442 }
443 /*
444 SwReader::SwReader(SvStorage& rStg, const String& rFileName, SwPaM& rPam)
445     : SwDocFac(rPam.GetDoc()), pStrm(0), pStg(&rStg), pMedium(0), pCrsr(&rPam),
446     aFileName(rFileName)
447 {
448 }
449 */
SwReader(SfxMedium & rMedium,const String & rFileName,SwPaM & rPam)450 SwReader::SwReader(SfxMedium& rMedium, const String& rFileName, SwPaM& rPam)
451     : SwDocFac(rPam.GetDoc()), pStrm(0), pMedium(&rMedium),
452     pCrsr(&rPam), aFileName(rFileName)
453 {
454     SetBaseURL( rMedium.GetBaseURL() );
455 }
456 
SwReader(const uno::Reference<embed::XStorage> & rStg,const String & rFilename,SwPaM & rPam)457 SwReader::SwReader( const uno::Reference < embed::XStorage > &rStg, const String& rFilename, SwPaM &rPam )
458     : SwDocFac(rPam.GetDoc()), pStrm(0), xStg( rStg ), pMedium(0), pCrsr(&rPam), aFileName(rFilename)
459 {
460 }
461 
Reader()462 Reader::Reader()
463     : pTemplate(0), pStrm(0), pMedium(0), bInsertMode(0),
464     bTmplBrowseMode(0), bReadUTF8(0), bBlockMode(0), bOrganizerMode(0),
465     bHasAskTemplateName(0), bIgnoreHTMLComments(0)
466 {
467 }
468 
~Reader()469 Reader::~Reader()
470 {
471     delete pTemplate;
472 }
473 
GetTemplateName() const474 String Reader::GetTemplateName() const
475 {
476     return aEmptyStr;
477 }
478 
479 // Die Filter-Vorlage laden, setzen und wieder freigeben
GetTemplateDoc()480 SwDoc* Reader::GetTemplateDoc()
481 {
482     if( !bHasAskTemplateName )
483     {
484         SetTemplateName( GetTemplateName() );
485         bHasAskTemplateName = sal_True;
486     }
487 
488     if( !aTemplateNm.Len() )
489         ClearTemplate();
490     else
491     {
492         INetURLObject aTDir( aTemplateNm );
493         String aFileName = aTDir.GetMainURL( INetURLObject::NO_DECODE );
494         DBG_ASSERT( !aTDir.HasError(), "No absolute path for template name!" );
495         DateTime aCurrDateTime;
496         sal_Bool bLoad = sal_False;
497 
498         // Wenn das Template schon mal geladen wurde, nur einmal pro
499         // Minute nachschauen, ob es geaendert wurde.
500         if( !pTemplate || aCurrDateTime >= aChkDateTime )
501         {
502             Date aTstDate;
503             Time aTstTime;
504             if( FStatHelper::GetModifiedDateTimeOfFile(
505                             aTDir.GetMainURL( INetURLObject::NO_DECODE ),
506                             &aTstDate, &aTstTime ) &&
507                 ( !pTemplate || aDStamp != aTstDate || aTStamp != aTstTime ))
508             {
509                 bLoad = sal_True;
510                 aDStamp = aTstDate;
511                 aTStamp = aTstTime;
512             }
513 
514             // Erst in einer Minute wieder mal nachschauen, ob sich die
515             // Vorlage geaendert hat.
516             aChkDateTime = aCurrDateTime;
517             aChkDateTime += Time( 0L, 1L );
518         }
519 
520         if( bLoad )
521         {
522             ClearTemplate();
523             ASSERT( !pTemplate, "Who holds the template doc?" );
524 
525                 // #95605#: If the writer module is not installed,
526                 // we cannot create a SwDocShell. We could create a
527                 // SwWebDocShell however, because this exists always
528                 // for the help.
529                 SvtModuleOptions aModuleOptions;
530                 if( aModuleOptions.IsWriter() )
531                 {
532                     SwDocShell *pDocSh =
533                         new SwDocShell ( SFX_CREATE_MODE_INTERNAL );
534                     SfxObjectShellLock xDocSh = pDocSh;
535                     if( pDocSh->DoInitNew( 0 ) )
536                     {
537                         pTemplate = pDocSh->GetDoc();
538                         pTemplate->SetOle2Link( Link() );
539                         // always FALSE
540                         pTemplate->GetIDocumentUndoRedo().DoUndo( false );
541                         pTemplate->set(IDocumentSettingAccess::BROWSE_MODE, bTmplBrowseMode );
542                         pTemplate->RemoveAllFmtLanguageDependencies();
543 
544                         ReadXML->SetOrganizerMode( sal_True );
545                         SfxMedium aMedium( aFileName, sal_False );
546                         SwReader aRdr( aMedium, aEmptyStr, pTemplate );
547                         aRdr.Read( *ReadXML );
548                         ReadXML->SetOrganizerMode( sal_False );
549 
550                         pTemplate->acquire();
551                     }
552                 }
553         }
554 
555         ASSERT( !pTemplate || FStatHelper::IsDocument( aFileName ) ||
556                 aTemplateNm.EqualsAscii( "$$Dummy$$" ),
557                 "TemplatePtr but no template exist!" );
558     }
559 
560     return pTemplate;
561 }
562 
SetTemplate(SwDoc & rDoc)563 sal_Bool Reader::SetTemplate( SwDoc& rDoc )
564 {
565     sal_Bool bRet = sal_False;
566 
567     GetTemplateDoc();
568     if( pTemplate )
569     {
570         rDoc.RemoveAllFmtLanguageDependencies();
571         rDoc.ReplaceStyles( *pTemplate );
572         rDoc.SetFixFields(false, NULL);
573         bRet = sal_True;
574     }
575 
576     return bRet;
577 }
578 
ClearTemplate()579 void Reader::ClearTemplate()
580 {
581     if( pTemplate )
582     {
583         if( 0 == pTemplate->release() )
584             delete pTemplate,
585         pTemplate = 0;
586     }
587 }
588 
SetTemplateName(const String & rDir)589 void Reader::SetTemplateName( const String& rDir )
590 {
591     if( rDir.Len() && aTemplateNm != rDir )
592     {
593         ClearTemplate();
594         aTemplateNm = rDir;
595     }
596 }
597 
MakeHTMLDummyTemplateDoc()598 void Reader::MakeHTMLDummyTemplateDoc()
599 {
600     ClearTemplate();
601     pTemplate = new SwDoc;
602     pTemplate->acquire();
603     pTemplate->set(IDocumentSettingAccess::BROWSE_MODE, bTmplBrowseMode );
604     pTemplate->getPrinter( true );
605     pTemplate->RemoveAllFmtLanguageDependencies();
606     aChkDateTime = Date( 1, 1, 2300 );  // 2300. Jahrtausend sollte reichen
607     aTemplateNm.AssignAscii( "$$Dummy$$" );
608 }
609 
610 // alle die die Streams / Storages nicht geoeffnet brauchen,
611 // muessen die Methode ueberladen
SetStrmStgPtr()612 int Reader::SetStrmStgPtr()
613 {
614     ASSERT( pMedium, "Wo ist das Medium??" );
615 
616     if( pMedium->IsStorage() )
617     {
618         if( SW_STORAGE_READER & GetReaderType() )
619         {
620             xStg = pMedium->GetStorage();
621             return sal_True;
622         }
623     }
624     else
625     {
626         pStrm = pMedium->GetInStream();
627         if ( pStrm && SotStorage::IsStorageFile(pStrm) && (SW_STORAGE_READER & GetReaderType()) )
628         {
629             pStg = new SotStorage( *pStrm );
630             pStrm = NULL;
631         }
632         else if ( !(SW_STREAM_READER & GetReaderType()) )
633         {
634             pStrm = NULL;
635             return sal_False;
636         }
637 
638         return sal_True;
639     }
640     return sal_False;
641 }
642 
643 
GetReaderType()644 int Reader::GetReaderType()
645 {
646     return SW_STREAM_READER;
647 }
648 
649 
SetFltName(const String &)650 void Reader::SetFltName( const String& )
651 {
652 }
653 
654 
SetNoOutlineNum(SwDoc &)655 void Reader::SetNoOutlineNum( SwDoc& /*rDoc*/ )
656 {
657     // JP 10.03.96: jetzt wieder keine Nummerierung in den Vorlagen
658 }
659 
660 
ResetFrmFmtAttrs(SfxItemSet & rFrmSet)661 void Reader::ResetFrmFmtAttrs( SfxItemSet &rFrmSet )
662 {
663     rFrmSet.Put( SvxLRSpaceItem(RES_LR_SPACE) );
664     rFrmSet.Put( SvxULSpaceItem(RES_UL_SPACE) );
665     rFrmSet.Put( SvxBoxItem(RES_BOX) );
666 }
667 
668 
ResetFrmFmts(SwDoc & rDoc)669 void Reader::ResetFrmFmts( SwDoc& rDoc )
670 {
671     for (sal_uInt16 i=0; i<3; ++i)
672     {
673         sal_uInt16 nPoolId;
674         switch (i)
675         {
676             default:
677                 ASSERT(i == 0, "Impossible");
678                 //fallthrough
679             case 0:
680                 nPoolId = RES_POOLFRM_FRAME;
681                 break;
682             case 1:
683                 nPoolId = RES_POOLFRM_GRAPHIC;
684                 break;
685             case 2:
686                 nPoolId = RES_POOLFRM_OLE;
687                 break;
688         }
689 
690         SwFrmFmt *pFrmFmt = rDoc.GetFrmFmtFromPool( nPoolId );
691 
692         pFrmFmt->ResetFmtAttr( RES_LR_SPACE );
693         pFrmFmt->ResetFmtAttr( RES_UL_SPACE );
694         pFrmFmt->ResetFmtAttr( RES_BOX );
695     }
696 }
697 
698     // read the sections of the document, which is equal to the medium.
699     // returns the count of it
GetSectionList(SfxMedium &,SvStrings &) const700 sal_uInt16 Reader::GetSectionList( SfxMedium&, SvStrings& ) const
701 {
702     return 0;
703 }
704 
705 // ------------------------------------------------
HasGlossaries(const Reader & rOptions)706 sal_Bool SwReader::HasGlossaries( const Reader& rOptions )
707 {
708     // Variable uebertragen
709     Reader* po = (Reader*) &rOptions;
710     po->pStrm = pStrm;
711     po->pStg  = pStg;
712     po->bInsertMode = sal_False;
713 
714     // ist ein Medium angegeben, dann aus diesem die Streams besorgen
715     sal_Bool bRet = sal_False;
716     if( !( 0 != (po->pMedium = pMedium ) && !po->SetStrmStgPtr() ))
717         bRet = po->HasGlossaries();
718     return bRet;
719 }
720 
ReadGlossaries(const Reader & rOptions,SwTextBlocks & rBlocks,sal_Bool bSaveRelFiles)721 sal_Bool SwReader::ReadGlossaries( const Reader& rOptions,
722                                 SwTextBlocks& rBlocks, sal_Bool bSaveRelFiles )
723 {
724     // Variable uebertragen
725     Reader* po = (Reader*) &rOptions;
726     po->pStrm = pStrm;
727     po->pStg  = pStg;
728     po->bInsertMode = sal_False;
729 
730     // ist ein Medium angegeben, dann aus diesem die Streams besorgen
731     sal_Bool bRet = sal_False;
732     if( !( 0 != (po->pMedium = pMedium ) && !po->SetStrmStgPtr() ))
733         bRet = po->ReadGlossaries( rBlocks, bSaveRelFiles );
734     return bRet;
735 }
736 
HasGlossaries() const737 sal_Bool Reader::HasGlossaries() const
738 {
739     return sal_False;
740 }
741 
ReadGlossaries(SwTextBlocks &,sal_Bool) const742 sal_Bool Reader::ReadGlossaries( SwTextBlocks&, sal_Bool ) const
743 {
744     return sal_False;
745 }
746 
747 // ------------------------------------------------
748 
GetReaderType()749 int StgReader::GetReaderType()
750 {
751     return SW_STORAGE_READER;
752 }
753 
754 
755 
756 
757 /*
758  * Writer
759  */
760 
761 /*
762  * Konstruktoren, Destruktoren sind inline (inc/shellio.hxx).
763  */
764 
SwWriter(SvStream & rStrm,SwCrsrShell & rShell,sal_Bool bInWriteAll)765 SwWriter::SwWriter(SvStream& rStrm, SwCrsrShell &rShell, sal_Bool bInWriteAll)
766     : pStrm(&rStrm), pMedium(0), pOutPam(0), pShell(&rShell),
767     rDoc(*rShell.GetDoc()), bWriteAll(bInWriteAll)
768 {
769 }
770 
SwWriter(SvStream & rStrm,SwDoc & rDocument)771 SwWriter::SwWriter(SvStream& rStrm,SwDoc &rDocument)
772     : pStrm(&rStrm), pMedium(0), pOutPam(0), pShell(0), rDoc(rDocument),
773     bWriteAll(true)
774 {
775 }
776 
SwWriter(SvStream & rStrm,SwPaM & rPam,sal_Bool bInWriteAll)777 SwWriter::SwWriter(SvStream& rStrm, SwPaM& rPam, sal_Bool bInWriteAll)
778     : pStrm(&rStrm), pMedium(0), pOutPam(&rPam), pShell(0),
779     rDoc(*rPam.GetDoc()), bWriteAll(bInWriteAll)
780 {
781 }
782 
SwWriter(const uno::Reference<embed::XStorage> & rStg,SwDoc & rDocument)783 SwWriter::SwWriter( const uno::Reference < embed::XStorage >& rStg, SwDoc &rDocument)
784     : pStrm(0), xStg( rStg ), pMedium(0), pOutPam(0), pShell(0), rDoc(rDocument), bWriteAll(true)
785 {
786 }
787 
SwWriter(SfxMedium & rMedium,SwCrsrShell & rShell,sal_Bool bInWriteAll)788 SwWriter::SwWriter(SfxMedium& rMedium, SwCrsrShell &rShell, sal_Bool bInWriteAll)
789     : pStrm(0), pMedium(&rMedium), pOutPam(0), pShell(&rShell),
790     rDoc(*rShell.GetDoc()), bWriteAll(bInWriteAll)
791 {
792 }
793 
SwWriter(SfxMedium & rMedium,SwDoc & rDocument)794 SwWriter::SwWriter(SfxMedium& rMedium, SwDoc &rDocument)
795     : pStrm(0), pMedium(&rMedium), pOutPam(0), pShell(0), rDoc(rDocument),
796     bWriteAll(true)
797 {
798 }
799 
Write(WriterRef & rxWriter,const String * pRealFileName)800 sal_uLong SwWriter::Write( WriterRef& rxWriter, const String* pRealFileName )
801 {
802     // --> OD 2007-03-30 #i73788#
803     SwPauseThreadStarting aPauseThreadStarting;
804     // <--
805 
806     sal_Bool bHasMark = sal_False;
807     SwPaM * pPam;
808 
809     SwDoc *pDoc = 0;
810 
811     if ( pShell && !bWriteAll && pShell->IsTableMode() )
812     {
813         bWriteAll = sal_True;
814         pDoc = new SwDoc;
815         pDoc->acquire();
816 
817         // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
818         // von der Originalen an und kopiere die selectierten Boxen.
819         // Die Groessen werden prozentual korrigiert.
820 
821         // lasse ueber das Layout die Boxen suchen
822         SwSelBoxes aBoxes;
823         GetTblSel( *pShell, aBoxes );
824         SwTableNode* pTblNd = (SwTableNode*)aBoxes[0]->GetSttNd()->StartOfSectionNode();
825         SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), 2 );
826         SwCntntNode *pNd = aIdx.GetNode().GetCntntNode();
827         ASSERT( pNd, "Node not found" );
828         SwPosition aPos( aIdx, SwIndex( pNd ) );
829         pTblNd->GetTable().MakeCopy( pDoc, aPos, aBoxes );
830     }
831 
832     if( !bWriteAll && ( pShell || pOutPam ))
833     {
834         if( pShell )
835             pPam = pShell->GetCrsr();
836         else
837             pPam = pOutPam;
838 
839         SwPaM *pEnd = pPam;
840 
841         // Erste Runde: Nachsehen, ob eine Selektion besteht.
842         while(sal_True)
843         {
844             bHasMark = bHasMark || pPam->HasMark();
845             pPam = (SwPaM *) pPam->GetNext();
846             if(bHasMark || pPam == pEnd)
847                 break;
848         }
849 
850         // Wenn keine Selektion besteht, eine ueber das ganze Dokument aufspannen.
851         if(!bHasMark)
852         {
853             if( pShell )
854             {
855                 pShell->Push();
856                 pShell->SttEndDoc(sal_True);
857                 pShell->SetMark();
858                 pShell->SttEndDoc(sal_False);
859             }
860             else
861             {
862                 pPam = new SwPaM( *pPam );
863                 pPam->Move( fnMoveBackward, fnGoDoc );
864                 pPam->SetMark();
865                 pPam->Move( fnMoveForward, fnGoDoc );
866             }
867         }
868         // pPam ist immer noch der akt. Cursor !!
869     }
870     else
871     {
872         // keine Shell oder alles schreiben -> eigenen Pam erzeugen
873         SwDoc* pOutDoc = pDoc ? pDoc : &rDoc;
874         pPam = new SwPaM( pOutDoc->GetNodes().GetEndOfContent() );
875         if( pOutDoc->IsClipBoard() )
876         {
877             pPam->Move( fnMoveBackward, fnGoDoc );
878             pPam->SetMark();
879             pPam->Move( fnMoveForward, fnGoDoc );
880         }
881         else
882         {
883             pPam->SetMark();
884             pPam->Move( fnMoveBackward, fnGoDoc );
885         }
886     }
887 
888     rxWriter->bWriteAll = bWriteAll;
889     SwDoc* pOutDoc = pDoc ? pDoc : &rDoc;
890 
891     // falls der Standart PageDesc. immer noch auf initalen Werten steht
892     // (wenn z.B. kein Drucker gesetzt wurde) dann setze jetzt auf DIN A4
893     // --> OD 2004-11-17 #i37248# - Modifications are only allowed at a new document.
894     // <pOutDoc> contains a new document, if <pDoc> is set - see above.
895     if ( pDoc && !pOutDoc->getPrinter( false ) )
896     // <--
897     {
898         const SwPageDesc& rPgDsc = const_cast<const SwDoc *>(pOutDoc)->GetPageDesc( 0 );
899         //const SwPageDesc& rPgDsc = *pOutDoc->GetPageDescFromPool( RES_POOLPAGE_STANDARD );;
900         const SwFmtFrmSize& rSz = rPgDsc.GetMaster().GetFrmSize();
901         // Clipboard-Dokument wird immer ohne Drucker angelegt, so ist
902         // der Std.PageDesc immer aug LONG_MAX !! Mappe dann auf DIN A4
903         if( LONG_MAX == rSz.GetHeight() || LONG_MAX == rSz.GetWidth() )
904         {
905             SwPageDesc aNew( rPgDsc );
906             SwFmtFrmSize aNewSz( rSz );
907             Size a4(SvxPaperInfo::GetPaperSize( PAPER_A4 ));
908             aNewSz.SetHeight( a4.Width() );
909             aNewSz.SetWidth( a4.Height() );
910             aNew.GetMaster().SetFmtAttr( aNewSz );
911             pOutDoc->ChgPageDesc( 0, aNew );
912         }
913     }
914 
915     sal_Bool bLockedView(sal_False);
916     SwEditShell* pESh = pOutDoc->GetEditShell();
917     if( pESh )
918     {
919         bLockedView = pESh->IsViewLocked();
920         pESh->LockView( sal_True );    //lock visible section
921         pESh->StartAllAction();
922     }
923 
924     sal_Bool bWasPurgeOle = pOutDoc->get(IDocumentSettingAccess::PURGE_OLE);
925     pOutDoc->set(IDocumentSettingAccess::PURGE_OLE, false);
926 
927     sal_uLong nError = 0;
928     if( pMedium )
929         nError = rxWriter->Write( *pPam, *pMedium, pRealFileName );
930     else if( pStg )
931         nError = rxWriter->Write( *pPam, *pStg, pRealFileName );
932     else if( pStrm )
933         nError = rxWriter->Write( *pPam, *pStrm, pRealFileName );
934     else if( xStg.is() )
935         nError = rxWriter->Write( *pPam, xStg, pRealFileName );
936 
937     pOutDoc->set(IDocumentSettingAccess::PURGE_OLE, bWasPurgeOle );
938 
939     if( pESh )
940     {
941         pESh->EndAllAction();
942         pESh->LockView( bLockedView );
943     }
944 
945     // Falls nur zum Schreiben eine Selektion aufgespannt wurde, vor der
946     // Rueckkehr den alten Crsr wieder herstellen.
947     if( !bWriteAll && ( pShell || pOutPam ))
948     {
949         if(!bHasMark)
950         {
951             if( pShell )
952                 pShell->Pop( sal_False );
953             else
954                 delete pPam;
955         }
956     }
957     else
958     {
959         delete pPam;            // loesche den hier erzeugten Pam
960         // Alles erfolgreich geschrieben? Sag' das dem Dokument!
961         if ( !IsError( nError ) && !pDoc )
962         {
963             rDoc.ResetModified();
964             // --> OD 2005-02-11 #i38810# - reset also flag, that indicates
965             // updated links
966             rDoc.SetLinksUpdated( sal_False );
967             // <-
968         }
969     }
970 
971     if ( pDoc )
972     {
973         if ( !pDoc->release() )
974             delete pDoc;
975         bWriteAll = sal_False;
976     }
977 
978     return nError;
979 }
980 
981 
982 /*  */
983 
984 // ----------------------------------------------------------------------
985 
986 
SetHTMLTemplate(SwDoc & rDoc)987 sal_Bool SetHTMLTemplate( SwDoc & rDoc )
988 {
989     // Vorlagennamen von den Sfx-HTML-Filter besorgen!!!
990     if( !ReadHTML->GetTemplateDoc() )
991         ReadHTML->MakeHTMLDummyTemplateDoc();
992 
993     sal_Bool bRet = ReadHTML->SetTemplate( rDoc );
994 
995     SwNodes& rNds = rDoc.GetNodes();
996     SwNodeIndex aIdx( rNds.GetEndOfExtras(), 1 );
997     SwCntntNode* pCNd = rNds.GoNext( &aIdx );
998     if( pCNd )
999     {
1000         pCNd->SetAttr
1001             ( SwFmtPageDesc(rDoc.GetPageDescFromPool(RES_POOLPAGE_HTML, false) ) );
1002         pCNd->ChgFmtColl( rDoc.GetTxtCollFromPool( RES_POOLCOLL_TEXT, false ));
1003     }
1004 
1005     return bRet;
1006 }
1007 
1008 
1009