xref: /trunk/main/sw/source/filter/basflt/shellio.cxx (revision 6fddd742)
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